6.0的蓝牙已经开发完毕,因为可以得到系统6.0的jar包,so也就开发的快些,更好些。4.4因为代码部分在setting模块里,部分在系统中,so不方便打成jar包。所以就通过广播接受改变状态之类的。也算鼓捣出来一款。
开发的思路:
1.开关蓝牙
2.扫描到蓝牙列表和得到配对列表
下面关于连接蓝牙:
A2dp:这个是蓝牙音频传输协议
AVRCP:输入设备控制协议
首先要弄清当前蓝牙的功能属于那种协议,具体代码判断协议的方法不清楚。(本项目用不到)
3.连接蓝牙
4.断开蓝牙与取消配对
1.开关蓝牙
/**
* 打开蓝牙or关闭蓝牙
* @param flag true:open
*/
public void openOrCloseBluetooth(boolean flag) {
if (flag) {
mBluetoothAdapter.enable();
} else {
mBluetoothAdapter.disable();
}
}
2.扫描到蓝牙列表和得到配对列表
扫描蓝牙
//开始扫描
public void startScan() {
if (mBluetoothAdapter != null) {
// scanResultList.clear();
if (mBluetoothAdapter.isDiscovering()) {
Log.d(TAG, "startScan: cancelDiscovery");
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();
Log.d(TAG, "startScan: 开始扫描周围蓝牙");
} else {
Log.d(TAG, "startScan: 扫描周围蓝牙异常");
}
}
扫描之后如何获取扫描结果主要通过广播获取
private void registerBluetoothBroadcastReceiver(Context context) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
if (mReceiver == null) {
mReceiver = new BluetoothBroadCasteReceiver();
}
Log.d(TAG, "registerBluetoothBroadcastReceiver: 注册蓝牙广播" + mBluetoothAdapter.isEnabled());
context.registerReceiver(mReceiver, filter);
}
接受器中主要处理这三个状态
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.d(TAG, "onReceive: 开始扫描。");
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.d(TAG, "onReceive: 扫描结束。");
if (callBack != null) {
//callBack.scan_result(scanResultList, getHasConnectBlueDevices());
callBack.scanEnd();
}
break;
case BluetoothDevice.ACTION_CLASS_CHANGED:
Log.d(TAG, "onReceive: 一个已经改变的远程设备的蓝牙类。");
break;
case BluetoothDevice.ACTION_FOUND:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
BluetoothDeviceBean bluetoothDeviceBean = new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_NONE);
if (device != null) {
//发现的设备统一给一个未配对的状态
if (callBack != null) {
callBack.foundDevice(bluetoothDeviceBean, getHasConnectBlueDevices());
}
Log.d(TAG, "onReceive: 远程设备发现。" + device.getName() + "??" + device.getAddress() + "???" + device.getBondState());
}
break;
tips:
1.扫描蓝牙的时候,扫描结束的广播等待时间较长,为了页面体验就在发现设备的广播中,做数据的收集,但注意的是同一个设备会多次被发现,所以数据要做一些扁平化处理
2.扫描的结果也包含了已经配对的,so数据应该做一些处理
获得已经配对的列表
/**
* 获得已经配对的蓝牙列表
* @return
*/
public Set getHasConnectBlueDevices() {
Set bondedDevices = mBluetoothAdapter.getBondedDevices();
Set bluetoothDeviceBeans = new LinkedHashSet<>();
if (bondedDevices != null) {
for (BluetoothDevice de :
bondedDevices) {
bluetoothDeviceBeans.add(new BluetoothDeviceBean(de, Bluetooth_State.State_BOND_BONDED));
}
Log.e(TAG, "getHasConnectBlueDevices: 已经配对的蓝牙设备" + bluetoothDeviceBeans.toString());
return bluetoothDeviceBeans;
} else {
Log.e(TAG, "没有已经配对的蓝牙设备");
return bluetoothDeviceBeans;
}
}
tips:已经配对的列表中及时当前的设备没有连接也会显示。
3.连接蓝牙
连接蓝牙主要分为两部分,一部分是配对,配对完成后再连接
配对:
/**
* 蓝牙配对
* @param btClass
* @param btDevice
*/
public void createBond(Class btClass, BluetoothDevice btDevice) {
Method createBondMethod = null;
try {
createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
} catch (NoSuchMethodException e) {
e.printStackTrace();
Log.d(TAG, "createBond: XXXX");
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.d(TAG, "createBond: XXXX1");
} catch (InvocationTargetException e) {
Log.d(TAG, "createBond: XXXX2");
e.printStackTrace();
}
}
在广播中得到配对的状态:
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
switch (state) {
case BluetoothDevice.BOND_NONE:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_NONE 删除配对" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_NONE));
}
break;
case BluetoothDevice.BOND_BONDING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_BONDING 正在配对" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_BONDING));
}
break;
case BluetoothDevice.BOND_BONDED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_BONDED 配对成功" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_BONDED));
}
//连接操作
conectBluetoothDevice(device);
break;
}
break;
收到配对成功的广播进行连接:
A2dp连接:
//连接蓝牙
public void conectBluetoothDevice(BluetoothDevice device) {
if (mA2dpService != null) {
try {
Log.d(TAG, "createBond: 配对成功开始连接");
mA2dpService.connect(device);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
输入控制设备的连接:
/**
*
* @param device
* @param isConnect true:连接 false:断开
*/
private void connectOrDisConnectHidBT(BluetoothDevice device, boolean isConnect) {
if (mHidService != null) {
//连接
try {
String flag = "";
if (isConnect) {
flag = "connect";
} else {
flag = "disconnect";
}
if (mHidService.getProfile() == getInputDeviceHiddenConstant()) {
if (device != null) {
//得到BluetoothInputDevice然后反射connect连接设备
Method method = mHidService.getProxy().getClass().getMethod(flag,
new Class[]{BluetoothDevice.class});
method.invoke(mHidService.getProxy(), device);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
}
}
/**
* 获取BluetoothProfile中hid的profile,"INPUT_DEVICE"类型隐藏,需反射获取
* @return
*/
@SuppressLint("NewApi")
public static int getInputDeviceHiddenConstant() {
Class clazz = BluetoothProfile.class;
for (Field f : clazz.getFields()) {
int mod = f.getModifiers();
if (Modifier.isStatic(mod) && Modifier.isPublic(mod)
&& Modifier.isFinal(mod)) {
try {
if (f.getName().equals("INPUT_DEVICE")) {
return f.getInt(null);
}
} catch (Exception e) {
}
}
}
return -1;
}
tips:连接蓝牙的时候,需要开启一个服务,通过广播接受来判定是否连接成功
A2dp的服务:
private void initA2dpService() {
Intent i = new Intent(IBluetoothA2dp.class.getName());
context.bindService(i, mConnection, Context.BIND_AUTO_CREATE);
}
IBluetoothA2dp mA2dpService;
public ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
try {
mA2dpService = IBluetoothA2dp.Stub.asInterface(service);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
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, "BluetoothA2dp.STATE_CONNECTING: " + device.getName() + " connecting");
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTING));
}
break;
case BluetoothA2dp.STATE_CONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device != null) {
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTED));
}
Log.d(TAG, "BluetoothA2dp.STATE_CONNECTED: " + device.getName() + " 连接成功");
}
break;
case BluetoothA2dp.STATE_DISCONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BluetoothA2dp.STATE_DISCONNECTING: " + device.getName() + " connecting");
break;
case BluetoothA2dp.STATE_DISCONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_DISCONNECTED));
}
Log.d(TAG, "BluetoothA2dp.STATE_DISCONNECTED: " + device.getName() + " disconnected");
break;
}
break;
输入控制设备:
//判断连接hid设备的服务是否连上
private BTHidServiceBean mHidService = null;
/**
* 查看BluetoothInputDevice源码,connect(BluetoothDevice device)该方法可以连接HID设备,但是查看BluetoothInputDevice这个类
* 是隐藏类,无法直接使用,必须先通过BluetoothProfile.ServiceListener回调得到BluetoothInputDevice,然后再反射connect方法连接
*/
private BluetoothProfile.ServiceListener connect = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
//BluetoothProfile proxy这个已经是BluetoothInputDevice类型了
mHidService = new BTHidServiceBean(profile, proxy);
}
@Override
public void onServiceDisconnected(int profile) {
}
};
/**
* 注册输入设备的服务
*/
private void initHidService() {
mBluetoothAdapter.getProfileProxy(context, connect, getInputDeviceHiddenConstant());
}
监听连接的广播:
private void registerBluetoothBroadcastReceiver(Context context) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变
filter.addAction("android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED");
if (mReceiver == null) {
mReceiver = new BluetoothBroadCasteReceiver();
}
Log.d(TAG, "registerBluetoothBroadcastReceiver: 注册蓝牙广播" + mBluetoothAdapter.isEnabled());
context.registerReceiver(mReceiver, filter);
}
case "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED":
switch (intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0)) {
case BluetoothProfile.STATE_CONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BluetoothProfile.STATE_CONNECTING: " + device.getName() + " connecting");
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTING));
}
break;
case BluetoothProfile.STATE_CONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device != null) {
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTED));
}
Log.d(TAG, "BluetoothProfile.STATE_CONNECTED: " + device.getName() + " connecting");
}
break;
case BluetoothProfile.STATE_DISCONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BluetoothProfile.STATE_DISCONNECTING: " + device.getName() + " connecting");
break;
case BluetoothProfile.STATE_DISCONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_DISCONNECTED));
}
Log.d(TAG, "BluetoothProfile.STATE_DISCONNECTED: " + device.getName() + " disconnected");
break;
}
break;
附上如何判定蓝牙是否连接成功:
A2dp:
/**
* 判断蓝牙是否已经
* @param device
* @return
*/
public boolean isHasConnected(BluetoothDevice device) {
try {
if (mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_CONNECTED) {
Log.e(TAG, "isHasConnected: XXX1::" + device.getName() + "???" + mA2dpService.getConnectionState(device));
return true;
} else {
Log.e(TAG, "isHasConnected: XXX2::" + device.getName() + "???" + mA2dpService.getConnectionState(device));
}
} catch (RemoteException e) {
e.printStackTrace();
}
return false;
}
输入设备:
//判断蓝牙是否已经
public boolean isHasConnected(BluetoothDevice device) {
if (mHidService != null) {
BluetoothProfile proxy = mHidService.getProxy();
int connectionState = proxy.getConnectionState(device);
if (connectionState == BluetoothProfile.STATE_CONNECTED) {
return true;
}
}
return false;
}
4.断开蓝牙与取消配对
断开蓝牙不等于取消配对
A2dp
/**
* 断开蓝牙连接
* @param device
*/
public void disConectBluetoothDevice(BluetoothDevice device) {
if (isHasConnected(device) && mA2dpService != null) {
try {
mA2dpService.disconnect(device);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
取消配对一定包含断开蓝牙
/**
* 清除配对历史
* @param device
*/
public void unpairDevice(BluetoothDevice device) {
try {
Method m = device.getClass()
.getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.d(TAG, "清除配对异常" + e.getMessage());
}
}
/**
* @param currentDevice
* @param isUnpairDevice 是否取消配对
*/
public void disconnect(BluetoothDevice currentDevice, boolean isUnpairDevice) {
Set hasConnectBlueDevices = helper.getHasConnectBlueDevices();
if (hasConnectBlueDevices != null) {
for (BluetoothDeviceBean di :
hasConnectBlueDevices) {
if (di.getDevice().getAddress().equals(currentDevice.getAddress())) {
helper.disConectBluetoothDevice(di.getDevice());
if (isUnpairDevice) {
helper.unpairDevice(di.getDevice());
}
break;
}
}
}
}
输入设备:
配对方法是固定的,断开连接上面已经总结
附件1:4.4蓝牙A2dp工具类:
package com.ygjy.setting4_0.bluetooth.uitls;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.IBluetoothA2dp;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import com.ygjy.setting4_0.bluetooth.bean.BluetoothDeviceBean;
import com.ygjy.setting4_0.bluetooth.bean.Bluetooth_State;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* @创建人:hcy
* @创建时间:2018/11/9
* @作用描述:Function
**/
public class BlueToothHelper {
private static final String TAG = "BlueToothHelper>>>";
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
//private Set scanResultList;
private Context context;
public BlueToothHelper(Context context) {
//获得蓝牙管理对象
this.context = context;
mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
//获得蓝牙适配器
mBluetoothAdapter = mBluetoothManager.getAdapter();
//scanResultList = new LinkedHashSet<>();
if (hasBluetooth()) {
initA2dpService();
registerBluetoothBroadcastReceiver(context);
} else {
Toast.makeText(context, "当前设备不支持蓝牙", Toast.LENGTH_SHORT).show();
}
}
/**
* 设备是否支持蓝牙
*
* @return true:支持 false:不支持
*/
public boolean hasBluetooth() {
if (mBluetoothAdapter != null) {
Log.d(TAG, "该设备支持蓝牙:本机的蓝牙名称" + mBluetoothAdapter.getName());
return true;
} else {
Log.d(TAG, "该设备不支持蓝牙");
}
return false;
}
private BroadcastReceiver mReceiver;
/**
* 注册广播可以获取扫描结果和配对的状态
* @param context
*/
private void registerBluetoothBroadcastReceiver(Context context) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
if (mReceiver == null) {
mReceiver = new BluetoothBroadCasteReceiver();
}
Log.d(TAG, "registerBluetoothBroadcastReceiver: 注册蓝牙广播" + mBluetoothAdapter.isEnabled());
context.registerReceiver(mReceiver, filter);
}
public void unregisterBluetoothBroadCastReceiver(Context context) {
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
if (mA2dpService != null) {
context.unbindService(mConnection);
}
if (mReceiver != null) {
context.unregisterReceiver(mReceiver);
}
}
//开始扫描
public void startScan() {
if (mBluetoothAdapter != null) {
// scanResultList.clear();
if (mBluetoothAdapter.isDiscovering()) {
Log.d(TAG, "startScan: cancelDiscovery");
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();
Log.d(TAG, "startScan: 开始扫描周围蓝牙");
} else {
Log.d(TAG, "startScan: 扫描周围蓝牙异常");
}
}
//判断蓝牙是否已经开启
public boolean isEnabled() {
boolean bluetooth_state = mBluetoothAdapter.isEnabled();
Log.d(TAG, "isEnabled: 蓝牙当前是否开启::" + bluetooth_state);
return bluetooth_state;
}
/**
* 打开蓝牙or关闭蓝牙
* @param flag true:open
*/
public void openOrCloseBluetooth(boolean flag) {
if (flag) {
mBluetoothAdapter.enable();
} else {
mBluetoothAdapter.disable();
}
}
//蓝牙的广播
public class BluetoothBroadCasteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = null;
switch (action) {
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.d(TAG, "onReceive: 开始扫描。");
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
Log.d(TAG, "onReceive: 扫描结束。");
if (callBack != null) {
//callBack.scan_result(scanResultList, getHasConnectBlueDevices());
callBack.scanEnd();
}
break;
case BluetoothDevice.ACTION_CLASS_CHANGED:
Log.d(TAG, "onReceive: 一个已经改变的远程设备的蓝牙类。");
break;
case BluetoothDevice.ACTION_FOUND:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
BluetoothDeviceBean bluetoothDeviceBean = new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_NONE);
if (device != null) {
//发现的设备统一给一个未配对的状态
if (callBack != null) {
callBack.foundDevice(bluetoothDeviceBean, getHasConnectBlueDevices());
}
Log.d(TAG, "onReceive: 远程设备发现。" + device.getName() + "??" + device.getAddress() + "???" + device.getBondState());
}
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
switch (state) {
case BluetoothDevice.BOND_NONE:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_NONE 删除配对" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_NONE));
}
break;
case BluetoothDevice.BOND_BONDING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_BONDING 正在配对" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_BONDING));
}
break;
case BluetoothDevice.BOND_BONDED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_BONDED 配对成功" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_BONDED));
}
//连接操作
conectBluetoothDevice(device);
break;
}
break;
case BluetoothAdapter.ACTION_STATE_CHANGED:
int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
switch (blueState) {
case BluetoothAdapter.STATE_TURNING_ON:
break;
case BluetoothAdapter.STATE_ON:
Log.d(TAG, "onReceives: 蓝牙已经打开");
if (callBack != null) {
callBack.bluetooth_openOrClose(true);
}
break;
case BluetoothAdapter.STATE_TURNING_OFF:
break;
case BluetoothAdapter.STATE_OFF:
Log.d(TAG, "onReceives: 蓝牙已经关闭");
if (callBack != null) {
callBack.bluetooth_openOrClose(false);
}
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, "BluetoothA2dp.STATE_CONNECTING: " + device.getName() + " connecting");
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTING));
}
break;
case BluetoothA2dp.STATE_CONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device != null) {
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTED));
}
Log.d(TAG, "BluetoothA2dp.STATE_CONNECTED: " + device.getName() + " 连接成功");
}
break;
case BluetoothA2dp.STATE_DISCONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BluetoothA2dp.STATE_DISCONNECTING: " + device.getName() + " connecting");
break;
case BluetoothA2dp.STATE_DISCONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_DISCONNECTED));
}
Log.d(TAG, "BluetoothA2dp.STATE_DISCONNECTED: " + device.getName() + " disconnected");
break;
}
break;
}
}
}
//连接蓝牙
public void conectBluetoothDevice(BluetoothDevice device) {
if (mA2dpService != null) {
try {
Log.d(TAG, "createBond: 配对成功开始连接");
mA2dpService.connect(device);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
/**
* 断开蓝牙连接
* @param device
*/
public void disConectBluetoothDevice(BluetoothDevice device) {
if (isHasConnected(device) && mA2dpService != null) {
try {
mA2dpService.disconnect(device);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
public interface BuletoothCallBack {
void foundDevice(BluetoothDeviceBean deviceBean, Set hasBoundSet);
void scan_result(Set list, Set hasBoundSet);
void scanEnd();
void bluetooth_openOrClose(boolean b);
void update_state(BluetoothDeviceBean deviceBean);
}
private BuletoothCallBack callBack;
public void setCallBack(BuletoothCallBack callBack) {
this.callBack = callBack;
}
public boolean isConnectedAddress(BluetoothDevice _b) {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Class bluetoothAdapterClass = BluetoothAdapter.class;//得到BluetoothAdapter的Class对象
try {//得到蓝牙状态的方法
Method method = bluetoothAdapterClass.getDeclaredMethod("getConnectionState", (Class[]) null);
//打开权限
method.setAccessible(true);
int state = (int) method.invoke(bluetoothAdapter, (Object[]) null);
if (state == BluetoothAdapter.STATE_CONNECTED) {
Log.i(TAG, "BluetoothAdapter.STATE_CONNECTED");
Set devices = bluetoothAdapter.getBondedDevices();
Log.i(TAG, "devices:" + devices.size());
for (BluetoothDevice device : devices) {
Method isConnectedMethod = BluetoothDevice.class.getDeclaredMethod("isConnected", (Class[]) null);
method.setAccessible(true);
boolean isConnected = (boolean) isConnectedMethod.invoke(device, (Object[]) null);
if (isConnected) {
Log.i(TAG, "connected:" + device.getAddress());
if (getAddress(_b).equals(device.getAddress())) {
return true;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public String getAddress(BluetoothDevice device) {
return device.getAddress();
}
/**
* 获得已经配对的蓝牙列表
* @return
*/
public Set getHasConnectBlueDevices() {
Set bondedDevices = mBluetoothAdapter.getBondedDevices();
Set bluetoothDeviceBeans = new LinkedHashSet<>();
if (bondedDevices != null) {
for (BluetoothDevice de :
bondedDevices) {
bluetoothDeviceBeans.add(new BluetoothDeviceBean(de, Bluetooth_State.State_BOND_BONDED));
}
Log.e(TAG, "getHasConnectBlueDevices: 已经配对的蓝牙设备" + bluetoothDeviceBeans.toString());
return bluetoothDeviceBeans;
} else {
Log.e(TAG, "没有已经配对的蓝牙设备");
return bluetoothDeviceBeans;
}
}
/**
* 清除配对历史
* @param device
*/
public void unpairDevice(BluetoothDevice device) {
try {
Method m = device.getClass()
.getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.d(TAG, "清除配对异常" + e.getMessage());
}
}
/**
* 蓝牙配对
* @param btClass
* @param btDevice
*/
public void createBond(Class btClass, BluetoothDevice btDevice) {
Method createBondMethod = null;
try {
createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
} catch (NoSuchMethodException e) {
e.printStackTrace();
Log.d(TAG, "createBond: XXXX");
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.d(TAG, "createBond: XXXX1");
} catch (InvocationTargetException e) {
Log.d(TAG, "createBond: XXXX2");
e.printStackTrace();
}
}
private void initA2dpService() {
Intent i = new Intent(IBluetoothA2dp.class.getName());
context.bindService(i, mConnection, Context.BIND_AUTO_CREATE);
}
IBluetoothA2dp mA2dpService;
public ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
try {
mA2dpService = IBluetoothA2dp.Stub.asInterface(service);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
public Intent getExplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
/**
* 判断蓝牙是否已经
* @param device
* @return
*/
public boolean isHasConnected(BluetoothDevice device) {
try {
if (mA2dpService.getConnectionState(device) == BluetoothA2dp.STATE_CONNECTED) {
Log.e(TAG, "isHasConnected: XXX1::" + device.getName() + "???" + mA2dpService.getConnectionState(device));
return true;
} else {
Log.e(TAG, "isHasConnected: XXX2::" + device.getName() + "???" + mA2dpService.getConnectionState(device));
}
} catch (RemoteException e) {
e.printStackTrace();
}
return false;
}
}
附件2:蓝牙输入控制设备的工具类:
package com.ygjy.setting4_0.bluetooth.uitls;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.widget.Toast;
import com.ygjy.setting4_0.bluetooth.bean.BTHidServiceBean;
import com.ygjy.setting4_0.bluetooth.bean.BluetoothDeviceBean;
import com.ygjy.setting4_0.bluetooth.bean.Bluetooth_State;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* @创建人:hcy
* @创建时间:2018/11/9
* @作用描述:Function
**/
public class BlueToothHelper {
private static final String TAG = "BlueToothHelper>>>";
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
//private Set scanResultList;
private Context context;
BluetoothDevice device = null;
public BlueToothHelper(Context context) {
//获得蓝牙管理对象
this.context = context;
mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
//获得蓝牙适配器
mBluetoothAdapter = mBluetoothManager.getAdapter();
//scanResultList = new LinkedHashSet<>();
if (hasBluetooth()) {
initHidService();
registerBluetoothBroadcastReceiver(context);
} else {
Toast.makeText(context, "当前设备不支持蓝牙", Toast.LENGTH_SHORT).show();
}
}
/**
* 设备是否支持蓝牙
*
* @return true:支持 false:不支持
*/
public boolean hasBluetooth() {
if (mBluetoothAdapter != null) {
Log.d(TAG, "该设备支持蓝牙:本机的蓝牙名称" + mBluetoothAdapter.getName());
return true;
} else {
Log.d(TAG, "该设备不支持蓝牙");
}
return false;
}
private BroadcastReceiver mReceiver;
private void registerBluetoothBroadcastReceiver(Context context) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变
filter.addAction("android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED");
if (mReceiver == null) {
mReceiver = new BluetoothBroadCasteReceiver();
}
Log.d(TAG, "registerBluetoothBroadcastReceiver: 注册蓝牙广播" + mBluetoothAdapter.isEnabled());
context.registerReceiver(mReceiver, filter);
}
public void unregisterBluetoothBroadCastReceiver(Context context) {
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
// if (mA2dpService != null) {
// context.unbindService(mConnection);
// }
if (mReceiver != null) {
context.unregisterReceiver(mReceiver);
}
}
//开始扫描
public void startScan() {
if (mBluetoothAdapter != null) {
// scanResultList.clear();
if (mBluetoothAdapter.isDiscovering()) {
Log.d(TAG, "startScan: cancelDiscovery");
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();
Log.d(TAG, "startScan: 开始扫描周围蓝牙");
} else {
Log.d(TAG, "startScan: 扫描周围蓝牙异常");
}
}
//判断蓝牙是否已经开启
public boolean isEnabled() {
boolean bluetooth_state = mBluetoothAdapter.isEnabled();
Log.d(TAG, "isEnabled: 蓝牙当前是否开启::" + bluetooth_state);
return bluetooth_state;
}
public void openOrCloseBluetooth(boolean flag) {
if (flag) {
mBluetoothAdapter.enable();
} else {
mBluetoothAdapter.disable();
}
}
//蓝牙的广播
public class BluetoothBroadCasteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
Log.d(TAG, "onReceive: 开始扫描。");
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
if (callBack != null) {
//callBack.scan_result(scanResultList, getHasConnectBlueDevices());
callBack.scanEnd();
}
break;
case BluetoothDevice.ACTION_CLASS_CHANGED:
Log.d(TAG, "onReceive: 一个已经改变的远程设备的蓝牙类。");
break;
case BluetoothDevice.ACTION_FOUND:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
BluetoothDeviceBean bluetoothDeviceBean = new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_NONE);
if (device != null) {
//发现的设备统一给一个未配对的状态
if (callBack != null) {
callBack.foundDevice(bluetoothDeviceBean, getHasConnectBlueDevices());
}
Log.d(TAG, "onReceive: 远程设备发现。" + device.getName() + "??" + device.getAddress() + "???" + device.getBondState());
}
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
switch (state) {
case BluetoothDevice.BOND_NONE:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_NONE 删除配对" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_NONE));
}
break;
case BluetoothDevice.BOND_BONDING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_BONDING 正在配对" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_BONDING));
}
break;
case BluetoothDevice.BOND_BONDED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BOND_BONDED 配对成功" + device.getName());
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.State_BOND_BONDED));
}
conectBluetoothDevice(device);
break;
}
break;
case BluetoothAdapter.ACTION_STATE_CHANGED:
int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
switch (blueState) {
case BluetoothAdapter.STATE_TURNING_ON:
break;
case BluetoothAdapter.STATE_ON:
Log.d(TAG, "onReceives: 蓝牙已经打开");
if (callBack != null) {
callBack.bluetooth_openOrClose(true);
}
break;
case BluetoothAdapter.STATE_TURNING_OFF:
break;
case BluetoothAdapter.STATE_OFF:
Log.d(TAG, "onReceives: 蓝牙已经关闭");
if (callBack != null) {
callBack.bluetooth_openOrClose(false);
}
break;
}
break;
case "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED":
switch (intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0)) {
case BluetoothProfile.STATE_CONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BluetoothProfile.STATE_CONNECTING: " + device.getName() + " connecting");
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTING));
}
break;
case BluetoothProfile.STATE_CONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device != null) {
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_CONNECTED));
}
Log.d(TAG, "BluetoothProfile.STATE_CONNECTED: " + device.getName() + " connecting");
}
break;
case BluetoothProfile.STATE_DISCONNECTING:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.d(TAG, "BluetoothProfile.STATE_DISCONNECTING: " + device.getName() + " connecting");
break;
case BluetoothProfile.STATE_DISCONNECTED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (callBack != null) {
callBack.update_state(new BluetoothDeviceBean(device, Bluetooth_State.STATE_DISCONNECTED));
}
Log.d(TAG, "BluetoothProfile.STATE_DISCONNECTED: " + device.getName() + " disconnected");
break;
}
break;
}
}
}
//连接蓝牙
public void conectBluetoothDevice(BluetoothDevice device) {
connectOrDisConnectHidBT(device, true);
}
/**
*
* @param device
* @param isConnect true:连接 false:断开
*/
private void connectOrDisConnectHidBT(BluetoothDevice device, boolean isConnect) {
if (mHidService != null) {
//连接
try {
String flag = "";
if (isConnect) {
flag = "connect";
} else {
flag = "disconnect";
}
if (mHidService.getProfile() == getInputDeviceHiddenConstant()) {
if (device != null) {
//得到BluetoothInputDevice然后反射connect连接设备
Method method = mHidService.getProxy().getClass().getMethod(flag,
new Class[]{BluetoothDevice.class});
method.invoke(mHidService.getProxy(), device);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
}
}
public void disConectBluetoothDevice(BluetoothDevice device) {
if (isHasConnected(device)) {
//如果设备连接就让他断开连接
connectOrDisConnectHidBT(device, false);
}
}
//判断连接hid设备的服务是否连上
private BTHidServiceBean mHidService = null;
/**
* 查看BluetoothInputDevice源码,connect(BluetoothDevice device)该方法可以连接HID设备,但是查看BluetoothInputDevice这个类
* 是隐藏类,无法直接使用,必须先通过BluetoothProfile.ServiceListener回调得到BluetoothInputDevice,然后再反射connect方法连接
*/
private BluetoothProfile.ServiceListener connect = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
//BluetoothProfile proxy这个已经是BluetoothInputDevice类型了
mHidService = new BTHidServiceBean(profile, proxy);
}
@Override
public void onServiceDisconnected(int profile) {
}
};
/**
* 获取BluetoothProfile中hid的profile,"INPUT_DEVICE"类型隐藏,需反射获取
* @return
*/
@SuppressLint("NewApi")
public static int getInputDeviceHiddenConstant() {
Class clazz = BluetoothProfile.class;
for (Field f : clazz.getFields()) {
int mod = f.getModifiers();
if (Modifier.isStatic(mod) && Modifier.isPublic(mod)
&& Modifier.isFinal(mod)) {
try {
if (f.getName().equals("INPUT_DEVICE")) {
return f.getInt(null);
}
} catch (Exception e) {
}
}
}
return -1;
}
public interface BuletoothCallBack {
void foundDevice(BluetoothDeviceBean deviceBean, Set hasBoundSet);
void scan_result(Set list, Set hasBoundSet);
void scanEnd();
void bluetooth_openOrClose(boolean b);
void update_state(BluetoothDeviceBean deviceBean);
}
private BuletoothCallBack callBack;
public void setCallBack(BuletoothCallBack callBack) {
this.callBack = callBack;
}
public boolean isConnectedAddress(BluetoothDevice _b) {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Class bluetoothAdapterClass = BluetoothAdapter.class;//得到BluetoothAdapter的Class对象
try {//得到蓝牙状态的方法
Method method = bluetoothAdapterClass.getDeclaredMethod("getConnectionState", (Class[]) null);
//打开权限
method.setAccessible(true);
int state = (int) method.invoke(bluetoothAdapter, (Object[]) null);
if (state == BluetoothAdapter.STATE_CONNECTED) {
Log.i(TAG, "BluetoothAdapter.STATE_CONNECTED");
Set devices = bluetoothAdapter.getBondedDevices();
Log.i(TAG, "devices:" + devices.size());
for (BluetoothDevice device : devices) {
Method isConnectedMethod = BluetoothDevice.class.getDeclaredMethod("isConnected", (Class[]) null);
method.setAccessible(true);
boolean isConnected = (boolean) isConnectedMethod.invoke(device, (Object[]) null);
if (isConnected) {
Log.i(TAG, "connected:" + device.getAddress());
if (getAddress(_b).equals(device.getAddress())) {
return true;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public String getAddress(BluetoothDevice device) {
return device.getAddress();
}
public Set getHasConnectBlueDevices() {
Set bondedDevices = mBluetoothAdapter.getBondedDevices();
Set bluetoothDeviceBeans = new LinkedHashSet<>();
if (bondedDevices != null) {
for (BluetoothDevice de :
bondedDevices) {
bluetoothDeviceBeans.add(new BluetoothDeviceBean(de, Bluetooth_State.State_BOND_BONDED));
}
Log.e(TAG, "getHasConnectBlueDevices: 已经配对的蓝牙设备" + bluetoothDeviceBeans.toString());
return bluetoothDeviceBeans;
} else {
Log.e(TAG, "没有已经配对的蓝牙设备");
return bluetoothDeviceBeans;
}
}
//清除配对历史
public void unpairDevice(BluetoothDevice device) {
try {
Method m = device.getClass()
.getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.d(TAG, "清除配对异常" + e.getMessage());
}
}
public void createBond(Class btClass, BluetoothDevice btDevice) {
Method createBondMethod = null;
try {
createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
} catch (NoSuchMethodException e) {
e.printStackTrace();
Log.d(TAG, "createBond: XXXX");
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.d(TAG, "createBond: XXXX1");
} catch (InvocationTargetException e) {
Log.d(TAG, "createBond: XXXX2");
e.printStackTrace();
}
}
/**
* 注册输入设备的服务
*/
private void initHidService() {
mBluetoothAdapter.getProfileProxy(context, connect, getInputDeviceHiddenConstant());
}
//判断蓝牙是否已经
public boolean isHasConnected(BluetoothDevice device) {
if (mHidService != null) {
BluetoothProfile proxy = mHidService.getProxy();
int connectionState = proxy.getConnectionState(device);
if (connectionState == BluetoothProfile.STATE_CONNECTED) {
return true;
}
}
return false;
}
}