Using the ZentriOS BLE Android Library
The ZentriOS BLE Android Library is a Java library for developing Android apps that interact with ZentriOS BLE running on an AMS00x module. Using the ZentriOS BLE Android Library you can connect to the ZentriOS BLE module, switch it to remote COMMAND mode and issue ZentriOS BLE commands to it. See Serial Interface for a description of remote COMMAND mode.
This application note describes the ZentriOS BLE Android Library and the demonstration app. To illustrate how the library works, it describes some simple modifications to the demonstration app.
Prerequisites
The demonstration app requires a BLE-capable Android test device, such as a smart phone or tablet, and a Wahoo evaluation board, containing an AMS00x Bobcat module running ZentriOS BLE.
This application note assumes some familiarity and experience with:
- Java
- mobile development
- event driven application development
- the Android SDK
- an IDE such as Android Studio.
See http://developer.android.com/ for detailed documentation of Android development.
Set Up
Obtain a copy of the ZentriOS BLEAndroid Library from https://github.com/zentri/ble_command_android_demo
Obtain the Android SDK and Android Studio from https://developer.android.com/sdk/index.html.
Open Android Studio and import the ZentriOS BLE Android project, at the top level of the ZentriOS BLE Android Library working copy.
Switch on USB debugging mode for your Android test device and connect it to the computer running Android Studio.
With the factory settings, the ZentriOS BLE module begins to advertise immediately on applying power. Advertising stops after a few minutes. Press the Reset button to start advertising again.
Alternatively, to make the ZentriOS BLE module advertise forever, open a ZentriOS terminal to the module and set bl v h d : advertising high duration to 0
:
set bl v h d 0
Structure of the ZentriOS BLE Android Library
The ZentriOS BLEAndroid Project contains the truconnectandroid package, and the demonstration app package.
The truconnectandroid package contains the following packages:
- BLE - enums and classes for handling BLE commands and connections
- test
- truconnect - enums and classes for handling ZentriOS BLE commands and responses.
The central class of the truconnect package is the ZentriOS BLEManager class. This contains methods corresponding to all ZentriOS BLE commands and variables. It also contains methods for handling scanning and connection from the Android device, and for sending commands and receiving command results, via the ZentriOS BLEHandler class.
Building and Running the Demo App
In Android Studio:
- Select the app package.
- Click the Run App button.
- Android Studio builds the demo app, uploads it to your test device and runs it.
With the Wahoo board:
- Power up, or press reset to start advertising.
The demo app has two activities, corresponding to two display windows:
![]() | ![]() | ![]() | ![]() |
MainActivity | DeviceInfoActivity Command Mode | DeviceInfoActivity Stream Mode | DeviceInfoActivity Data Received |
On startup, the MainActivity display shows.
On your test device:
- Tap the Scan button. The demo app scans, detects the ZentriOS BLE module and displays its ID.
- Tap the ZentriOS BLE module ID in the scan list. The demo app switches to the DeviceInfoActivity display and displays some information from the sensors and buttons on the Wahoo board, connected to ZentriOS BLE module GPIOs.
- The
ADC
field displays the GPIO 9 value, corresponding to the Wahoo thermistor. - The
GPIO
field displays the value of GPIO 12, corresponding to Wahoo Button 2. - The
LED ON/OFF
button controls GPIO 14, the red LED in the Wahoo tricolor LED. The button indicator is lit when the LED is on.
- The
- Tap the
Read Values
button. This sends commands to the Wahoo board, obtains the command results and refreshes the data displayed in the fields.- The ADC value may change. If you place a finger on the Wahoo thermistor (circled) the value may decrease as the thermistor heats.
- If you update while pressing Button 2 on the Wahoo board, the GPIO field value changes to
1
. Release Button 2, update and the value returns to0
.
- Tap the
LED ON/OFF
button on your test device. The Wahoo board red LED lights in the tricolor LED. - Tap the
Command mode
button to switch to Stream mode. In Stream mode, you can send data to the Bobcat module and receive data from the module. Type in the app text field and tapSend
to send data. In the ZentriOS BLE terminal on the module, type data to see the data appear immediately in the app data received panel.
Structure of the Demo App
The demonstration app contains two activities, and a service that maintains the BLE connection when switching between activities.
The demonstration app, in the app package, contains:
- Activity classes:
- MainActivity - view of Scan button and the list of devices scanned
- DeviceInfoActivity - view of connected ZentriOS BLE module information
- Service class:
- ZentriOS BLEService - the shared service that maintains the BLE connection to the ZentriOS BLE module
- Device - represents a BLE device found by the scan
- DeviceList - provides the array of devices listed in the scan list
The activities receive intents from the ZentriOS BLEService as BLE events take place.
Modifying the Demo App
This section describes some simple modifications to the ZentriOS BLE Android demo app. These are intended to provide an indication of how the code is structured.
We perform some minor re-styling, and add another GPIO to the device info display.
In the file paths below, /ZentriOS BLEAndroid
refers to the directory containing the working copy of the ZentriOS BLEAndroid repository.
Changing the Logo
The Zentri logo icon used in the demo app can be replaced with a logo of your choice. The icon files are .png files located in the resource directories. The pixel resolutions are as shown below:
/ZentriOS BLEAndroid/app/src/main/res/drawable-hdpi/ackme_icon.png
(72x72)/ZentriOS BLEAndroid/app/src/main/res/drawable-mdpi/ackme_icon.png
(48x48)/ZentriOS BLEAndroid/app/src/main/res/drawable-xhdpi/ackme_icon.png
(96x96)/ZentriOS BLEAndroid/app/src/main/res/drawable-xxhdpi/ackme_icon.png
(144x144)
Create copies of your icon at the required resolutions in the resource directories. In our example we created icon files named sdc_icon.png
.
The logo icon is specified in two places in the application manifest, /ZentriOS BLEAndroid/app/src/main/AndroidManifest.xml
.
Replace the instances of the line android:icon="@drawable/ackme_icon"
with a specification for your new logo. For example:
...
<application
android:allowBackup="true"
android:icon="@drawable/sdc_icon"
... >
...
<service
android:name="ack.me.truconnectandroiddemo.TruconnectService"
android:icon="@drawable/sdc_icon"
... >
</service>
...
</application>
Rebuild the app and run it on your test device to see the changes.
Adding a Control for Button 1
This section demonstrates how to add a control for Wahoo Button 1 to the Device Info activity.
Wahoo Button 1 corresponds to GPIO 6.
The layout of the DeviceInfoActivity is specified in /ZentriOS BLEAndroid/app/src/main/res/layout/activity_device_info.xml
.
The (Button 2) GPIO field is specified with a TextView tag containing the attribute android:text="GPIO"
.
Copy the specification for the (Button 2) GPIO TextView to create another TextView for Button 1 directly above it in the XML. Note that as well as creating the new TextView, with modified attributes, we also modified the original (Button 2) GPIO TextView attributes. This layout aligns the Button 1 and Button 2 displays horizontally:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/gpio_b1_value_title"
android:textSize="30sp"
android:id="@+id/gpio_b1_value"
android:gravity="left"
android:layout_below="@+id/adc_value"
android:layout_alignParentStart="true"
android:layout_marginTop="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/gpio_value_title"
android:textSize="30sp"
android:id="@+id/gpio_value"
android:gravity="right"
android:layout_above="@+id/led_button"
android:layout_alignParentEnd="true" />
...
In the file /ZentriOS BLEAndroid/app/src/main/res/values/strings.xml
, add the button title string gpio_b1_value_title
, with content GPO B1:
, above the gpio_value_title
string, and modify the gpio_value_title
string content to GPO B2:
:
...
<string name="update-button-text">Read Values</string>
<string name="gpio-b1-value-title">GPIO B1:</string>
<string name="gpio-value-title">GPIO B2:</string>
<string name="adc-value-title">ADC:</string>
...
The remaining changes are in the file /ZentriOS BLEAndroid/app/src/main/java/ack/me/truconnectandroiddemo/DeviceInfoActivity.java
.
At the beginning of the DeviceInfoActivity class definition, we declare variables for Button 1:
- the declarations for
TEST_B1_GPIO
GPIO number - the TextView instance
mGPIOB1TextView
- A flag to track updating:
mGPIOB1UpdateInProgress
public class DeviceInfoActivity extends Activity
{
public static final String TAG = "DeviceInfo";
private static final int ADC_GPIO = 12;//thermistor on wahoo
private static final int TEST_GPIO = 9;//button2 on wahoo
private static final int TEST_B1_GPIO = 6; // Button 1
...
private TextView mADCTextView;
private TextView mGPIOTextView;
private TextView mGPIOB1TextView; // Button 1
...
private boolean mADCUpdateInProgress = false;
private boolean mGPIOUpdateInProgress = false;
private boolean mGPIOB1UpdateInProgress = false; // Button 1
...
}
In the onCreate method, add a line for the Button 1 TextView, as shown:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_info);
mADCTextView = (TextView)findViewById(R.id.adc_value);
mGPIOTextView = (TextView)findViewById(R.id.gpio_value);
mGPIOB1TextView = (TextView)findViewById(R.id.gpio_b1_value); // Button 1
...
Add the TEST_B1_GPIO
initialization to the DeviceInfoActivity.initGPIOs method:
private void initGPIOs()
{
...
mTruconnectManager.GPIOFunctionSet(TEST_GPIO, TruconnectGPIOFunction.NONE);
mTruconnectManager.GPIOFunctionSet(TEST_B1_GPIO, TruconnectGPIOFunction.NONE); // Button 1
...
mTruconnectManager.GPIOFunctionSet(TEST_GPIO, TruconnectGPIOFunction.STDIO);
mTruconnectManager.GPIOFunctionSet(TEST_B1_GPIO, TruconnectGPIOFunction.STDIO); // Button 1
...
mTruconnectManager.GPIODirectionSet(TEST_GPIO, TruconnectGPIODirection.INPUT);
mTruconnectManager.GPIODirectionSet(TEST_B1_GPIO, TruconnectGPIODirection.INPUT); // Button 1
...
}
Add a line to update the Button 1 GPIO to the DeviceInfoActivity.updateValues method, and a flag to track processing of the command:
private void updateValues()
{
mADCUpdateInProgress = true;
mGPIOUpdateInProgress = true;
mGPIOB1UpdateInProgress = true; // Button 1
Log.d(TAG, "Updating values");
mTruconnectManager.adc(ADC_GPIO);
mTruconnectManager.GPIOGet(TEST_GPIO);
mTruconnectManager.GPIOGet(TEST_B1_GPIO); // Button 1
}
This has the effect of sending the ZentriOS BLE command to get the value of the Button GPIO. The response to the command is delivered by the ZentriOS BLEService as an intent with the action ACTION_COMMAND_RESULT. The BroadcastReceiver accordingly calls the handleCommandResponse method, which extracts the ZentriOS BLE command response as variable result from the Intent extra bundle.
Finally, in the DeviceInfoActivity.handleCommandResponse method, add a case to handle the Button 1 GPIO update. Note that the commands are queued and processed in the order called. In the updateValues() method, the GPIO get command for Button2, TEST_GPIO
, is called first, so the corresponding flag mGPIOUpdateInProgress
is processed first when handling the command response.
private void handleCommandResponse(Intent intent)
{
...
switch (command)
{
...
case GPIO_GET:
if (mGPIOUpdateInProgress)
{
message = String.format("GPIO B2: %s", result);
mGPIOTextView.setText(message);
mGPIOUpdateInProgress = false;
Log.d(TAG, "Updating "+message);
}
else if(mGPIOB1UpdateInProgress) { // Button 1
message = String.format("GPIO B1: %s", result);
mGPIOB1TextView.setText(message);
mGPIOB1UpdateInProgress = false;
Log.d(TAG, "Updating "+message);
}
...
Build and run the app to see the result of these changes.
Press Button 1 on the Wahoo and click the Update button on the app.
These minor modifications indicate how functionality can be changed with small edits to the existing layout files and DeviceInfoActivity methods. For more complex changes and new features, a detailed knowledge of Android development is required.
Modified | Changes | ZentriOS BLE Version Required |
---|---|---|
2015-Apr-01 | Created | 1.5+ |
2015-Apr-16 | Updated for new library version | 1.5+ |