这次实际项目中要求了手机终端和低功耗蓝牙即蓝牙4.0通讯的功能,所以这次我也就把我自己的Android代码同大家分享,稍后考虑将框架整理后上传Github供大家交流学习。
1.蓝牙初始化
//初始化蓝牙设备
private void init_ble() {
// 手机硬件支持蓝牙
if (!getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "不支持BLE", Toast.LENGTH_SHORT).show();
}
// Initializes Bluetooth adapter.
// 获取手机本地的蓝牙适配器
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// 打开蓝牙权限
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
首先判断手机硬件是否支持低功耗蓝牙,如果支持那么获取手机的蓝牙适配器,接着判断蓝牙权限是否已经开启,如果未开启则去申请。
在这里大家也可以重写onActivityResult方法来对蓝牙开启成功后进行一个提示,这里我就没有写了。
2.简单蓝牙Fragment的实现
Fragment界面
在这里我们单独使用一个Fragment来进行蓝牙功能的演示,界面如下:
具体布局很简单,主要就是几个扫描和断开连接,下面三个按钮与此功能无关,是发送命令的,中间的listview显示可以连接的设备。
好了,下面我们将重点讲解具体的程序流程。
功能控件的定义
包括以下几个:
//扫描蓝牙按钮
private Button btnScan;
//取消蓝牙连接按钮
private Button btnDiscoonect;
//蓝牙适配器
BluetoothAdapter mBluetoothAdapter;
// 蓝牙信号强度
private ArrayList<Integer> rssis;
// 自定义Adapter
LeDeviceListAdapter mleDeviceListAdapter;
//蓝牙连接状态
private boolean mConnected = false;
private String status = "disconnected";
//蓝牙特征值
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private static BluetoothGattCharacteristic target_chara = null;
//蓝牙设备的list
private ListView lvDevice;
// 描述扫描蓝牙的状态
private boolean mScanning;
private boolean scan_flag;
//设备信息
public String deviceName;
public String deviceAddress;
public String deviceRssi;
// 蓝牙扫描时间
private static final long SCAN_PERIOD = 10000;
扫描蓝牙设备
case R.id.btn_scan_dev:
if (scan_flag) {
boolean gps_able = false;
mleDeviceListAdapter = new LeDeviceListAdapter();
lvDevice.setAdapter(mleDeviceListAdapter);
gps_able = isGpsEnable(getActivity());
if (gps_able == true) {
scanLeDevice(true);
} else {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
int requestCode = 1;
this.startActivityForResult(intent, requestCode);
}
} else {
scanLeDevice(false);
btnScan.setText("Scan Device");
}
break;
注意:大家可能会对其中对于GPS的操作感到疑惑,但是在Android6.0之后的系统中,想要扫描到蓝牙必须动态添加位置权限。
首先判断当前是否已经扫描,初始flag为true,然后初始化listview的适配器并检查当前位置权限有没有开启,如果开启了则开始扫描。
private void scanLeDevice(final boolean enable) {
if (enable) {
/* 开始扫描蓝牙设备,带mLeScanCallback 回调函数 */
Log.i("SCAN", "begin.....................");
mScanning = true;
scan_flag = false;
btnScan.setText("Stop Scanning");
mBluetoothAdapter.startLeScan(mLeScanCallback);
//TODO:版本
/*if(android.os.Build.VERSION.SDK_INT<21)
bluetoothAdapter.startLeScan(this);
else{
bluetoothLeScanner.startScan(callBack);
}*/
} else {
Log.i("Stop", "stoping................");
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
scan_flag = true;
}
}
核心还是调用了蓝牙适配器的startLeScan方法或者StartScan方法,这个看你的API版本了,下面我们需要重写我们的LeScanCallback函数,用来扫描到的蓝牙信息并添加到我们的listview中去。
/**
* 蓝牙扫描回调函数 实现扫描蓝牙设备,回调蓝牙BluetoothDevice,可以获取name MAC等信息
**/
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
byte[] scanRecord) {
// TODO Auto-generated method stub
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
/* 讲扫描到设备的信息输出到listview的适配器 */
mleDeviceListAdapter.addDevice(device, rssi);
mleDeviceListAdapter.notifyDataSetChanged();
}
});
System.out.println("Address:" + device.getAddress());
System.out.println("Name:" + device.getName());
System.out.println(&