本作者是一位安卓初学者,之前学过JAVA,安卓只学过三天。《BLE Tool》也是我一个安卓项目,因为作者学习安卓加开发只用了10天时间,目前只是把所有接口打通了,只提供如何怎么实现。有不对的地方,大家多指点。开发之前,最好了解一下BLE的通信原理。最终实现的界面:
1.开启权限
在AndroidManifest.xml中添加一下代码:
<uses-feature android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="andriod.permission.ACCESS_FINE_LOCATION"/>
2.初始化BLE
第一步:判断设备是否支持BLE功能
第二步:通过蓝牙管理器获取蓝牙适配器
第三步:判断设备是否打开蓝牙
在MainActivity.java中添加以下代码:
public boolean initialize() {
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
Log.e(TAG, "No support BLE.");
finish();
}
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e(TAG, "Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
if(!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
return true;
}
3.扫描设备实现
本作者时间扫描设备添加到Spanner控件中,在MainActivity.java中添加以下代码:
第一步:编写扫描函数
第二步:添加扫描回调函数
private void scanLeDevice(final boolean enable) {
if(enable) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
},SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (device.getName() != null) {
if (!mSearchBluetoothList.contains(device)) {
mSearchBluetoothList.add(device);
mBLENameList.add(device.getName());
}
}
}
});
}
};
4.将扫描到的设备添加到Spanner控件中
在MainActivity.java中添加以下代码:
private void setBLEName2Spanner(){
BLE_List_Spinner.setOnItemSelectedListener(this);
mBLENameList.add("<BLE List>");
ListAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,mBLENameList);
ListAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
BLE_List_Spinner.setAdapter(ListAdapter);
}
5.连接设备
在Spanner控件中选择要连接的设备,Spanner的选择事件实现,在MainActivity.java中添加以下代码:
@Override
public void onItemSelected(AdapterView<?> parent,View view,int position,long id)
{
disconnect();
close();
String item = parent.getSelectedItem().toString();
if(item != "<BLE List>") {
for(BluetoothDevice device : mSearchBluetoothList) {
if(device.getName().equals(item)) {
if(connect(device.getAddress()) == true) {
BLE_Connect_Button.setText("BLE DISCONNECT");
}
}
}
}
}
public void onNothingSelected(AdapterView<?> arg0)
{
}
连接函数的实现,在MainActivity.java中添加以下代码:
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
System.out.println("device.getBondState==" + device.getBondState());
return true;
}
6.断开连接
断开连接函数的实现,在MainActivity.java中添加以下代码:
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
7.读特征实现
读特征函数的实现,在MainActivity.java中添加以下代码:
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
8.写特征实现
写特征函数的实现,在MainActivity.java中添加以下代码:
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return false;
}
return mBluetoothGatt.writeCharacteristic(characteristic);
}
9.设置特征的通知的实现
特征通知函数的实现,在MainActivity.java中添加以下代码:
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
boolean isEnableNotification = mBluetoothGatt.setCharacteristicNotification(characteristic,enabled);
if(isEnableNotification) {
List<BluetoothGattDescriptor>descriptorList = characteristic.getDescriptors();
if(descriptorList != null && descriptorList.size() >0) {
for(BluetoothGattDescriptor descriptor : descriptorList) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
}
}
10.关闭BLE实现
关闭函数的实现,在MainActivity.java中添加以下代码:
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
11.功能的回调函数的实现
从第5点到第10的最终事项都需要调用回调函数,回调函数的实现,在MainActivity.java中添加以下代码:
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
gatt.discoverServices();
broadcastUpdate(intentAction);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
supportedGattServices = gatt.getServices();
for (BluetoothGattService gattService : supportedGattServices) {
if(gattService.getUuid().toString().equals("0000fe8f-0000-1000-8000-00805f9b34fb")) {
gattCharacteristics = gattService.getCharacteristics();
for(BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
if(gattCharacteristic.getUuid().toString().equals("44fa50b2-d0a3-472e-a939-d80cf17638bb")) {
Log.e("BLE Tool", "Log Link Success");
//Log.e("BLE Tool", gattCharacteristic.getUuid().toString());
}
}
}
}
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
}
else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
Log.e("BLE Tool", "Characteristic Read");
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
Log.e("BLE Tool", "Characteristic Notify");
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_WRITE);
Log.e("BLE Tool", "Characteristic Write");
}
}
};
private void broadcastUpdate(final String action){
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
final byte[] data = characteristic.getValue();
for(int i =0; i<data.length; i++) {
System.out.println("data..."+data[i]);
}
sendBroadcast(intent);
}
说道这里基本把所有要实现的功能函数都说完了。
本文分享自 Rice 嵌入式开发技术分享 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!