The online course, "Testing and Monitoring ML Model Deployments" is now live.

MetaWear Guide Series Part 9

A Better Connection I
Created: 28 February 2016

This is part 9 of a multipart series showing you how to get started with the MetaWear platform. View the contents of the series to easily skip forwards or backwards

One of the reasons why using the MetaWear sample Android app is a big jump for those new to Android is that it involves multiple activities and especially because it uses fragments which build upon other fragments. This can make some parts of it seem like a black box without some serious digging. In this section, I’ll unpack some of the more basic parts of the sample app. As a result, there will be a slight jump in complexity…But if you’ve made it this far, you’re probably ready.

We are going to add the Sample app’s to our project. This will allow us to select from multiple different boards, and eventually to manage our bluetooth connections more effectively.

To begin, we need to add a new dependency to our app build.grade file:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.mbientlab:metawear:2.4.0'
    compile 'com.mbientlab.bletoolbox:scanner:0.2.0' //add this

Be sure to sync the project after adding the new dependency.


Next, create the new activity. In Android Studio, go to File –> New –> Activity –> Blank Activity

Call the activity, ScannerActivity. The associated layout name will automatically update.

We add the ScannerActivity to our AndroidManifest.xml

    android:label="@string/app_name" >
        <action android:name="android.intent.action.MAIN" />
    android:label="@string/title_activity_scanner" >
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />

Note that scanner activity is now the LAUNCHER activity, and that we have removed that action from .MyActivity. If you run your app you should see the ‘Hello World’ message.

Let’s update our activty_scanner.xml layout file. The ScannerActivity will require the ids we update here:

<LinearLayout xmlns:android=""

        android:text="Select Device"
        android:layout_gravity="center_horizontal" />

    <fragment xmlns:tools="" android:id="@+id/scanner_fragment"
        tools:layout="@layout/blescan_device_list" android:layout_width="match_parent"
        android:layout_height="match_parent" />


You’ll note (and Android Studio will tell you) that a few strings need adding. Add these to your strings.xml file:

<string name="title_connecting">Connecting...</string>
<string name="message_wait">Please wait</string>
<string name="label_cancel">Cancel</string>

OK, now we’re ready to get to work on the ScannerActivity.

By checking against the branch version-0.8, make sure you’ve got all the imports required (there are quite a few).

We will be implementing both a ServiceConnection and a ScannerCommunicationBus in our activity, so the syntax is as follows:

public class ScannerActivity extends AppCompatActivity implements ScannerCommunicationBus, ServiceConnection {
	//activity code


Both of these have certain required methods. From part 3 You should already be familiar with those required for the ServiceConnection:

public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    serviceBinder = (MetaWearBleService.LocalBinder) iBinder;

public void onServiceDisconnected(ComponentName componentName) {


And there are a few standard activity setup methods to complete also:

protected void onCreate(Bundle savedInstanceState) {

    getApplicationContext().bindService(new Intent(this, MetaWearBleService.class), this, BIND_AUTO_CREATE);

public void onDestroy() {

    ///< Unbind the service when the activity is destroyed

Now we need to implement the methods for ScannerCommunicationBus. First, we’ll need a few variables (including our TAG variable for logging):

private static final String TAG = "MetaWear";
private final static UUID[] serviceUuids;
private MetaWearBleService.LocalBinder serviceBinder;
public static final int REQUEST_START_APP= 1;
private MetaWearBoard mwBoard;
static {
    serviceUuids= new UUID[] {

And then the methods themselves:

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch(requestCode) {
            case REQUEST_START_APP:
                ((BleScannerFragment) getFragmentManager().findFragmentById(;
        super.onActivityResult(requestCode, resultCode, data);

    public UUID[] getFilterServiceUuids() {
        return serviceUuids;

    public long getScanDuration() {
        return 10000L;

    public void onDeviceSelected(BluetoothDevice bluetoothDevice) {
        Log.i(TAG, "Device selected");

At this point, we have a basic structure. If you run the app, you will see the scanner activity with a scan button, but nothing will happen when you press the button. Let’s add more code:

public void onDeviceSelected(final BluetoothDevice btDevice) {
    mwBoard= serviceBinder.getMetaWearBoard(btDevice);

    final ProgressDialog connectDialog = new ProgressDialog(this);
    connectDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.label_cancel), new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialogInterface, int i) {

    mwBoard.setConnectionStateHandler(new MetaWearBoard.ConnectionStateHandler() {
        public void connected() {
            Log.i(TAG, String.format("Accelerometer: %s", mwBoard.getMacAddress()));

        public void disconnected() {

        public void failure(int status, Throwable error) {

We now have enough code to search for the boards over bluetooth without manually entering the MAC address. If you run the app and hit “Scan”, then a list of the MetaWear boards within range will be displayed:


The line of code in our log above mwBoard.getMacAddress() also ensures that when you select a board, its MAC address is displayed in the log:


Since this post is already quite long, I’ll break it into two sections. In section II, I will show you the next steps after selecting a board using our new ScannerActivity.

Note You can view all these changes in the github repository on the branch version-0.8

Next post in the series –>