2013-10-16 40 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