2013-10-16 74 views
3

我正在開發一個藍牙聊天的android應用程序。我已經成功地用兩部手機實現了藍牙聊天。但是我的問題是,如果我從聊天活動中切換到下一個活動,連接就會丟失,我無法從第二個活動發送消息。我怎樣才能保持連接?
這就是我想通過我的應用程序保持連接。只要用戶按退出按鈕,只有連接可以斷開。我想發送一個活動的消息,並從另一個活動接收這是我想要的。我無法使用我的代碼創建後臺服務。
任何人都可以幫我分割我的代碼嗎?如果我從一部手機收到消息,然後我想處理該消息,並且想要發回結果,那麼處理將在下一個活動中進行,這是我的應用程序的工作。Android藍牙背景監聽器

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()); 
    } 
} 
} 
} 

回答

0

我開發了一個類似BT的聊天,我會告訴ü我做了什麼不同,其evantually工作:

代替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"); 
     } 
    } 
} 
+0

我編輯並添加了一些代碼 – Tom

+0

我如何從Activity訪問這個? – Sreyas

+0

它是一個擴展線程的類。 你需要創建一個新的實例並運行它[serverInstance] .start() 它的最好的你閱讀它的深入瞭解 http://docs.oracle.com/javase/7/docs/api/ java/lang/Thread.html – Tom