记录下连接经典蓝牙遇到的坑。
一些基本概念资料很多,这里直接上代码,里面都有注释和一些关键点。
整个类如下:
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"
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)