美文网首页Android开发Android 开发相关文章收集Android知识
安卓开发之自动连接蓝牙2.0设备(音响,耳机)

安卓开发之自动连接蓝牙2.0设备(音响,耳机)

作者: 木子饼干 | 来源:发表于2018-01-08 16:39 被阅读0次

    背景

    前面的文章介绍了蓝牙4.0的连接,读写操作等,这篇文章主要是蓝牙2.0(传统蓝牙)与蓝牙耳机,音响等自动连接。

    权限

    和BLE一样,蓝牙2.0进行蓝牙相关操作,也需要使用到蓝牙权限,在AndroidManifest.xml清单文件中添加相应权限

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    

    适配器

    使用蓝牙前,需要获取蓝牙适配器

            blueToothAdapter = BluetoothAdapter.getDefaultAdapter();
           if (blueToothAdapter == null || !blueToothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
           }
    

    广播注册

    蓝牙搜索结果,配对,及连接状态,在广播中进行,因此记得实现及注册广播

     broadcastReceiver = new BroadcastReceiver() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                switch (action) {
                    case BluetoothDevice.ACTION_FOUND:
                        device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                        if (device != null) {
                            String name = device.getName();
                            if (name != null) {
                                Log.d(TAG, "onReceive: " + name);
                                if (name.contains("PuppyGo")) {
                                    if (blueToothAdapter.isDiscovering())
                                        blueToothAdapter.cancelDiscovery();
                                    device.createBond();
                                }
                            }
                        }
    
                        break;
                    case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                        device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                        switch (device.getBondState()) {
                            case BluetoothDevice.BOND_NONE:
                                Log.d(TAG, "取消配对");
                                search();
                                break;
                            case BluetoothDevice.BOND_BONDING:
                                Log.d(TAG, "配对中");
                                break;
                            case BluetoothDevice.BOND_BONDED:
                                blueToothAdapter.cancelDiscovery();
                                Log.d(TAG, "配对成功");
                                getBluetoothA2DP();
                                connect();
                                break;
                        }
                        break;
                    case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
                        switch (intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1)) {
                            case BluetoothA2dp.STATE_CONNECTING:
                                device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                Log.d(TAG, "device: " + device.getName() + " connecting");
                                break;
                            case BluetoothA2dp.STATE_CONNECTED:
                                isConnected = true;
                                device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                if (device != null) {
                                    String name = device.getName();
                                    if (name != null) {
                                        mName.setText(name);
                                    }
                                }
                                mPlayer = MediaPlayer.create(context, R.raw.summer);
                                mPlayer.start();
    
                                Log.d(TAG, "device: " + device.getName() + " connected");
                                break;
                            case BluetoothA2dp.STATE_DISCONNECTING:
                                device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                break;
                            case BluetoothA2dp.STATE_DISCONNECTED:
                                isConnected = false;
                                device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                Log.d(TAG, "device: " + device.getName() + " disconnected");
    
                                mName.setText("蓝牙名称:");
                                if (mPlayer != null) {
                                    mPlayer.pause();
                                    mPlayer.release();
                                    mPlayer = null;
                                }
                                search();
    
    
                                break;
                            default:
                                break;
                        }
                        break;
                }
            }
        };
        //注册广播
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
        registerReceiver(broadcastReceiver, intentFilter);
    

    搜索蓝牙

    在获取适配器,注册广播之后,就可以开始搜索蓝牙设备

      if (blueToothAdapter != null && blueToothAdapter.isEnabled()) {
            blueToothAdapter.startDiscovery();
        }
    

    搜索后的结果,会在BluetoothDevice.ACTION_FOUND中回调

         case BluetoothDevice.ACTION_FOUND:
                        device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                        if (device != null) {
                            String name = device.getName();
                            if (name != null) {
                                Log.d(TAG, "onReceive: " + name);
                                if (name.contains("PuppyGo")) {
                                    if (blueToothAdapter.isDiscovering())
                                        blueToothAdapter.cancelDiscovery();
                                    device.createBond();
                                }
                            }
                        }
                        break;
    

    如果搜索的结果,是你想要的蓝牙设备,便可以调用device.createBond()设置配对,网上也有另外的方法通过反射进行配对

    配对成功

    配对成功之后, 会返回BluetoothDevice.BOND_BONDED状态,亲测有些手机会自动连接上蓝牙2.0,但大部分手机还需要进行连接,这时候需要通过getProfileProxy来getBluetoothA2DP
    
                           case BluetoothDevice.BOND_BONDED:
                                blueToothAdapter.cancelDiscovery();
                                Log.d(TAG, "配对成功");
                                getBluetoothA2DP();
                                connect();
                                break;
    

    之后通过mBluetoothA2dp反射来进行连接

      //connect是隐藏的方法,只能通过反射机制来调用
    private void connect() {
    
        if (mBluetoothA2dp == null) {
            return;
        }
        if (device == null) {
            return;
        }
    
        try {
            Log.d(TAG, "connect" + device.getName());
            Method connect = mBluetoothA2dp.getClass().getDeclaredMethod("connect", BluetoothDevice.class);
            connect.setAccessible(true);
            connect.invoke(mBluetoothA2dp, device);
        } catch (Exception e) {
            Log.e(TAG, "connect exception:" + e);
            e.printStackTrace();
        }
    }
    

    连接成功会返回BluetoothA2dp.STATE_CONNECTED状态,至此,蓝牙设备已经连接成功,便可以进行一些操作,公司这边是要求播放歌曲来测试蓝牙音响是否卡顿,因此我这里进行简单的歌曲播放

    取消配对

    公司测试蓝牙连接过程中,会连接大量的蓝牙设备,如果没有取消配对,那么手机设置里面会出现一堆的配对设备。

        //取消配对
    private void unPairAllDevices() {
        Log.i(TAG, "unPairAllDevices");
        for (BluetoothDevice device : blueToothAdapter.getBondedDevices()) {
            String name = device.getName();
            if (name != null) {
                if (name.contains("PuppyGo")) {
                    try {
                        Method removeBond = device.getClass().getDeclaredMethod("removeBond");
                        removeBond.invoke(device);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

    最后

    不同于BLE连接,蓝牙2.0的连接,系统并没有提供相应方法,只能通过反射进行连接。自动连接过程中,如果在扫描结束后,仍没有搜索到相关设备,则需要通过延时操作,进行再次搜索。

    new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (!isConnected) {
                    search();
                }
            }
        }, 15000);
    

    延时操作的方法有多种,自己使用喜欢的方式。Demo比较简单,就不上传代码了,有问题认真阅读就行了。最后,不要吝惜你的钛合金右手点个赞。

    相关文章

      网友评论

        本文标题:安卓开发之自动连接蓝牙2.0设备(音响,耳机)

        本文链接:https://www.haomeiwen.com/subject/fepbnxtx.html