Android 蓝牙通信的梳理总结

       从项目中封装出来的Demo,  先上效果图,图1是刚运行app搜索蓝牙设备的效果动图,图2是点击搜到的蓝牙设备列表项的发起连接效果图,图3是被点击的蓝牙设备收到的蓝牙配对请求效果图:

           

                                图1                               图2                                图3

 

      Android中的无线传输蓝牙通信,先增加权限:

 
 

       接下来正式进入代码部分,第一步是先获取系统默认的蓝牙适配器,打开蓝牙。BluetoothAdapter.getDefaultAdapter()这个方法是获取默认蓝牙适配器的唯一方法,获得适配器之后打开蓝牙却有2种方式,直接用方法enable()可以打开蓝牙,但是这个方法打开蓝牙不会弹出提示,实际的开发场景多会需要UI交互提示用户,所以多用Intent的方式去打开蓝牙,图2的效果便是如此:

 /**
     * 开启蓝牙且被发现
     *
     * enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,更多的时候我们需要问下用户是否打开,一下这两行代码同样是打开蓝牙,不过会提示用户:
     *
     *  Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
     *  enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
     */
    private void enablebluetooth() {

        //获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        startActivityForResult(enable, REQUEST_DISCOVERABLE);
    }

        然后在onActivityResult响应中,mBtAdapter.startDiscovery()开始搜索周围的蓝牙设备:

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_DISCOVERABLE:
                if (resultCode != Activity.RESULT_CANCELED) {
                    mBtAdapter.startDiscovery();        //startDiscovery()开始搜索,这是搜索的第一步, 使用BluetoothAdapter的startDiscovery()方法来搜索蓝牙设备
                    String blueToothName = SharedPreferencesUtils.getInst().getBlueToothAddress(context);
                    if (TextUtils.isEmpty(blueToothName)) {
                    } else {
                        device = mBtAdapter.getRemoteDevice(blueToothName);
                        if (device != null) {
                            if (client == null || !client.isConnect()) {
                                client = BlueToothTool.getInstance();
                                client.setDevice(device);
                                client.setMhandler(handler);
                                client.connect();
                                newBlueToothConnect = true;
                            }
                        } else
                            mBtAdapter.startDiscovery();
                    }
                }
                break;
            default:
                break;
        }
    }









    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            System.out.println("----------------------------------" + msg.what + "----------------------------------");
            switch (msg.what) {
                case BlueToothTool.CONNECT_FAILED:

                    newBlueToothConnect = false;
                    break;
                case BlueToothTool.CONNECT_SUCCESS:

                    STContext.getInst().bluetoothDevice = device;
                    SharedPreferencesUtils.getInst().setBlueToothAddress(device.getAddress(), context);
                    isFindBlueToothDevice = false;

                    break;
                case BlueToothTool.READ_FAILED:

                    break;
                case BlueToothTool.WRITE_FAILED:
//
                    break;
                case BlueToothTool.DATA:
                    if (msg.obj != null && msg.obj.toString().length() > 10) {
                        STContext.getInst().bluetoothDevice = device;
                        newBlueToothConnect = false;
                        SharedPreferencesUtils.getInst().setBlueToothAddress(device.getAddress(), context);
                    }
                    break;
            }
        }
    };

      接着注册蓝牙寻找相关的广播,并在广播接受器对相应的广播编写相关的逻辑

    /**
     * 注册广播事件
     *
     * BluetoothDevice.ACTION_FOUND:搜索到
     * ACTION_DISCOVERY_FINISHED:搜索结束
     * ACTION_FOUND:找到设备,这个Intent中包含两个extra fields:EXTRA_DEVICE和EXTRA_CLASS,分别包含BluetooDevice和BluetoothClass。
     * 我们可以自己注册相应的BroadcastReceiver来接收响应的广播,以便实现某些功能
     */
    @Override
    public void onResume() {
        super.onResume();
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        receiver = new BluetoothReceiver();
        registerReceiver(receiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(receiver, filter);
    }






    /**
     * 广播接收器
     */
    private class BluetoothReceiver extends 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);
                //getAddress()获取本地蓝牙地址       getName()获取本地蓝牙名称
                if (!TextUtils.isEmpty(device.getName()) && !TextUtils.equals("null", device.getName())) {
                    String str = device.getName() + "|" + device.getAddress();

                    if (deviceList.indexOf(str) == -1)// 防止重复添加
                        deviceList.add(str); // 获取设备名称和mac地址
                    if (multiTypeAdapter != null) {
                        multiTypeAdapter.notifyItemInserted(deviceList.size());
                        rl_system_message.scrollToPosition(deviceList.size());
                    }
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                if (findCount < 2) {
                    mBtAdapter.cancelDiscovery();
                    findCount++;
                    pro_loading.setVisibility(View.GONE);
                    txt_state.setText("检测完毕");
                }
            }
        }
    }

  点击想连接的蓝牙设备后,执行连接方法,其中核心是BluetoothServerSocket蓝牙连接对象:

   /**
     * 开辟连接线程任务
     */
    public void connect() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                BluetoothSocket tmp = null;
                Method method;
                activeDisconnect = false;
                try {
                    method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
                    tmp = (BluetoothSocket) method.invoke(device, 1);
                } catch (Exception e) {
                    System.out.println("----------------------------------" + "11111111111111111111" + "----------------------------------");
                    setState(CONNECT_FAILED);
                    Log.e("TAG", e.toString());
                }
                socket = tmp;
                try {
                    socket.connect();
                    isConnect = true;
                    if (nullDataCount == 0) {
                        setState(CONNECT_SUCCESS);
                    } else {
                        nullDataCount = 0;
                        reconnectCount++;
                    }
                    Readtask readtask = new Readtask();  //连接成功后开启读取数据的线程
                    readtask.start();
                } catch (Exception e) {
                    System.out.println("----------------------------------" + "2222222222222222222" + "----------------------------------");
                    System.out.println("----------------------------------" + e.getMessage() + "----------------------------------");
                    if (!activeDisconnect){
                        setState(CONNECT_FAILED);
                        isConnect = false;
                    }
                    Log.e("TAG", e.toString());
                }
            }
        });
        new Thread(thread).start();
    }

   Demo已上传:https://download.csdn.net/download/crystal_xing/10878789

你可能感兴趣的:(android)