《Android BLE 开发》--初学者

    本作者是一位安卓初学者,从事嵌入式开发岗位,由于工作需要开发一个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)
    {

    }

}

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rice嵌入式开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值