Android经典蓝牙连接

Android经典蓝牙连接,第1张

记录下连接经典蓝牙遇到的坑。

一些基本概念资料很多,这里直接上代码,里面都有注释和一些关键点。

整个类如下:



import android.app.Activity;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 
 * time:2022/2/15
 */
public class BleControlTool {

    private static BleControlTool mInstance;
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothReceiver mReceiver;
    private BluetoothDevice mDeviceResult;  //连接的设备
    private BluetoothA2dp mBluetoothA2dp;   //高级音频传输协议

    private Activity mActivity;

    private BleControlTool() {

    }

    public static BleControlTool getInstance() {
        if (mInstance == null) {
            synchronized (BleControlTool.class) {
                if (mInstance == null) {
                    mInstance = new BleControlTool();
                }
            }
        }
        return mInstance;
    }

    public void startBlueToothConnect(Activity activity) {
        mActivity = activity;
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (!mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.enable();
        }

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);//发现设备
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//配对
        intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束

        //注意,有些设备连接状态是这个广播,我就是栽在这里,一台设备是这里的回调,有些设备又是下面的广播回调,所以要做兼容...
        intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
        //注意,有些设备连接状态又是这个广播,
        intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);

        mReceiver = new BluetoothReceiver();
        mActivity.registerReceiver(mReceiver, intentFilter);

        mBluetoothAdapter.getProfileProxy(mActivity, new BluetoothProfile.ServiceListener() {
            @Override
            public void onServiceConnected(int profile, BluetoothProfile proxy) {
                MagicLog.e("-----onServiceConnected1");
                if (profile == BluetoothProfile.A2DP) {
                    //Service连接成功,获得BluetoothA2DP
                    MagicLog.e("-----onServiceConnected2");
                    mBluetoothA2dp = (BluetoothA2dp) proxy;

                    //获取到 mBluetoothA2dp 后才开始扫描,如果蓝牙没有预先打开,这里会先执行,mBluetoothAdapter.enable()调用之后,这做一个延时
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            //开始扫描
                            startDiscovery();
                        }
                    }, 5000);

                    //这里可以做已经配对过的设备可以直接进行连接,本人没有做具体处理测试,可自行做。
                    /*Set bondedDevices = mBluetoothAdapter.getBondedDevices();
                    for (BluetoothDevice device : bondedDevices) {
                        MagicLog.d("配对过的  name:" + device.getName() + "  mac:" + device.getAddress());
                        if (device.getName().contains("Self")) {
                            mDeviceResult = device;
                            connectClassic(device);
                        }
                    }*/
                }
                /*List mDevices = proxy.getConnectedDevices();
                if (mDevices != null) {
                    for (int i = 0; i < mDevices.size(); i++) {
                        System.out.println("---连接上的设备:" + mDevices.get(i).getName() + "---" + mDevices.get(i).getAddress());
                    }
                }*/
            }

            @Override
            public void onServiceDisconnected(int profile) {
                MagicLog.e("-----onServiceDisconnected3");
            }
        }, BluetoothProfile.A2DP);
    }

    //蓝牙广播接收数据
    private class BluetoothReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (mActivity.isFinishing()) {
                MagicLog.d("-----------return");
                return;
            }
            if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device == null) {
                    return;
                }
                MagicLog.d("扫描到可连接的蓝牙设备  name:" + device.getName() + "  mac:" + device.getAddress());
                if (!TigerUtil.isEmpty(device.getName())) {
                    if (device.getName().contains("Selfie")) {
                        mDeviceResult = device;
                        createBond();
                    }
                }
            } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
                MagicLog.d("-=-==============BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED");
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, -1);
                MagicLog.d("=======state:" + state);
                switch (state) {
                    case BluetoothAdapter.STATE_CONNECTING:
                        MagicLog.d("=======STATE_CONNECTING");
                        break;
                    case BluetoothAdapter.STATE_CONNECTED:
                        MagicLog.d("=======STATE_CONNECTED,连接成功就销毁,这里销毁也是关键");
                        destroyBT();
                        break;
                    case BluetoothAdapter.STATE_DISCONNECTED:
                        MagicLog.d("=======STATE_DISCONNECTED");
                        break;
                }
            } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
                MagicLog.d("=-------BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED");
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                switch (intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1)) {
                    case BluetoothA2dp.STATE_CONNECTING:
                        BluetoothDevice deviceC = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                        MagicLog.d("=====连接中: " + deviceC.getName() + " connecting");
                        break;
                    case BluetoothA2dp.STATE_CONNECTED:
                        MagicLog.d("=====连接成功 device: " + device.getAddress() + " connected");
                        destroyBT();
                        break;
                    case BluetoothA2dp.STATE_DISCONNECTING:
                        MagicLog.d("=====连接断开 device: ");
                        break;
                    case BluetoothA2dp.STATE_DISCONNECTED:
                        MagicLog.d("=====连接断开2 device: ");
                        //进行重连
                        break;
                    default:
                        break;
                }
            } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device == null) {
                    return;
                }
                switch (bondState) {
                    case BluetoothDevice.BOND_BONDED:  //配对成功
                        MagicLog.d("=====配对ok Device:" + device.getAddress() + " bonded.");
                        connectClassic();  //连接蓝牙设备
                        break;
                    case BluetoothDevice.BOND_BONDING:
                        MagicLog.d("=====配对中 Device:" + device.getAddress() + " bonding.");
                        break;
                    case BluetoothDevice.BOND_NONE:
                        MagicLog.d("=====配对失败 Device:" + device.getAddress() + " not bonded.");
                        //不知道是蓝牙耳机的关系还是什么原因,经常配对不成功
                        //配对不成功的话,重新尝试配对
                        createBond();
                        break;
                    default:
                        break;
                }
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
                System.out.println("------扫描结束");

            }
        }
    }

    private void createBond() {
        if (mDeviceResult != null) {
            MagicLog.d("-----createBond");
            mDeviceResult.createBond();
        }
    }

    private void startDiscovery() {
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter.startDiscovery();
        }
    }

    private void cancelDiscovery() {
        if (mBluetoothAdapter != null) {
            mBluetoothAdapter.cancelDiscovery();
        }
    }

    private void connectClassic() {
        try {
            if (mBluetoothA2dp == null) {
                return;
            }
            //这里用反射连接
            Method method = mBluetoothA2dp.getClass().getMethod("connect", BluetoothDevice.class);
            //method.setAccessible(true);
            method.invoke(mBluetoothA2dp, mDeviceResult);

            MagicLog.d("直接开始连接经典blue----------connectClassic-");

        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public void destroyBT() {
        if (mBluetoothAdapter != null && mBluetoothA2dp != null) {
            mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp);
            mBluetoothA2dp = null;
            mBluetoothAdapter = null;
        }
        if (mActivity != null) {
            mActivity.unregisterReceiver(mReceiver);
            mActivity = null;
        }
    }

}

正常一般上面的步骤就差不多了,但是有些蓝牙设备是奇奇怪怪的,比如我的:

 看到红圈没有,他是个键盘图标,连接成功后,发现Activity重新创建了,那就要在清单文件加上,这也是个坑:

 android:configChanges="keyboard|keyboardHidden|navigation"
 android:screenOrientation="portrait"

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/992616.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存