5

Bluetoothチャットを使用してAndroidアプリケーションを開発しています。2 台の電話で Bluetooth チャットを正常に実装しました。しかし、私の問題は、チャット アクティビティから次のアクティビティに変更すると、接続が失われ、2 番目のアクティビティからメッセージを送信できないことです。どうすれば接続を維持できますか?
つまり、アプリ全体で接続を維持したいということです。ユーザーが終了ボタンを押すたびに、接続のみが切断されます。あるアクティビティからメッセージを送信し、別のアクティビティから受信したいのはこれです。コードでバックグラウンド サービスを作成できません。
コードを分割するのを手伝ってくれる人はいますか? ある電話からメッセージを受け取った場合、メッセージを処理して結果を送り返したいのですが、その処理は次のアクティビティで行われます。これは私のアプリの動作です。

  public class BluetoothTexting extends Activity {

  private static int DISCOVERY_REQUEST = 1;

  private Handler handler = new Handler();

  private ArrayList<BluetoothDevice> foundDevices = new ArrayList<BluetoothDevice>();
    private ArrayAdapter<BluetoothDevice> aa; 
  private ListView list;

  private BluetoothAdapter bluetooth;
  private BluetoothSocket socket;
  private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    configureBluetooth();


    setupListView();    


    setupSearchButton();


    setupListenButton();
    }

     private void configureBluetooth() {
     bluetooth = BluetoothAdapter.getDefaultAdapter();
     }

      private void setupListenButton() {
      Button listenButton = (Button)findViewById(R.id.button_listen);
      listenButton.setOnClickListener(new OnClickListener() {
      public void onClick(View view) {
       Intent disc = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
      startActivityForResult(disc, DISCOVERY_REQUEST);     
     }
    });
    }

     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == DISCOVERY_REQUEST) {
      boolean isDiscoverable = resultCode > 0;
      if (isDiscoverable) {
       String name = "bluetoothserver";
        try {
         final BluetoothServerSocket btserver = 
         bluetooth.listenUsingRfcommWithServiceRecord(name, uuid);

          AsyncTask<Integer, Void, BluetoothSocket> acceptThread = 
         new AsyncTask<Integer, Void, BluetoothSocket>() {

        @Override
        protected BluetoothSocket doInBackground(Integer... params) {
          try {
            socket = btserver.accept(params[0]*1000);
            return socket;
          } catch (IOException e) {
            Log.d("BLUETOOTH", e.getMessage());            
          }
          return null;
        }

        @Override
        protected void onPostExecute(BluetoothSocket result) {
          if (result != null)
            switchUI();
        }            
      };          
      acceptThread.execute(resultCode);
    } catch (IOException e) {
      Log.d("BLUETOOTH", e.getMessage());            
    }
  }
}
}

      private void setupListView() {
        aa = new ArrayAdapter<BluetoothDevice>(this, 
           android.R.layout.simple_list_item_1,
           foundDevices);
      list = (ListView)findViewById(R.id.list_discovered);    
      list.setAdapter(aa);

     list.setOnItemClickListener(new OnItemClickListener() {
      public void onItemClick(AdapterView<?> arg0, View view, 
                          int index, long arg3) {
       AsyncTask<Integer, Void, Void> connectTask = 
       new AsyncTask<Integer, Void, Void>() { 
        @Override
        protected Void doInBackground(Integer... params) {
          try {
            BluetoothDevice device = foundDevices.get(params[0]);
            socket = device.createRfcommSocketToServiceRecord(uuid);
            socket.connect();              
          } catch (IOException e) {
            Log.d("BLUETOOTH_CLIENT", e.getMessage());
          }
          return null;
        }

        @Override
        protected void onPostExecute(Void result) {
          switchUI();
        }
      };
    connectTask.execute(index);
  }      
});
}

        private void setupSearchButton() {
        Button searchButton = (Button)findViewById(R.id.button_search);

         searchButton.setOnClickListener(new OnClickListener() {
         public void onClick(View view) {
         registerReceiver(discoveryResult, 
                     new IntentFilter(BluetoothDevice.ACTION_FOUND));

    if (!bluetooth.isDiscovering()) {
      foundDevices.clear();
      bluetooth.startDiscovery();
    }
  }
});
}

   private void switchUI() {    
   final TextView messageText = (TextView)findViewById(R.id.text_messages);
   final EditText textEntry = (EditText)findViewById(R.id.text_message);
   final Button btnSend = (Button)findViewById(R.id.send); 

   messageText.setVisibility(View.VISIBLE);
   list.setVisibility(View.GONE);
  textEntry.setEnabled(true);
    btnSend.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {

        if(textEntry.getText().length()>0)
        {
             sendMessage(socket, textEntry.getText().toString());   

        }
        else
        {
             sendMessage(socket, "Test_String");    
        }
    }
});  
      /*textEntry.setOnKeyListener(new OnKeyListener() {
        public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
         if ((keyEvent.getAction() == KeyEvent.ACTION_DOWN) &&
        (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)) {
        sendMessage(socket, textEntry.getText().toString());
         textEntry.setText("");
         return true;
         }
        return false;
  }      
});*/
       BluetoothSocketListener bsl = new BluetoothSocketListener(socket, handler,         messageText);
Thread messageListener = new Thread(bsl);
    messageListener.start();
}

    private void sendMessage(BluetoothSocket socket, String msg) {
    OutputStream outStream;
    try {
     outStream = socket.getOutputStream();
    byte[] byteString = (msg + " ").getBytes();
    byteString[byteString.length - 1] = 0;
    outStream.write(byteString);
  //  outStream.close();
   // socket.close();
  } catch (IOException e) {
    Log.d("BLUETOOTH_COMMS", e.getMessage());
  }    
  }

  BroadcastReceiver discoveryResult = new BroadcastReceiver() {
   @Override
    public void onReceive(Context context, Intent intent) {
   BluetoothDevice remoteDevice;
   remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
   if (bluetooth.getBondedDevices().contains(remoteDevice)) {  
     foundDevices.add(remoteDevice);
     aa.notifyDataSetChanged();
   }
 }
 };

    private class MessagePoster implements Runnable {
     private TextView textView;
     private String message;

     public MessagePoster(TextView textView, String message) {
     this.textView = textView;
     this.message = message;
   }

    public void run() {
     textView.append("\n"+message);
    Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
    }     
  }

      private class BluetoothSocketListener implements Runnable {

  private BluetoothSocket socket;
  private TextView textView;
  private Handler handler;

  public BluetoothSocketListener(BluetoothSocket socket, 
                                 Handler handler, TextView textView) {
    this.socket = socket;
    this.textView = textView;
    this.handler = handler;
  }

    public void run() {
    int bufferSize = 1024;
  byte[] buffer = new byte[bufferSize];      
  try {
    InputStream instream = socket.getInputStream();
    int bytesRead = -1;
    String message = "";
    while (true) {
      message = "";
      bytesRead = instream.read(buffer);
      if (bytesRead != -1) {
        while ((bytesRead==bufferSize)&&(buffer[bufferSize-1] != 0)) {
          message = message + new String(buffer, 0, bytesRead);
          bytesRead = instream.read(buffer);
        }
        message = message + new String(buffer, 0, bytesRead - 1); 

        handler.post(new MessagePoster(textView, message));              
        socket.getInputStream();

      }
    }
  } catch (IOException e) {
    Log.d("BLUETOOTH_COMMS", e.getMessage());
  } 
}
}
}
4

1 に答える 1

2

私は同様の bt-chat を開発しました。

doInBackground、asyncTask、およびアクティビティ内で新しい実行可能ファイルを定義する代わりに、さまざまなスレッドで接続を開始および管理しました。そうすれば、接続は開いたままになります。

編集: サーバー スレッド コードを追加しました。サーバーが接続されるとブロードキャストが送信されるため、すべてのアクティビティがそれを登録して受信できるため、BT の接続中にアクティビティを変更しても問題はありません。

public class Server extends Thread {


    private BluetoothAdapter btAdapter;
    private String socketString = "a random string";
    private BluetoothServerSocket btServerSocket;
    private BluetoothSocket btConnectedSocket;
    private final String TAG = "Server";
    private MainActivity parent;
    /*package-protected*/ static final String ACTION = "Bluetooth socket is connected";
    private boolean connected;

    public Server(MainActivity parent) {
        this.parent = parent;
        connected= false;
    }

    @Override
    public void run() {
        btAdapter = BluetoothAdapter.getDefaultAdapter();

        try {
            Log.i(TAG, "getting socket from adapter");
            btServerSocket = btAdapter.listenUsingRfcommWithServiceRecord(socketString, MainActivity.BT_UUID);
            listen();

        }
        catch (IOException ex) {
            Log.e(TAG, "error while initializing");
        }
    }

    private void listen() {
        Log.i(TAG, "listening");
        btConnectedSocket = null;
        while (!connected) {
            try {
                btConnectedSocket = btServerSocket.accept();
            }
            catch (IOException ex) {
                Log.e(TAG,"connection failed");
                connectionFailed();
            }

            if (btConnectedSocket != null) {
                broadcast();
                closeServerSocket();
            }
            else {
                Log.i(TAG,  "socket is null");
                connectionFailed();
            }
        }

    }

    private void broadcast() {
        try {
            Log.i(TAG, "connected? "+btConnectedSocket.isConnected());
            Intent intent = new Intent();
            intent.setAction(ACTION);
            intent.putExtra("state", btConnectedSocket.isConnected());
            parent.sendBroadcast(intent); 
            connected = true;
        }
        catch (RuntimeException runTimeEx) {

        }

        closeServerSocket();
    }


    private void connectionFailed () {

    }

    public void closeServerSocket() {
        try {
            btServerSocket.close();
        }
        catch (IOException ex) {
            Log.e(TAG+":cancel", "error while closing server socket");
        }
    }
}
于 2013-10-16T08:54:46.497 に答える