安卓蓝牙通信开发

目录

一、需要达到的效果

二、项目结构

三、代码部分

1.申请权限

2.DeviceList —— 蓝牙搜索设备功能

3.ChatService —— 蓝牙连接功能

4. MainActivity—— 主聊天界面

四、效果图:


一、需要达到的效果

能用蓝牙在设备见进行简单通信。

二、项目结构

三、代码部分

1.申请权限

在AndroidManifest.xml中添加如下权限

    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

2.DeviceList —— 蓝牙搜索设备功能

蓝牙搜索主要是要实现一个BroadcastReceiver 广播接收者。
首先要注册广播,才能使用,添加蓝牙设备ACTION_FOUND等,如下

    private IntentFilter filter = new IntentFilter();
    …………………………………………………
 
    filter.addAction(BluetoothDevice.ACTION_FOUND);
    filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    this.registerReceiver(mReceiver,filter);

其次就是这里广播接收
一旦开启广播搜索,并找到设备 接收到ACTION_FOUND的信息,则可以从BluetoothDevice.EXTRA_DEVICE中得到搜索到的设备信息,显示到屏幕上。
如果是DISCOVERY_FINISHED,即结束搜索。

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override public void onReceive(Context context, Intent intent) {
            String action=intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice  device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // 得到设备信息
            }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED
                    .equals(action)){ //结束搜索了  }
            }
        }
    };


3.ChatService —— 蓝牙连接功能

通过下列3个线程来实现。

1) AcceptThread —— 被动等待连接的线程

使用BluetoothServerSocket accept函数,收到连接,则保持此连接传给 ConnectedThread 

    // 创建监听线程,准备接受新连接。使用阻塞方式,调用BluetoothServerSocket.accept()
    private class AcceptThread extends Thread{
        private final BluetoothServerSocket mmServerSocket;
 
        public AcceptThread(){
            BluetoothServerSocket tmp = null;
            try{
                tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);
            }catch (IOException e){}
            mmServerSocket = tmp;
        }
 
 
        public void run(){
        BluetoothSocket socket= null;
 
        while(mState != STATE_CONNECTED){
            try{
                socket = mmServerSocket.accept();
            }catch (IOException e) {
                break;
            }
            if(socket != null){
                connected(socket,socket.getRemoteDevice());
                try{
                    mmServerSocket.close();
                }catch (IOException e){}
            }
        }
    }
 
        public void cancel(){
            try{
                mmServerSocket.close();
            }catch (IOException e){}
        }
}

2) ConnectThread —— 主动发起连接的线程

createRfcommSocketToServiceRecord 根据UUID 发起连接,连接成功则将连接传入ConnectedThread

// 连接线程,专门用来对外发出连接对方蓝牙的请求并进行处理
    // 构造函数里通过BluetoothDevice.createRfcommSocketToServiceRecord(),
    // 从待连接的device产生BluetoothSocket,然后在run方法中connect
    // 成功后调用 BluetoothChatService的connnected()方法,定义cancel()在关闭线程时能关闭socket
    private class ConnectThread extends Thread{
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
 
        public ConnectThread(BluetoothDevice device){
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            mmDevice=device;
            BluetoothSocket tmp = null;
            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try{
                // MY_UUID is the app's UUID string, also used by the server code
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            }catch (IOException e){}
            mmSocket = tmp;
        }
 
        public void run(){
            // Cancel discovery because it will slow down the connection
            mAdapter.cancelDiscovery();
            try{
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
            }catch (IOException e){
                connectionFailed();
                // Unable to connect; close the socket and get out
                try{
                    mmSocket.close();
                }catch (IOException e2){}
 
                //ChatService.this.start();
               return;
           }
            synchronized(ChatService.this){
                mConnectedThread = null;
           }
            connected(mmSocket,mmDevice);
        }
 
        public void cancel(){
           /* try{
                mmSocket.close();
            }catch (IOException e){}*/
        }
    }

3) ConnectedThread —— 管理连接的线程

管理连接好的双方,进行数据通信。输入输出流,接收数据,发送数据
 

 // 双方蓝牙连接后一直运行的线程。构造函数中设置输入输出流。
    // Run方法中使用阻塞模式的InputStream.read()循环读取输入流
    // 然后psot到UI线程中更新聊天信息。也提供了write()将聊天消息写入输出流传输至对方,
    // 传输成功后回写入UI线程。最后cancel()关闭连接的socket
 
    private class ConnectedThread extends Thread{
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
 
        public ConnectedThread(BluetoothSocket socket){
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut=null;
            // Get the input and output streams, using temp objects because
            // member streams are final
            try{
                tmpIn=mmSocket.getInputStream();
                tmpOut=mmSocket.getOutputStream();
            }catch (IOException e){}
 
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }
 
        public void run(){
            byte[]buffer=new byte[1024];
            int bytes;
            while (true){
                try{
                    bytes = mmInStream.read(buffer);
                    mHandler.obtainMessage(MainActivity.MESSAGE_READ,bytes,-1,buffer).sendToTarget();
                }catch (IOException e){
                    connectionLost();
                    break;
                }
            }
        }
 
        public void write(byte[]buffer){
            try{
                mmOutStream.write(buffer);
            }catch (IOException e){
                Log.d("MainActivity","Send Fail");
            }
            mHandler.obtainMessage(MainActivity.MESSAGE_WRITE,buffer).sendToTarget();
        }
 
        public void cancel(){
            try{
                mmSocket.close();
            }catch (IOException e){}
        }
    }

4. MainActivity—— 主聊天界面

将双方信息显示在上方,具体代码见文章末尾代码仓库地址

四、效果图:

 

实现的功能有开启和关闭蓝牙、查找设备、打开设备可见、以及设备间的通信

主聊天界面:Listview显示对话,EditText编辑消息,点击Button发送消息

设备列表:两个ListView分别显示已配对和搜索到的设备,点击Button按钮开始查找设备。

需要注意设备在配对前需要开启设备可见

代码仓库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值