Android蓝牙背景监听器

时间:2013-10-16 05:37:28

标签: android bluetooth android-bluetooth background-service

我正在开发一个带蓝牙聊天的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());
  } 
}
}
}

1 个答案:

答案 0 :(得分:0)

我开发了类似的bt-chat,我会告诉你我做了哪些不同的工作:

而不是doInBackground,asyncTask并在活动中定义新的runnable,我启动并管理不同线程上的连接。这样连接就会保持打开状态。

编辑:我添加了服务器线程代码。 请注意,当服务器连接时,它会发送广播,因此任何活动都可以注册并接收,因此在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");
        }
    }
}