Android的蓝牙后台监听器 [英] Android Bluetooth background listener

查看:843
本文介绍了Android的蓝牙后台监听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个Android应用程序与蓝牙聊天。我已经成功地实现蓝牙聊天有两个phones.But我的问题是,如果我更改到下一个活动的聊天活动连接丢失,那么我无法从次活动发送消息。我该如何维护我的连接?
这就是我想要保持连接,通过我的应用程序。每当退出按钮,用户preSS则只有连接可断开连接。我想从一个活动发送消息,并从另一项活动收到这就是我想要的。我不能用我的code创建一个后台服务。
谁能帮我拆我的code?如果我得到一个消息从一个手机,然后我要处理的消息,我想送回来的结果,处理将是下一个活动,这是我的应用程序的工作。

 公共类BluetoothTexting延伸活动{

  私有静态诠释DISCOVERY_REQUEST = 1;

  私人处理程序处理程序=新的处理程序();

  私人的ArrayList< BluetoothDevice类> foundDevices =新的ArrayList< BluetoothDevice类>();
    私人ArrayAdapter< BluetoothDevice类> AA;
  私人的ListView列表;

  私人BluetoothAdapter蓝牙;
  私有的BluetoothSocket插座;
  私人的UUID的uuid = UUID.fromString(00001101-0000-1000-8000-00805F9B34FB);

  @覆盖
  公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);


    configureBluetooth();


    setupListView();


    setupSearchButton();


    setupListenButton();
    }

     私人无效configureBluetooth(){
     蓝牙= BluetoothAdapter.getDefaultAdapter();
     }

      私人无效setupListenButton(){
      按钮listenButton =(按钮)findViewById(R.id.button_listen);
      listenButton.setOnClickListener(新OnClickListener(){
      公共无效的onClick(视图查看){
       意图盘=新的意图(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
      startActivityForResult(盘,DISCOVERY_REQUEST);
     }
    });
    }

     @覆盖
     保护无效onActivityResult(INT申请code,INT结果code,意图数据){
     如果(要求code == DISCOVERY_REQUEST){
      布尔isDiscoverable =结果code取代; 0;
      如果(isDiscoverable){
       字符串名称=bluetoothserver;
        尝试 {
         最后BluetoothServerSocket btserver =
         bluetooth.listenUsingRfcommWithServiceRecord(名称,UUID);

          AsyncTask的<整数,无效的BluetoothSocket> acceptThread =
         新的AsyncTask<整数,无效的BluetoothSocket>(){

        @覆盖
        受保护的BluetoothSocket doInBackground(整数... PARAMS){
          尝试 {
            插座= btserver.accept(PARAMS [0] * 1000);
            返回插座;
          }赶上(IOException异常E){
            Log.d(蓝牙,e.getMessage());
          }
          返回null;
        }

        @覆盖
        保护无效onPostExecute(的BluetoothSocket结果){
          如果(结果!= NULL)
            switchUI();
        }
      };
      acceptThread.execute(结果code);
    }赶上(IOException异常E){
      Log.d(蓝牙,e.getMessage());
    }
  }
}
}

      私人无效setupListView(){
        AA =新的ArrayAdapter< BluetoothDevice类>(这一点,
           android.R.layout.simple_list_item_1,
           foundDevices);
      名单=(ListView控件)findViewById(R.id.list_discovered);
      list.setAdapter(AA);

     list.setOnItemClickListener(新OnItemClickListener(){
      公共无效onItemClick(适配器视图<>为arg0,视图中查看,
                          INT指数,长ARG3){
       AsyncTask的<整数,虚空,虚空> connectTask =
       新的AsyncTask<整数,虚空,虚空>(){
        @覆盖
        保护无效doInBackground(整数... PARAMS){
          尝试 {
            BluetoothDevice类设备= foundDevices.get(PARAMS [0]);
            插座= device.createRfcommSocketToServiceRecord(UUID);
            Socket.connect()的;
          }赶上(IOException异常E){
            Log.d(BLUETOOTH_CLIENT,e.getMessage());
          }
          返回null;
        }

        @覆盖
        保护无效onPostExecute(无效的结果){
          switchUI();
        }
      };
    connectTask.execute(指数);
  }
});
}

        私人无效setupSearchButton(){
        按钮searchButton =(按钮)findViewById(R.id.button_search);

         sea​​rchButton.setOnClickListener(新OnClickListener(){
         公共无效的onClick(视图查看){
         registerReceiver(discoveryResult,
                     新的IntentFilter(BluetoothDevice.ACTION_FOUND));

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

   私人无效switchUI(){
   最后的TextView =的MessageText(TextView中)findViewById(R.id.text_messages);
   最后的EditText TEXTENTRY =(EditText上)findViewById(R.id.text_message);
   最终按钮btnSend =(按钮)findViewById(R.id.send);

   messageText.setVisibility(View.VISIBLE);
   list.setVisibility(View.GONE);
  textEntry.setEnabled(真正的);
    btnSend.setOnClickListener(新OnClickListener(){

    @覆盖
    公共无效的onClick(视图v){

        如果(textEntry.getText()长度()> 0)
        {
             的sendMessage(插座,textEntry.getText()的toString());

        }
        其他
        {
             的sendMessage(插座,Test_String);
        }
    }
});
      /*textEntry.setOnKeyListener(new OnKeyListener(){
        公共布尔onKey(查看视图,INT关键code,KeyEvent的的keyEvent){
         如果((keyEvent.getAction()== KeyEvent.ACTION_DOWN)及&安培;
        (钥匙code == KeyEvent.KEY code_DPAD_CENTER)){
        的sendMessage(插座,textEntry.getText()的toString());
         textEntry.setText();
         返回true;
         }
        返回false;
  }
}); * /
       BluetoothSocketListener BSL =新BluetoothSocketListener(插座,处理程序,的MessageText);
帖子消息监听=新主题(BSL);
    messageListener.start();
}

    私人无效的sendMessage(的BluetoothSocket插座,弦乐味精){
    的OutputStream outStream;
    尝试 {
     outStream = socket.getOutputStream();
    byte []的字节字符串=(MSG +).getBytes();
    字节字符串[byteString.length  -  1] = 0;
    outStream.write(字节字符串);
  // outStream.close();
   // socket.close();
  }赶上(IOException异常E){
    Log.d(BLUETOOTH_COMMS,e.getMessage());
  }
  }

  BroadcastReceiver的discoveryResult =新的BroadcastReceiver(){
   @覆盖
    公共无效的onReceive(上下文的背景下,意图意图){
   BluetoothDevice类远端设备;
   远端设备= intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
   如果(bluetooth.getBondedDevices()。包括(远端设备)){
     foundDevices.add(远端设备);
     aa.notifyDataSetChanged();
   }
 }
 };

    私有类MessagePoster实现Runnable {
     私人的TextView TextView的;
     私人字符串信息;

     公共MessagePoster(TextView的TextView的,字符串消息){
     this.textView = TextView的;
     this.message =消息;
   }

    公共无效的run(){
     textView.append(\ N+消息);
    Toast.makeText(getApplicationContext(),消息,Toast.LENGTH_LONG).show();
    }
  }

      私有类BluetoothSocketListener实现Runnable {

  私有的BluetoothSocket插座;
  私人的TextView TextView的;
  私人处理程序处理程序;

  公共BluetoothSocketListener(的BluetoothSocket插座,
                                 处理程序处理程序,TextView的TextView的){
    this.socket =插座;
    this.textView = TextView的;
    this.handler =处理程序;
  }

    公共无效的run(){
    INT缓冲区大小= 1024;
  byte []的缓冲区=新的字节[BUFFERSIZE]
  尝试 {
    InputStream的河道= socket.getInputStream();
    INT读取动作= -1;
    字符串消息=;
    而(真){
      消息=;
      读取动作= instream.read(缓冲液);
      如果(读取动作!= -1){
        而((读取动作== BUFFERSIZE)及及(缓冲液[BUFFERSIZE-1] = 0)!){
          消息=信息+新的String(缓冲,0,读取动作);
          读取动作= instream.read(缓冲液);
        }
        消息=信息+新的String(缓冲,0,读取动作 -  1);

        handler.post(新MessagePoster(TextView的,消息));
        socket.getInputStream();

      }
    }
  }赶上(IOException异常E){
    Log.d(BLUETOOTH_COMMS,e.getMessage());
  }
}
}
}
 

解决方案

我开发了一个类似的BT-聊天,我会告诉ü,我所做的不同而evantually工作:

而不是doInBackground,AsyncTask的,并确定新的可运行我发起并管理在不同的线程连接的活动中。这样的连接保持打开。

编辑:我添加的服务器线程code。 请注意,当服务器连接发送一个广播这样的活动可以注册并领取因此在不断变化的活动,而BT的连接没有问题。

 公共类服务器扩展Thread {


    私人BluetoothAdapter btAdapter;
    私人字符串socketString =一个随机字符串;
    私人BluetoothServerSocket btServerSocket;
    私有的BluetoothSocket btConnectedSocket;
    私人最终字符串变量=服务器;
    私人MainActivity父母;
    / *包保护* / static final的字符串操作=蓝牙套接字连接;
    私人布尔连接;

    公共服务器(MainActivity父){
        this.parent =父母;
        连接= FALSE;
    }

    @覆盖
    公共无效的run(){
        btAdapter = BluetoothAdapter.getDefaultAdapter();

        尝试 {
            Log.i(TAG,从适配器获得插座);
            btServerSocket = btAdapter.listenUsingRfcommWithServiceRecord(socketString,MainActivity.BT_UUID);
            听();

        }
        赶上(IOException异常前){
            Log.e(TAG,错误在初始化);
        }
    }

    私人无效听(){
        Log.i(TAG,听);
        btConnectedSocket = NULL;
        而(!连接){
            尝试 {
                btConnectedSocket = btServerSocket.accept();
            }
            赶上(IOException异常前){
                Log.e(TAG,连接失败);
                连接失败();
            }

            如果(btConnectedSocket!= NULL){
                广播();
                closeServerSocket();
            }
            其他 {
                Log.i(TAG,插座为空);
                连接失败();
            }
        }

    }

    私人无效广播(){
        尝试 {
            Log.i(TAG,有联系吗?+ btConnectedSocket.isConnected());
            意向意图=新的意图();
            intent.setAction(ACTION);
            intent.putExtra(状态,btConnectedSocket.isConnected());
            parent.sendBroadcast(意向);
            连接=真正的;
        }
        赶上(RuntimeException的runTimeEx){

        }

        closeServerSocket();
    }


    私人无效为connectionFailed(){

    }

    公共无效closeServerSocket(){
        尝试 {
            btServerSocket.close();
        }
        赶上(IOException异常前){
            Log.e(TAG +:取消,错误而关闭服务器套接字);
        }
    }
}
 

I am developing an android application with bluetooth chat. I have successfully implemented bluetooth chat with two phones.But my problem is that if I Change to next activity from the chatting activity the connection is lost then I am not able to send messages from second activity. How can I maintain my connection?
That is I want to stay connected through out my app. Whenever the user press on exit button then only the connection can disconnect. I want to send message from one activity and receive from another activity this is what I want. I am not able to create a background service with my code.
Can anyone help me to split my code? If I got a message from one phone then I want to process the message and I want to send back the result, that processing will be on next activity this is the working of my app.

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

解决方案

I developed a similar bt-chat and i'll tell u what i did different which evantually worked:

instead of doInBackground, asyncTask and defining new runnable inside the activity i initiated and managed the connection on different threads. that way the connection stays opened.

EDIT: i added the server thread code. notice that when the server is connected it sends a broadcast so any activity could register it and receive so there is no problem in changing activities while the BT connects.

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

这篇关于Android的蓝牙后台监听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆