本作者是一位安卓初学者,从事嵌入式开发岗位,由于工作需要开发一个BLE debug工具,所以开始了我的第一个安卓程序《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);
}
说道这里基本把所有要实现的功能函数都说完了。
具体实现代码:
AndroidManifest.xml的代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.harrychen.bletool" >
<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"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Spinner
android:id="@+id/BLE_List_Spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
/>
<Button
android:id="@+id/BLE_Connect_Button"
android:text="BLE CONNECT"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/BLE_List_Spinner"
android:textColor="#0000EE"
android:textSize="15dp"
/>
<TextView
android:id="@+id/BLE_Log_Text"
android:text="BLE Log:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/BLE_Connect_Button"
/>
<EditText
android:id="@+id/BLE_Log_Edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/BLE_Log_Text"
android:hint="BLE Log Show"
android:inputType="textMultiLine"
android:gravity="left|top"
android:maxLines="15"
android:focusable="false"
android:scrollbars="vertical"
/>
<Button
android:id="@+id/Log_Clear_Button"
android:text="CLEAR LOG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/BLE_Log_Edit"
android:textColor="#0000EE"
android:textSize="15dp"
/>
<Button
android:id="@+id/Read_Button"
android:text="READ"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/Log_Clear_Button"
android:layout_alignLeft="@+id/Log_Clear_Button"
android:textColor="#0000EE"
android:textSize="15dp"
/>
<Button
android:id="@+id/Write_Button"
android:text="WRITE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/Log_Clear_Button"
android:layout_alignRight="@+id/Log_Clear_Button"
android:textColor="#0000EE"
android:textSize="15dp"
/>
<Button
android:id="@+id/Notify_Button"
android:text="NOTIFY"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/Read_Button"
android:textColor="#0000EE"
android:textSize="15dp"
/>
</RelativeLayout>
MainActivity.java
package com.example.harrychen.bletool;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
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.content.pm.PackageManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MainActivity extends Activity implements AdapterView.OnItemSelectedListener{
private final static String TAG = MainActivity.class.getSimpleName();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothGattCharacteristic mBluetoothtCharacteristic;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
private Handler mHandler =new Handler();
private boolean mScanning;
private static final long SCAN_PERIOD = 5000;
List<BluetoothGattService> supportedGattServices;
List<BluetoothGattCharacteristic> gattCharacteristics;
private List<String> mBLENameList = new ArrayList<String>();
private ArrayAdapter<String> ListAdapter;
private List<BluetoothDevice> mSearchBluetoothList = new ArrayList<>();
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
public final static String ACTION_GATT_CONNECTED = "com.charon.www.NewBluetooth.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED = "com.charon.www.NewBluetooth.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.charon.www.NewBluetooth.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE = "com.charon.www.NewBluetooth.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA = "com.charon.www.NewBluetooth.EXTRA_DATA";
public final static String DEVICE_TWO_ADDRESS = "com.example.bluetooth.le.DEVICE_TWO_ADDRESS";
public final static String ACTION_GATT_WRITE= "com.example.bluetooth.le.ACTION_GATT_WRITE";
public List<UUID> writeUuid = new ArrayList<>();
public List<UUID> readUuid =new ArrayList<>();
public List<UUID> notifyUuid =new ArrayList<>();
private Spinner BLE_List_Spinner;
private Button BLE_Connect_Button;
private Button Log_Clear_Button;
private Button Read_Button;
private Button Write_Button;
private Button Notify_Button;
private EditText BLE_Log_Edit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BLE_List_Spinner = (Spinner)findViewById(R.id.BLE_List_Spinner);
BLE_Connect_Button = (Button)findViewById(R.id.BLE_Connect_Button);
Log_Clear_Button = (Button)findViewById(R.id.Log_Clear_Button);
Read_Button = (Button)findViewById(R.id.Read_Button);
Write_Button = (Button)findViewById(R.id.Write_Button);
Notify_Button = (Button)findViewById(R.id.Notify_Button);
BLE_Log_Edit = (EditText)findViewById(R.id.BLE_Log_Edit);
initialize();
scanLeDevice(true);
setBLEName2Spanner();
BLE_Connect_Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (BLE_Connect_Button.getText().equals("BLE DISCONNECT")) {
BLE_Connect_Button.setText("BLE CONNECT");
disconnect();
close();
} else if (BLE_Connect_Button.getText().equals("BLE CONNECT")) {
BLE_Connect_Button.setText("BLE DISCONNECT");
connect(mBluetoothDeviceAddress);
}
}
});
Log_Clear_Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BLE_Log_Edit.setText("");
}
});
Read_Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for(BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
if(gattCharacteristic.getUuid().toString().equals("00000000-0000-0061-6180-00030006ff08")) {
mBluetoothtCharacteristic = gattCharacteristic;
}
}
readCharacteristic(mBluetoothtCharacteristic);
}
});
Write_Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
if (gattCharacteristic.getUuid().toString().equals("00000000-0000-0061-6180-00030006ff08")) {
mBluetoothtCharacteristic = gattCharacteristic;
}
}
byte[] value = new byte[10];
value[0] = 0x02;
mBluetoothtCharacteristic.setValue(value);
writeCharacteristic(mBluetoothtCharacteristic);
}
});
Notify_Button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for(BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
if(gattCharacteristic.getUuid().toString().equals("44fa50b2-d0a3-472e-a939-d80cf17638bb")) {
mBluetoothtCharacteristic = gattCharacteristic;
Log.w("Notify",gattCharacteristic.getUuid().toString());
}
}
setCharacteristicNotification(mBluetoothtCharacteristic, true);
}
});
}
@Override
protected void onResume(){
super.onResume();
registerReceiver(mGattUpdateReceiver,makeGattUpdateIntentFilter());
}
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;
}
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);
}
public class LocalBinder extends Binder {
public MainActivity getService() {
return MainActivity.this;
}
}
public boolean onUnbind(Intent intent) {
close();
return onUnbind(intent);
}
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
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;
}
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return false;
}
return mBluetoothGatt.writeCharacteristic(characteristic);
}
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);
}
}
}
}
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
public List<BluetoothGattService> getSupportedGattServices() {
if (mBluetoothGatt == null) return null;
return mBluetoothGatt.getServices();
}
public BluetoothGattService getSupportedGattServices(UUID uuid) {
BluetoothGattService mBluetoothGattService;
if (mBluetoothGatt == null) return null;
mBluetoothGattService = mBluetoothGatt.getService(uuid);
return mBluetoothGattService;
}
//--------------------------------------Scan BLE----------------------------------
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());
}
}
}
});
}
};
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(ACTION_DATA_AVAILABLE.equals(action)) {
String data = intent.getStringExtra(EXTRA_DATA);
BLE_Log_Edit.setText("aaaa"+data);
//System.out.println("Receiver..."+data);
}
}
};
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_GATT_CONNECTED);
intentFilter.addAction(ACTION_GATT_DISCONNECTED);
intentFilter.addAction(ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(ACTION_DATA_AVAILABLE);
return intentFilter;
}
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);
}
@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)
{
}
}
作者作为安卓初学者,因工作需要开发BLE debug工具《BLE Tool》。介绍了开发前需了解BLE通信原理,详细阐述了开启权限、初始化BLE、扫描设备、连接与断开设备、读写特征等功能的实现步骤,还提及了具体实现代码所在文件。
1万+

被折叠的 条评论
为什么被折叠?



