Monday, June 6, 2016

Bluetooth LE Gatt Example, step-by-step

Last post demonstrate the Android Bluetooth Le Gatt example code with Arduino/Genuino 101. This post start to (TRY to) implement my own Bluetooth LE Gatt Example, step-by-step. The aim of the examples (in coming series) are scan BLE device, find and link with specified device Genuino 101 (programmed with "LEDCB", refer previous post), and read and write characteristic of the device to turn ON/OFF the Genuino 101 on-board LED.

The main reference material are:
- Android Developers Guide > Bluetooth Low Energy
- The Android example code - BluetoothLeGatt. (The example in last post)

In this first step, create a new project in Android Studio, named AndroidBleGatt.

In my example (in coming post) I will scan LE device using BluetoothLeScanner (Added in API level 21) instead of calling deprecated startLeScan() and stopLeScan() methods as in the BluetoothLeGatt example, so specify the Min Sdk Version of API 21.

Edit AndroidManifest.xml to add uses-feature of "android.hardware.bluetooth_le", uses-permission of "android.permission.BLUETOOTH", "android.permission.BLUETOOTH_ADMIN" and "android.permission.ACCESS_COARSE_LOCATION".

AndroidManifest.xml
<?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>
    </application>

</manifest>

Edit MainActivity.java
package com.blogspot.android_er.androidblegatt;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothLeScanner mBluetoothLeScanner;

    private boolean mScanning;

    private static final int RQS_ENABLE_BLUETOOTH = 1;

    @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 not supported in 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;
        }

    }

    @Override
    protected void onResume() {
        super.onResume();

        if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new 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);
    }

    private void getBluetoothAdapterAndLeScanner(){
        // Get BluetoothAdapter and BluetoothLeScanner.
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

        mScanning = false;
    }
}



Up to here, the app simple check Bluetooth LE available and enable it. In next post, I will show how to scan available Bluetooth LE devices in range.

Next:
Bluetooth LE Gatt Example, scan BLE devices
Scan specified BLE devices with ScanFilter
Connect to Bluetooth LE device and display GATT Services



2 comments:

Unknown said...

For me the code somehow doesn't work (tested on 3 different devices). It just doesnt list any devices, although other ble scanner apps from play store do. I used another phone with a peripheral simulator app as ble peripheral (I didnt copy the ScanFilter part). The same problem has also occured when using other example codes. Does someone know what the problem could be?

Unknown said...

same problem iam facing in my app also please can any one help me in this