Bluetooth Le Event – Connect To Bluetooth Le Device As Well As Display Gatt Services

Posted on

Last shipping service of Bluetooth LE representative exhibit how to “Scan specified BLE devices amongst ScanFilter“. This shipping service exhibit how to connect to the device together with display the supported service past times the device.


Modify from in conclusion “Scan specified BLE devices amongst ScanFilter“. Basically this role re-create from “example code of Bluetooth Le Gatt”, refer to “Bluetooth Le Gatt representative to link amongst Arduino/Genuino 101“.

Create a novel activity ControlActivity.java

package com.blogspot.android_er.androidblegatt;  import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattService; 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.os.Bundle; import android.os.IBinder; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.ExpandableListView; import android.widget.SimpleExpandableListAdapter; import android.widget.TextView;  import java.util.ArrayList; import java.util.HashMap; import java.util.List;  world course of written report ControlActivity extends AppCompatActivity {      someone concluding static String TAG = ControlActivity.class.getSimpleName();      world static concluding String EXTRAS_DEVICE_NAME = "DEVICE_NAME";     world static concluding String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";      someone String mDeviceName;     someone String mDeviceAddress;      someone boolean mConnected = false;     someone BluetoothGattCharacteristic mNotifyCharacteristic;     someone BluetoothLeService mBluetoothLeService;      TextView textViewState;     someone ExpandableListView mGattServicesList;      someone concluding String LIST_NAME = "NAME";     someone concluding String LIST_UUID = "UUID";      someone ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =             novel ArrayList<ArrayList<BluetoothGattCharacteristic>>();      // Code to grapple Service lifecycle.     someone concluding ServiceConnection mServiceConnection = novel ServiceConnection() {          @Override         world void onServiceConnected(ComponentName componentName, IBinder service) {             mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();             if (!mBluetoothLeService.initialize()) {                 Log.e(TAG, "Unable to initialize Bluetooth");                 finish();             }             // Automatically connects to the device upon successful start-up initialization.             mBluetoothLeService.connect(mDeviceAddress);         }          @Override         world void onServiceDisconnected(ComponentName componentName) {             mBluetoothLeService = null;         }     };      // Handles diverse events fired past times the Service.     // ACTION_GATT_CONNECTED: connected to a GATT server.     // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.     // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.     // ACTION_DATA_AVAILABLE: received information from the device.  This tin lav hold upwards a number of read     //                        or notification operations.     someone concluding BroadcastReceiver mGattUpdateReceiver = novel BroadcastReceiver() {         @Override         world void onReceive(Context context, Intent intent) {             concluding String activity = intent.getAction();             if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {                 mConnected = true;                 updateConnectionState("GATT_CONNECTED");             } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {                 mConnected = false;                 updateConnectionState("GATT_DISCONNECTED");                 clearUI();             } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {                 // Show all the supported services together with characteristics on the user interface.                 displayGattServices(mBluetoothLeService.getSupportedGattServices());             } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {                 displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));              }         }     };      someone void clearUI() {         mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);     }      someone void updateConnectionState(final String st) {         runOnUiThread(new Runnable() {             @Override             world void run() {                 textViewState.setText(st);             }         });     }      someone void displayData(String data) {         if (data != null) {             textViewState.setText(data);         }     }      // Demonstrates how to iterate through the supported GATT Services/Characteristics.     // In this sample, nosotros populate the information construction that is jump to the ExpandableListView     // on the UI.     someone void displayGattServices(List<BluetoothGattService> gattServices) {          if (gattServices == null) return;         String uuid = null;         String unknownServiceString = "Unknown Service";         String unknownCharaString = "Unknown Characteristic";         ArrayList<HashMap<String, String>> gattServiceData =                 novel ArrayList<HashMap<String, String>>();         ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData                 = novel ArrayList<ArrayList<HashMap<String, String>>>();         mGattCharacteristics = novel ArrayList<ArrayList<BluetoothGattCharacteristic>>();          // Loops through available GATT Services.         for (BluetoothGattService gattService : gattServices) {             HashMap<String, String> currentServiceData = novel HashMap<String, String>();             uuid = gattService.getUuid().toString();             currentServiceData.put(                     LIST_NAME, lookup(uuid, unknownServiceString));             currentServiceData.put(LIST_UUID, uuid);             gattServiceData.add(currentServiceData);              ArrayList<HashMap<String, String>> gattCharacteristicGroupData =                     novel ArrayList<HashMap<String, String>>();             List<BluetoothGattCharacteristic> gattCharacteristics =                     gattService.getCharacteristics();             ArrayList<BluetoothGattCharacteristic> charas =                     novel ArrayList<BluetoothGattCharacteristic>();              // Loops through available Characteristics.             for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {                 charas.add(gattCharacteristic);                 HashMap<String, String> currentCharaData = novel HashMap<String, String>();                 uuid = gattCharacteristic.getUuid().toString();                 currentCharaData.put(                         LIST_NAME, lookup(uuid, unknownCharaString));                 currentCharaData.put(LIST_UUID, uuid);                 gattCharacteristicGroupData.add(currentCharaData);              }             mGattCharacteristics.add(charas);             gattCharacteristicData.add(gattCharacteristicGroupData);         }          SimpleExpandableListAdapter gattServiceAdapter = novel SimpleExpandableListAdapter(                 this,                 gattServiceData,                 android.R.layout.simple_expandable_list_item_2,                 novel String[] {LIST_NAME, LIST_UUID},                 novel int[] { android.R.id.text1, android.R.id.text2 },                 gattCharacteristicData,                 android.R.layout.simple_expandable_list_item_2,                 novel String[] {LIST_NAME, LIST_UUID},                 novel int[] { android.R.id.text1, android.R.id.text2 }         );         mGattServicesList.setAdapter(gattServiceAdapter);     }      // If a given GATT characteristic is selected, cheque for supported features.  This sample     // demonstrates 'Read' together with 'Notify' features.  See     // http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the consummate     // listing of supported characteristic features.     someone concluding ExpandableListView.OnChildClickListener servicesListClickListner =             novel ExpandableListView.OnChildClickListener() {                 @Override                 world boolean onChildClick(ExpandableListView parent, View v, int groupPosition,                                             int childPosition, long id) {                     if (mGattCharacteristics != null) {                         concluding BluetoothGattCharacteristic characteristic =                                 mGattCharacteristics.get(groupPosition).get(childPosition);                         concluding int charaProp = characteristic.getProperties();                         if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {                             // If at that topographic point is an active notification on a characteristic, clear                             // it commencement together with thus it doesn't update the information plain on the user interface.                             if (mNotifyCharacteristic != null) {                                 mBluetoothLeService.setCharacteristicNotification(                                         mNotifyCharacteristic, false);                                 mNotifyCharacteristic = null;                             }                             mBluetoothLeService.readCharacteristic(characteristic);                         }                         if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {                             mNotifyCharacteristic = characteristic;                             mBluetoothLeService.setCharacteristicNotification(                                     characteristic, true);                         }                         furnish true;                     }                     furnish false;                 }             };      @Override     protected void onCreate(@Nullable Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_control);          concluding Intent intent = getIntent();         mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);         mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);          TextView textViewDeviceName = (TextView)findViewById(R.id.textDeviceName);         TextView textViewDeviceAddr = (TextView)findViewById(R.id.textDeviceAddress);         textViewState = (TextView)findViewById(R.id.textState);          textViewDeviceName.setText(mDeviceName);         textViewDeviceAddr.setText(mDeviceAddress);          mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);         mGattServicesList.setOnChildClickListener(servicesListClickListner);          Intent gattServiceIntent = novel Intent(this, BluetoothLeService.class);         bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);     }      @Override     protected void onResume() {         super.onResume();         registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());         if (mBluetoothLeService != null) {             concluding boolean number = mBluetoothLeService.connect(mDeviceAddress);             Log.d(TAG, "Connect asking result=" + result);         }     }      @Override     protected void onPause() {         super.onPause();         unregisterReceiver(mGattUpdateReceiver);     }      @Override     protected void onDestroy() {         super.onDestroy();         unbindService(mServiceConnection);         mBluetoothLeService = null;     }      someone static IntentFilter makeGattUpdateIntentFilter() {         concluding IntentFilter intentFilter = novel IntentFilter();         intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);         intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);         intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);         intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);         furnish intentFilter;     }      someone static HashMap<String, String> attributes = novel HashMap();      world static String lookup(String uuid, String defaultName) {         String advert = attributes.get(uuid);         furnish advert == null ? defaultName : name;     } }  

And associated layout, activity_control.xml.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:padding="16dp"     android:orientation="vertical"     tools:context="com.blogspot.android_er.androidblegatt.ControlActivity">      <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="Hello World!" />      <TextView         android:id="@+id/textDeviceName"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:textSize="20dp"         android:textStyle="bold"/>     <TextView         android:id="@+id/textDeviceAddress"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:textSize="20dp"         android:textStyle="bold" />     <TextView         android:id="@+id/textState"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:textSize="20dp"         android:textStyle="bold" />     <ExpandableListView android:id="@+id/gatt_services_list"         android:layout_width="match_parent"         android:layout_height="wrap_content"/> </LinearLayout>  

Modify MainActivity.java to add together a push clit to start ControlActivity.

package com.blogspot.android_er.androidblegatt;  import android.app.Activity; import android.app.AlertDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.le.BluetoothLeScanner; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.Toast;  import java.util.ArrayList; import java.util.List;  world course of written report MainActivity extends AppCompatActivity {      someone BluetoothAdapter mBluetoothAdapter;     someone BluetoothLeScanner mBluetoothLeScanner;      someone boolean mScanning;      someone static concluding int RQS_ENABLE_BLUETOOTH = 1;      Button btnScan;     ListView listViewLE;      List<BluetoothDevice> listBluetoothDevice;     ListAdapter adapterLeScanResult;      someone Handler mHandler;     someone static concluding long SCAN_PERIOD = 10000;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          // Check if BLE is supported on the device.         if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {             Toast.makeText(this,                     "BLUETOOTH_LE non supported inward this device!",                     Toast.LENGTH_SHORT).show();             finish();         }          getBluetoothAdapterAndLeScanner();          // Checks if Bluetooth is supported on the device.         if (mBluetoothAdapter == null) {             Toast.makeText(this,                     "bluetoothManager.getAdapter()==null",                     Toast.LENGTH_SHORT).show();             finish();             return;         }          btnScan = (Button)findViewById(R.id.scan);         btnScan.setOnClickListener(new View.OnClickListener() {             @Override             world void onClick(View v) {                 scanLeDevice(true);             }         });         listViewLE = (ListView)findViewById(R.id.lelist);          listBluetoothDevice = novel ArrayList<>();         adapterLeScanResult = novel ArrayAdapter<BluetoothDevice>(                 this, android.R.layout.simple_list_item_1, listBluetoothDevice);         listViewLE.setAdapter(adapterLeScanResult);         listViewLE.setOnItemClickListener(scanResultOnItemClickListener);          mHandler = novel Handler();      }      AdapterView.OnItemClickListener scanResultOnItemClickListener =             novel AdapterView.OnItemClickListener(){                  @Override                 world void onItemClick(AdapterView<?> parent, View view, int position, long id) {                     concluding BluetoothDevice device =                             (BluetoothDevice) parent.getItemAtPosition(position);                      String msg = device.getAddress() + "\n"                             + device.getBluetoothClass().toString() + "\n"                             + getBTDevieType(device);                      novel AlertDialog.Builder(MainActivity.this)                             .setTitle(device.getName())                             .setMessage(msg)                             .setPositiveButton("OK", novel DialogInterface.OnClickListener() {                                 @Override                                 world void onClick(DialogInterface dialog, int which) {                                  }                             })                             .setNeutralButton("CONNECT", novel DialogInterface.OnClickListener() {                                 @Override                                 world void onClick(DialogInterface dialog, int which) {                                     concluding Intent intent = novel Intent(MainActivity.this,                                             ControlActivity.class);                                     intent.putExtra(ControlActivity.EXTRAS_DEVICE_NAME,                                             device.getName());                                     intent.putExtra(ControlActivity.EXTRAS_DEVICE_ADDRESS,                                             device.getAddress());                                      if (mScanning) {                                         mBluetoothLeScanner.stopScan(scanCallback);                                         mScanning = false;                                         btnScan.setEnabled(true);                                     }                                     startActivity(intent);                                 }                             })                             .show();                  }             };      someone String getBTDevieType(BluetoothDevice d){         String type = "";          switch (d.getType()){             instance BluetoothDevice.DEVICE_TYPE_CLASSIC:                 type = "DEVICE_TYPE_CLASSIC";                 break;             instance BluetoothDevice.DEVICE_TYPE_DUAL:                 type = "DEVICE_TYPE_DUAL";                 break;             instance BluetoothDevice.DEVICE_TYPE_LE:                 type = "DEVICE_TYPE_LE";                 break;             instance BluetoothDevice.DEVICE_TYPE_UNKNOWN:                 type = "DEVICE_TYPE_UNKNOWN";                 break;             default:                 type = "unknown...";         }          furnish type;     }      @Override     protected void onResume() {         super.onResume();          if (!mBluetoothAdapter.isEnabled()) {             if (!mBluetoothAdapter.isEnabled()) {                 Intent enableBtIntent = novel Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);                 startActivityForResult(enableBtIntent, RQS_ENABLE_BLUETOOTH);             }         }     }      @Override     protected void onActivityResult(int requestCode, int resultCode, Intent data) {          if (requestCode == RQS_ENABLE_BLUETOOTH && resultCode == Activity.RESULT_CANCELED) {             finish();             return;         }          getBluetoothAdapterAndLeScanner();          // Checks if Bluetooth is supported on the device.         if (mBluetoothAdapter == null) {             Toast.makeText(this,                     "bluetoothManager.getAdapter()==null",                     Toast.LENGTH_SHORT).show();             finish();             return;         }          super.onActivityResult(requestCode, resultCode, data);     }      someone void getBluetoothAdapterAndLeScanner(){         // Get BluetoothAdapter together with BluetoothLeScanner.         concluding BluetoothManager bluetoothManager =                 (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);         mBluetoothAdapter = bluetoothManager.getAdapter();         mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();          mScanning = false;     }      /*     to telephone telephone startScan (ScanCallback callback),     Requires BLUETOOTH_ADMIN permission.     Must concur ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to teach results.      */     someone void scanLeDevice(final boolean enable) {         if (enable) {             listBluetoothDevice.clear();             listViewLE.invalidateViews();              // Stops scanning later on a pre-defined scan period.             mHandler.postDelayed(new Runnable() {                 @Override                 world void run() {                     mBluetoothLeScanner.stopScan(scanCallback);                     listViewLE.invalidateViews();                      Toast.makeText(MainActivity.this,                             "Scan timeout",                             Toast.LENGTH_LONG).show();                      mScanning = false;                     btnScan.setEnabled(true);                 }             }, SCAN_PERIOD);              //mBluetoothLeScanner.startScan(scanCallback);              //scan specified devices entirely amongst ScanFilter             ScanFilter scanFilter =                     novel ScanFilter.Builder()                             .setServiceUuid(BluetoothLeService.ParcelUuid_GENUINO101_ledService)                             .build();             List<ScanFilter> scanFilters = novel ArrayList<ScanFilter>();             scanFilters.add(scanFilter);              ScanSettings scanSettings =                     novel ScanSettings.Builder().build();              mBluetoothLeScanner.startScan(scanFilters, scanSettings, scanCallback);              mScanning = true;             btnScan.setEnabled(false);         } else {             mBluetoothLeScanner.stopScan(scanCallback);             mScanning = false;             btnScan.setEnabled(true);         }     }      someone ScanCallback scanCallback = novel ScanCallback() {         @Override         world void onScanResult(int callbackType, ScanResult result) {             super.onScanResult(callbackType, result);              addBluetoothDevice(result.getDevice());         }          @Override         world void onBatchScanResults(List<ScanResult> results) {             super.onBatchScanResults(results);             for(ScanResult number : results){                 addBluetoothDevice(result.getDevice());             }         }          @Override         world void onScanFailed(int errorCode) {             super.onScanFailed(errorCode);             Toast.makeText(MainActivity.this,                     "onScanFailed: " + String.valueOf(errorCode),                     Toast.LENGTH_LONG).show();         }          someone void addBluetoothDevice(BluetoothDevice device){             if(!listBluetoothDevice.contains(device)){                 listBluetoothDevice.add(device);                 listViewLE.invalidateViews();             }         }     }; }  

Modify AndroidManifest.xml to add activity of “.ControlActivity”.

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="com.blogspot.android_er.androidblegatt">      <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>     <uses-permission android:name="android.permission.BLUETOOTH"/>     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>      <application         android:allowBackup="true"         android:icon="@mipmap/ic_launcher"         android:label="@string/app_name"         android:supportsRtl="true"         android:theme="@style/AppTheme">         <activity android:name=".MainActivity">             <intent-filter>                 <action android:name="android.intent.action.MAIN" />                  <category android:name="android.intent.category.LAUNCHER" />             </intent-filter>         </activity>         <activity android:name=".ControlActivity"/>         <service android:name=".BluetoothLeService" android:enabled="true"/>     </application>  </manifest> 

Bluetooth LE Gatt Example, step-by-step