.. highlight:: java MetaWearBoard ============= The `MetaWearBoard `_ class is the central class for communicating with your MetaWear board; it is similar to the old MetaWearController class from previous APIs. To retrieve a MetaWearBoard object, you will need a reference to the `MetaWearBleService.LocalBinder `_ class and the BluetoothDevice object that corresponds to the MetaWear board you are using. You can create a BluetoothDevice object with `BluetoothAdapter.getRemoteDevice `_ if you know the MAC address or initiate a `Bluetooth LE scan `_ to find your board. :: import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; // Other required imports public class MainActivity extends Activity implements ServiceConnection { private final String MW_MAC_ADDRESS= "EC:2C:09:81:22:AC"; private MetaWearBoard mwBoard; public void retrieveBoard() { final BluetoothManager btManager= (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); final BluetoothDevice remoteDevice= btManager.getAdapter().getRemoteDevice(MW_MAC_ADDRESS); // Create a MetaWear board object for the Bluetooth Device mwBoard= binder.getMetaWearBoard(remoteDevice); } } Connection State ---------------- The device's connection state is controlled with the connect and disconnect functions. Notifications about the connection state are handled by the `ConnectionStateHandler `_ class. You register a handler by calling `setConnectionStateHandler `_. :: import android.util.Log; import static com.mbientlab.metawear.MetaWearBoard.ConnectionStateHandler; public class MainActivity extends Activity implements ServiceConnection { private final ConnectionStateHandler stateHandler= new ConnectionStateHandler() { @Override public void connected() { Log.i("MainActivity", "Connected"); } @Override public void disconnected() { Log.i("MainActivity", "Connected Lost"); } @Override public void failure(int status, Throwable error) { Log.e("MainActivity", "Error connecting", error); } }; public void connectBoard() { mwBoard.setConnectionStateHandler(stateHandler); mwBoard.connect(); } } Asynchronous Operations ----------------------- Instead of registering callback functions to asynchronously receive responses from MetaWear or Bluetooth LE requests, asynchronous operations are encapsulated by the `AsyncOperation `_ class. This class acts as an observer of the task, notifying the user asynchronously when the task is complete. To see this class in action, call `MetaWearBoard.readRssi `_; the method returns an `AsyncOperation `_ holding an integer result. :: AsyncOperation result= mwBoard.readRssi(); With our AsyncOperation object in hand, we now register a handler to listen for the result of this request. If the request has already been completed when the handler is registered, it will immediately be executed and discarded. Otherwise, it will be queued and executed later when the task has finished. The `CompletionHandler `_ class has two methods: success and failure. The former is called if the request was successful and passes the result to the caller, Conversely, the latter is called if the operation or success callback function failed, passing the error to the user. :: import com.mbientlab.metawear.AsyncResult; public class MainActivity extends Activity implements ServiceConnection { public void updateRssi() { AsyncResult result= mwBoard.readRssi(); result.onComplete(new AsyncResult.CompletionHandler() { @Override public void success(final Integer result) { Log.i("MainActivity", String.format("Rssi (%d dBm)", result)); } @Override public void failure(Throwable error) { Log.e("AsyncResult Example", "Error reading RSSI value", error); } }); } } Modules ------- Modules are on-board sensors or features supported by the firmware. To interact with the underlying MetaWear modules, you will first need to establish a connection with the board. Once a successful connection has been established, you can then call `MetaWearBoard.getModule `_. If the board does not support the requested module, an `UnsupportedModuleException `_ will be thrown. This is a checked exception, meaning users must handle the exception. :: import com.mbientlab.metawear.module.Led; import com.mbientlab.metawear.UnsupportedModuleException; public class MainActivity extends Activity implements ServiceConnection { // Only run this function once a connection to the board has been made public void turnOnLed() { try { // Do not need to type cast result to Led class Led ledCtrllr= mwBoard.getModule(Led.class); ledCtrllr.writeChannelAttributes(Led.ColorChannel.BLUE) .setRiseTime((short) 0).setPulseDuration((short) 1000) .setRepeatCount((byte) -1).setHighTime((short) 500) .setHighIntensity((byte) 16).setLowIntensity((byte) 16) .commit(); ledCtrllr.playLed(false); } catch (UnsupportedModuleException e) { Toast.makeText(this, "Led module not supported on this board / firmware", Toast.LENGTH_LONG).show(); Log.e("MainActivity", "No Led on the board", e); } } } For users who know exactly what modules their MetaWears have, the `lookupModule `_ can be used to retrieve modules without needing to handle exceptions. This function will simply return null if a module cannot be found. :: Led ledCtrllr; if ((ledCtrllr= mwBoard.getModule(Led.class)) != null) { ledCtrllr.writeChannelAttributes(Led.ColorChannel.BLUE) .setRiseTime((short) 0).setPulseDuration((short) 1000) .setRepeatCount((byte) -1).setHighTime((short) 500) .setHighIntensity((byte) 16).setLowIntensity((byte) 16) .commit(); ledCtrllr.playLed(false); } Serialization ------------- The internal state of the class can be converted into a byte array, which can then be saved onto the device. You can use this to persist the state across app crashes or combine it with the Macro system to rebuild the class state after a programmed command executes. To serialize the state, call `serializeState `_ and conversely, call `deserializeState `_ to restore the class' state. :: import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import android.content.SharedPreferences; public class MainActivity extends Activity implements ServiceConnection { private static final String SHARED_PREF_KEY= "MainActivity.SHARED_PREF_KEY"; public void serializeToFile() throws IOException { String filename= String.format("metawearboard_%s", mwBoard.getMacAddress()); File file = new File(context.getFilesDir(), ); FileOutputStream fos= new FileOutputStream(file); fos.write(mwBoard.serializeState()); fos.close(); } public void deserializeFromFile() throws IOException { String filename= String.format("metawearboard_%s", mwBoard.getMacAddress()); File fPtr= new File(filename); FileInputStream fis= new FileInputStream(fPtr); // only works with files < 2GB byte[] buffer= new byte[(int) fPtr.length()]; fis.read(buffer); mwBoard.deserializeState(buffer); } public void serializeToSharedPreferences() { SharedPreferences.Editor editor= getSharedPreferences(SHARED_PREF_KEY, MODE_PRIVATE).edit(); editor.putString(mwBoard.getMacAddress(), new String(mwBoard.serializeState())); editor.apply(); } public void deserializeFromSharedPreferences() { SharedPreferences sharedPref= getSharedPreferences(SHARED_PREF_KEY, MODE_PRIVATE); String stateStr= sharedPref.getString(mwBoard.getMacAddress(), ""); if (!stateStr.isEmpty()) { mwBoard.deserializeState(stateStr); } else { Log.i("MainActivity", "Cannot find state for this board"); } } } Updating Firmware ----------------- As of api v2.6.0, the `updateFirmware `_ function is deprecated. Instead, the api provides the `downloadLatestFirmware `_ function which will download the latest firmware release to your mobile device. The firmware file can then be uploaded to your MetaWear using the `Nordic DFU library `_. :: mwBoard.downloadLatestFirmware().onComplete(new AsyncOperation.CompletionHandler() { @Override public void success(File result) { if (mwBoard.inMetaBootMode()) { mwBoard.disconnect(); } else { mwBoard.lookupModule(Debug.class).jumpToBootloader(); } } }); Checkout the Nordic DFU library GitHub page or the `MetaWear Android app `_ source code for information and examples on how to use the library.