mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-21 16:34:23 +01:00
Template profile rewritten to use new BleManager API
This commit is contained in:
@@ -27,8 +27,10 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -47,7 +49,7 @@ public class TemplateActivity extends BleProfileServiceReadyActivity<TemplateSer
|
||||
|
||||
// TODO change view references to match your need
|
||||
private TextView mValueView;
|
||||
private TextView mValueUnitView;
|
||||
private TextView mBatteryLevelView;
|
||||
|
||||
@Override
|
||||
protected void onCreateView(final Bundle savedInstanceState) {
|
||||
@@ -59,7 +61,9 @@ public class TemplateActivity extends BleProfileServiceReadyActivity<TemplateSer
|
||||
private void setGUI() {
|
||||
// TODO assign your views to fields
|
||||
mValueView = findViewById(R.id.value);
|
||||
mValueUnitView = findViewById(R.id.value_unit);
|
||||
mBatteryLevelView = findViewById(R.id.battery);
|
||||
|
||||
findViewById(R.id.action_set_name).setOnClickListener(v -> getService().performAction("Template"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,16 +81,7 @@ public class TemplateActivity extends BleProfileServiceReadyActivity<TemplateSer
|
||||
protected void setDefaultUI() {
|
||||
// TODO clear your UI
|
||||
mValueView.setText(R.string.not_available_value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceBound(final TemplateService.TemplateBinder binder) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceUnbound() {
|
||||
// not used
|
||||
mBatteryLevelView.setText(R.string.not_available);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,25 +128,53 @@ public class TemplateActivity extends BleProfileServiceReadyActivity<TemplateSer
|
||||
return TemplateService.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceBound(final TemplateService.TemplateBinder binder) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceUnbound() {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) {
|
||||
// this may notify user or show some views
|
||||
}
|
||||
|
||||
private void setValueOnView(final int value) {
|
||||
@Override
|
||||
public void onDeviceDisconnected(final BluetoothDevice device) {
|
||||
super.onDeviceDisconnected(device);
|
||||
mBatteryLevelView.setText(R.string.not_available);
|
||||
}
|
||||
|
||||
// Handling updates from the device
|
||||
@SuppressWarnings("unused")
|
||||
private void setValueOnView(@NonNull final BluetoothDevice device, final int value) {
|
||||
// TODO assign the value to a view
|
||||
mValueView.setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int value) {
|
||||
mBatteryLevelView.setText(getString(R.string.battery, value));
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
final BluetoothDevice device = intent.getParcelableExtra(TemplateService.EXTRA_DEVICE);
|
||||
|
||||
if (TemplateService.BROADCAST_TEMPLATE_MEASUREMENT.equals(action)) {
|
||||
final int value = intent.getIntExtra(TemplateService.EXTRA_DATA, 0);
|
||||
// Update GUI
|
||||
setValueOnView(value);
|
||||
setValueOnView(device, value);
|
||||
} else if (TemplateService.BROADCAST_BATTERY_LEVEL.equals(action)) {
|
||||
final int batteryLevel = intent.getIntExtra(TemplateService.EXTRA_BATTERY_LEVEL, 0);
|
||||
// Update GUI
|
||||
onBatteryLevelChanged(device, batteryLevel);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -159,6 +182,7 @@ public class TemplateActivity extends BleProfileServiceReadyActivity<TemplateSer
|
||||
private static IntentFilter makeIntentFilter() {
|
||||
final IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(TemplateService.BROADCAST_TEMPLATE_MEASUREMENT);
|
||||
intentFilter.addAction(TemplateService.BROADCAST_BATTERY_LEVEL);
|
||||
return intentFilter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,34 +21,43 @@
|
||||
*/
|
||||
package no.nordicsemi.android.nrftoolbox.template;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
|
||||
import no.nordicsemi.android.ble.BleManager;
|
||||
import no.nordicsemi.android.ble.Request;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.log.LogContract;
|
||||
import no.nordicsemi.android.nrftoolbox.parser.TemplateParser;
|
||||
import no.nordicsemi.android.nrftoolbox.battery.BatteryManager;
|
||||
import no.nordicsemi.android.nrftoolbox.template.callback.TemplateDataCallback;
|
||||
|
||||
/**
|
||||
* Modify to template manager to match your requirements.
|
||||
* The TemplateManager extends {@link BatteryManager}, but it may easily extend {@link BleManager}
|
||||
* instead if you don't need Battery Service support. If not, also modify the
|
||||
* {@link TemplateManagerCallbacks} to extend {@link no.nordicsemi.android.ble.BleManagerCallbacks}
|
||||
* and replace BatteryManagerGattCallback to BleManagerGattCallback in this class.
|
||||
*/
|
||||
public class TemplateManager extends BleManager<TemplateManagerCallbacks> {
|
||||
private static final String TAG = "TemplateManager";
|
||||
|
||||
public class TemplateManager extends BatteryManager<TemplateManagerCallbacks> {
|
||||
// TODO Replace the services and characteristics below to match your device.
|
||||
/** The service UUID */
|
||||
public final static UUID SERVICE_UUID = UUID.fromString("0000180D-0000-1000-8000-00805f9b34fb"); // TODO change the UUID to your match your service
|
||||
/** The characteristic UUID */
|
||||
private static final UUID MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A37-0000-1000-8000-00805f9b34fb"); // TODO change the UUID to your match your characteristic
|
||||
static final UUID SERVICE_UUID = UUID.fromString("0000180D-0000-1000-8000-00805f9b34fb"); // Heart Rate service
|
||||
/** A UUID of a characteristic with notify property */
|
||||
private static final UUID MEASUREMENT_CHARACTERISTIC_UUID = UUID.fromString("00002A37-0000-1000-8000-00805f9b34fb"); // Heart Rate Measurement
|
||||
/** A UUID of a characteristic with read property */
|
||||
private static final UUID READABLE_CHARACTERISTIC_UUID = UUID.fromString("00002A38-0000-1000-8000-00805f9b34fb"); // Body Sensor Location
|
||||
/** Some other service UUID */
|
||||
private static final UUID OTHER_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb"); // Generic Access service
|
||||
/** A UUID of a characteristic with write property */
|
||||
private static final UUID WRITABLE_CHARACTERISTIC_UUID = UUID.fromString("00002A00-0000-1000-8000-00805f9b34fb"); // Device Name
|
||||
|
||||
// TODO add more services and characteristics, if required
|
||||
private BluetoothGattCharacteristic mCharacteristic;
|
||||
// TODO Add more services and characteristics references.
|
||||
private BluetoothGattCharacteristic mRequiredCharacteristic, mDeviceNameCharacteristic, mOptionalCharacteristic;
|
||||
|
||||
public TemplateManager(final Context context) {
|
||||
super(context);
|
||||
@@ -56,83 +65,147 @@ public class TemplateManager extends BleManager<TemplateManagerCallbacks> {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected BleManagerGattCallback getGattCallback() {
|
||||
protected BatteryManagerGattCallback getGattCallback() {
|
||||
return mGattCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* BluetoothGatt callbacks for connection/disconnection, service discovery, receiving indication, etc
|
||||
*/
|
||||
private final BleManagerGattCallback mGattCallback = new BleManagerGattCallback() {
|
||||
private final BatteryManagerGattCallback mGattCallback = new BatteryManagerGattCallback() {
|
||||
|
||||
@Override
|
||||
protected Deque<Request> initGatt(@NonNull final BluetoothGatt gatt) {
|
||||
final LinkedList<Request> requests = new LinkedList<>();
|
||||
// TODO initialize your device, enable required notifications and indications, write what needs to be written to start working
|
||||
requests.add(Request.newEnableNotificationsRequest(mCharacteristic));
|
||||
return requests;
|
||||
protected void initialize() {
|
||||
// Initialize the Battery Manager. It will enable Battery Level notifications.
|
||||
// Remove it if you don't need this feature.
|
||||
super.initialize();
|
||||
|
||||
// TODO Initialize your manager here.
|
||||
// Initialization is done once, after the device is connected. Usually it should
|
||||
// enable notifications or indications on some characteristics, write some data or
|
||||
// read some features / version.
|
||||
// After the initialization is complete, the onDeviceReady(...) method will be called.
|
||||
|
||||
// Increase the MTU
|
||||
requestMtu(43)
|
||||
.with((device, mtu) -> log(LogContract.Log.Level.APPLICATION, "MTU changed to " + mtu))
|
||||
.done(device -> {
|
||||
// You may do some logic in here that should be done when the request finished successfully.
|
||||
// In case of MTU this method is called also when the MTU hasn't changed, or has changed
|
||||
// to a different (lower) value. Use .with(...) to get the MTU value.
|
||||
})
|
||||
.fail((device, status) -> log(LogContract.Log.Level.WARNING, "MTU change not supported"));
|
||||
|
||||
// Set notification callback
|
||||
setNotificationCallback(mRequiredCharacteristic)
|
||||
// This callback will be called each time the notification is received
|
||||
.with(new TemplateDataCallback() {
|
||||
@Override
|
||||
public void onSampleValueReceived(@NonNull final BluetoothDevice device, final int value) {
|
||||
// Let's lass received data to the service
|
||||
mCallbacks.onSampleValueReceived(device, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInvalidDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||
log(LogContract.Log.Level.WARNING, "Invalid data received: " + data);
|
||||
}
|
||||
});
|
||||
|
||||
// Enable notifications
|
||||
enableNotifications(mRequiredCharacteristic)
|
||||
// Method called after the data were sent (data will contain 0x0100 in this case)
|
||||
.with((device, data) -> log(LogContract.Log.Level.DEBUG, "Data sent: " + data))
|
||||
// Method called when the request finished successfully. This will be called after .with(..) callback
|
||||
.done(device -> log(LogContract.Log.Level.APPLICATION, "Notifications enabled successfully"))
|
||||
// Methods called in case of an error, for example when the characteristic does not have Notify property
|
||||
.fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to enable notifications"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRequiredServiceSupported(@NonNull final BluetoothGatt gatt) {
|
||||
// TODO Initialize required characteristics.
|
||||
// It should return true if all has been discovered (that is that device is supported).
|
||||
final BluetoothGattService service = gatt.getService(SERVICE_UUID);
|
||||
if (service != null) {
|
||||
mCharacteristic = service.getCharacteristic(MEASUREMENT_CHARACTERISTIC_UUID);
|
||||
mRequiredCharacteristic = service.getCharacteristic(MEASUREMENT_CHARACTERISTIC_UUID);
|
||||
}
|
||||
return mCharacteristic != null;
|
||||
final BluetoothGattService otherService = gatt.getService(OTHER_SERVICE_UUID);
|
||||
if (otherService != null) {
|
||||
mDeviceNameCharacteristic = otherService.getCharacteristic(WRITABLE_CHARACTERISTIC_UUID);
|
||||
}
|
||||
return mRequiredCharacteristic != null && mDeviceNameCharacteristic != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isOptionalServiceSupported(@NonNull final BluetoothGatt gatt) {
|
||||
// Initialize Battery characteristic
|
||||
super.isOptionalServiceSupported(gatt);
|
||||
|
||||
// TODO If there are some optional characteristics, initialize them there.
|
||||
final BluetoothGattService service = gatt.getService(SERVICE_UUID);
|
||||
if (service != null) {
|
||||
mOptionalCharacteristic = service.getCharacteristic(READABLE_CHARACTERISTIC_UUID);
|
||||
}
|
||||
return mOptionalCharacteristic != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeviceDisconnected() {
|
||||
mCharacteristic = null;
|
||||
}
|
||||
// Release Battery Service
|
||||
super.onDeviceDisconnected();
|
||||
|
||||
// TODO implement data handlers. Methods below are called after the initialization is complete.
|
||||
// TODO Release references to your characteristics.
|
||||
mRequiredCharacteristic = null;
|
||||
mDeviceNameCharacteristic = null;
|
||||
mOptionalCharacteristic = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeviceReady() {
|
||||
super.onDeviceReady();
|
||||
|
||||
// TODO initialization is now ready. The activity is being notified using TemplateManagerCallbacks#onDeviceReady() method.
|
||||
// This method may be removed from this class if not required as the super class implementation handles this event.
|
||||
}
|
||||
// Initialization is now ready.
|
||||
// The service or activity has been notified with TemplateManagerCallbacks#onDeviceReady().
|
||||
// TODO Do some extra logic here, of remove onDeviceReady().
|
||||
|
||||
@Override
|
||||
protected void onCharacteristicNotified(@NonNull final BluetoothGatt gatt, @NonNull final BluetoothGattCharacteristic characteristic) {
|
||||
// TODO this method is called when a notification has been received
|
||||
// This method may be removed from this class if not required
|
||||
|
||||
log(LogContract.Log.Level.APPLICATION, "\"" + TemplateParser.parse(characteristic) + "\" received");
|
||||
|
||||
int value;
|
||||
final int flags = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
|
||||
if ((flags & 0x01) > 0) {
|
||||
value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 1);
|
||||
} else {
|
||||
value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1);
|
||||
}
|
||||
//This will send callback to the Activity when new value is received from HR device
|
||||
mCallbacks.onSampleValueReceived(gatt.getDevice(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCharacteristicIndicated(@NonNull final BluetoothGatt gatt, @NonNull final BluetoothGattCharacteristic characteristic) {
|
||||
// TODO this method is called when an indication has been received
|
||||
// This method may be removed from this class if not required
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCharacteristicRead(@NonNull final BluetoothGatt gatt, @NonNull final BluetoothGattCharacteristic characteristic) {
|
||||
// TODO this method is called when the characteristic has been read
|
||||
// This method may be removed from this class if not required
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCharacteristicWrite(@NonNull final BluetoothGatt gatt, @NonNull final BluetoothGattCharacteristic characteristic) {
|
||||
// TODO this method is called when the characteristic has been written
|
||||
// This method may be removed from this class if not required
|
||||
// Device is ready, let's read something here. Usually there is nothing else to be done
|
||||
// here, as all had been done during initialization.
|
||||
readCharacteristic(mOptionalCharacteristic)
|
||||
.with((device, data) -> {
|
||||
// Characteristic value has been read
|
||||
// Let's do some magic with it.
|
||||
if (data.size() > 0) {
|
||||
final Integer value = data.getIntValue(Data.FORMAT_UINT8, 0);
|
||||
log(LogContract.Log.Level.APPLICATION, "Value '" + value + "' has been read!");
|
||||
} else {
|
||||
log(LogContract.Log.Level.WARNING, "Value is empty!");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// TODO Define manager's API
|
||||
|
||||
/**
|
||||
* This method will write important data to the device.
|
||||
*
|
||||
* @param parameter parameter to be written.
|
||||
*/
|
||||
void performAction(final String parameter) {
|
||||
log(LogContract.Log.Level.VERBOSE, "Changing device name to \"" + parameter + "\"");
|
||||
// Write some data to the characteristic.
|
||||
writeCharacteristic(mDeviceNameCharacteristic, Data.from(parameter))
|
||||
// If data are longer than MTU-3, they will be chunked into multiple packets.
|
||||
// Check out other split options, with .split(...).
|
||||
.split()
|
||||
// Callback called when data were sent, or added to outgoing queue is Write Without Request
|
||||
// type has been chosen.
|
||||
.with((device, data) -> log(LogContract.Log.Level.DEBUG, data.size() + " bytes were sent"))
|
||||
// Callback called when data were sent, or added to outgoing queue is Write Without Request
|
||||
// type has been chosen.
|
||||
.done(device -> log(LogContract.Log.Level.APPLICATION, "Device name set to \"" + parameter + "\""))
|
||||
// Callback called when write has failed.
|
||||
.fail((device, status) -> log(LogContract.Log.Level.WARNING, "Failed to change device name"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,24 +21,18 @@
|
||||
*/
|
||||
package no.nordicsemi.android.nrftoolbox.template;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import no.nordicsemi.android.ble.BleManagerCallbacks;
|
||||
import no.nordicsemi.android.nrftoolbox.battery.BatteryManagerCallbacks;
|
||||
import no.nordicsemi.android.nrftoolbox.template.callback.TemplateCharacteristicCallback;
|
||||
|
||||
/**
|
||||
* Interface {@link TemplateManagerCallbacks} must be implemented by {@link TemplateActivity} in order to receive callbacks from {@link TemplateManager}
|
||||
* Interface {@link TemplateManagerCallbacks} must be implemented by {@link TemplateService}
|
||||
* in order to receive callbacks from {@link TemplateManager}
|
||||
*/
|
||||
public interface TemplateManagerCallbacks extends BleManagerCallbacks {
|
||||
interface TemplateManagerCallbacks extends BatteryManagerCallbacks, TemplateCharacteristicCallback {
|
||||
|
||||
// TODO add more callbacks. Callbacks are called when a data has been received/written to a remote device. This is the way how the manager notifies the activity about this event.
|
||||
|
||||
/**
|
||||
* Called when a value is received.
|
||||
*
|
||||
* @param device a device from which the value was obtained
|
||||
* @param value
|
||||
* the new value
|
||||
*/
|
||||
void onSampleValueReceived(final BluetoothDevice device, int value);
|
||||
// Callbacks are called when a data has been received/written to a remote device.
|
||||
// This is the way how the manager notifies the activity about this event.
|
||||
|
||||
// TODO add more callbacks.
|
||||
// If you need, create more ...Callback interfaces and extend this interface with them.
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
@@ -44,6 +45,9 @@ public class TemplateService extends BleProfileService implements TemplateManage
|
||||
public static final String BROADCAST_TEMPLATE_MEASUREMENT = "no.nordicsemi.android.nrftoolbox.template.BROADCAST_MEASUREMENT";
|
||||
public static final String EXTRA_DATA = "no.nordicsemi.android.nrftoolbox.template.EXTRA_DATA";
|
||||
|
||||
public static final String BROADCAST_BATTERY_LEVEL = "no.nordicsemi.android.nrftoolbox.BROADCAST_BATTERY_LEVEL";
|
||||
public static final String EXTRA_BATTERY_LEVEL = "no.nordicsemi.android.nrftoolbox.EXTRA_BATTERY_LEVEL";
|
||||
|
||||
private final static String ACTION_DISCONNECT = "no.nordicsemi.android.nrftoolbox.template.ACTION_DISCONNECT";
|
||||
|
||||
private final static int NOTIFICATION_ID = 864;
|
||||
@@ -55,16 +59,19 @@ public class TemplateService extends BleProfileService implements TemplateManage
|
||||
private final LocalBinder mBinder = new TemplateBinder();
|
||||
|
||||
/**
|
||||
* This local binder is an interface for the bonded activity to operate with the HTS sensor
|
||||
* This local binder is an interface for the bound activity to operate with the sensor.
|
||||
*/
|
||||
public class TemplateBinder extends LocalBinder {
|
||||
// empty
|
||||
// TODO add some service API that mey be used from the Activity
|
||||
class TemplateBinder extends LocalBinder {
|
||||
// TODO Define service API that may be used by a bound Activity
|
||||
|
||||
// public void setLights(final boolean on) {
|
||||
// Logger.v(getLogSession(), "Light set to: " + on);
|
||||
// mManager.setLights(on);
|
||||
// }
|
||||
/**
|
||||
* Sends some important data to the device.
|
||||
*
|
||||
* @param parameter some parameter.
|
||||
*/
|
||||
public void performAction(final String parameter) {
|
||||
mManager.performAction(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,7 +115,7 @@ public class TemplateService extends BleProfileService implements TemplateManage
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSampleValueReceived(final BluetoothDevice device, final int value) {
|
||||
public void onSampleValueReceived(@NonNull final BluetoothDevice device, final int value) {
|
||||
final Intent broadcast = new Intent(BROADCAST_TEMPLATE_MEASUREMENT);
|
||||
broadcast.putExtra(EXTRA_DEVICE, getBluetoothDevice());
|
||||
broadcast.putExtra(EXTRA_DATA, value);
|
||||
@@ -120,14 +127,17 @@ public class TemplateService extends BleProfileService implements TemplateManage
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBatteryLevelChanged(@NonNull final BluetoothDevice device, final int batteryLevel) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the notification
|
||||
*
|
||||
* @param messageResId
|
||||
* message resource id. The message must have one String parameter,<br />
|
||||
* f.e. <code><string name="name">%s is connected</string></code>
|
||||
* @param defaults
|
||||
* signals that will be used to notify the user
|
||||
* Creates the notification.
|
||||
*
|
||||
* @param messageResId message resource id. The message must have one String parameter,<br />
|
||||
* f.e. <code><string name="name">%s is connected</string></code>
|
||||
* @param defaults signals that will be used to notify the user
|
||||
*/
|
||||
private void createNotification(final int messageResId, final int defaults) {
|
||||
final Intent parentIntent = new Intent(this, FeaturesActivity.class);
|
||||
@@ -138,7 +148,7 @@ public class TemplateService extends BleProfileService implements TemplateManage
|
||||
final PendingIntent disconnectAction = PendingIntent.getBroadcast(this, DISCONNECT_REQ, disconnect, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
// both activities above have launchMode="singleTask" in the AndroidManifest.xml file, so if the task is already running, it will be resumed
|
||||
final PendingIntent pendingIntent = PendingIntent.getActivities(this, OPEN_ACTIVITY_REQ, new Intent[] { parentIntent, targetIntent }, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
final PendingIntent pendingIntent = PendingIntent.getActivities(this, OPEN_ACTIVITY_REQ, new Intent[]{parentIntent, targetIntent}, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this, ToolboxApplication.CONNECTED_DEVICE_CHANNEL);
|
||||
builder.setContentIntent(pendingIntent);
|
||||
builder.setContentTitle(getString(R.string.app_name)).setContentText(getString(messageResId, getDeviceName()));
|
||||
@@ -172,5 +182,4 @@ public class TemplateService extends BleProfileService implements TemplateManage
|
||||
stopSelf();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package no.nordicsemi.android.nrftoolbox.template.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* This class defines your characteristic API.
|
||||
* In this example (that is the HRM characteristic, which the template is based on), is notifying
|
||||
* with a value (Heart Rate). The single method just returns the value and ignores other
|
||||
* optional data from Heart Rate Measurement characteristic for simplicity.
|
||||
*/
|
||||
public interface TemplateCharacteristicCallback {
|
||||
|
||||
/**
|
||||
* Called when a value is received.
|
||||
*
|
||||
* @param device a device from which the value was obtained.
|
||||
* @param value the new value.
|
||||
*/
|
||||
void onSampleValueReceived(@NonNull final BluetoothDevice device, int value);
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package no.nordicsemi.android.nrftoolbox.template.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import no.nordicsemi.android.ble.callback.profile.ProfileDataCallback;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
|
||||
/**
|
||||
* This is a sample data callback, that's based on Heart Rate Measurement characteristic.
|
||||
* It parses the HR value and ignores other optional data for simplicity.
|
||||
* Check {@link no.nordicsemi.android.ble.common.callback.hr.HeartRateMeasurementDataCallback}
|
||||
* for full implementation.
|
||||
*
|
||||
* TODO Modify the content to parse your data.
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public abstract class TemplateDataCallback implements ProfileDataCallback, TemplateCharacteristicCallback {
|
||||
|
||||
@Override
|
||||
public void onDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||
if (data.size() < 2) {
|
||||
onInvalidDataReceived(device, data);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read flags
|
||||
int offset = 0;
|
||||
final int flags = data.getIntValue(Data.FORMAT_UINT8, offset);
|
||||
final int hearRateType = (flags & 0x01) == 0 ? Data.FORMAT_UINT8 : Data.FORMAT_UINT16;
|
||||
offset += 1;
|
||||
|
||||
// Validate packet length. The type's lower nibble is its length.
|
||||
if (data.size() < 1 + (hearRateType & 0x0F)) {
|
||||
onInvalidDataReceived(device, data);
|
||||
return;
|
||||
}
|
||||
|
||||
final int value = data.getIntValue(hearRateType, offset);
|
||||
// offset += hearRateType & 0xF;
|
||||
|
||||
// ...
|
||||
|
||||
// Report the parsed value(s)
|
||||
onSampleValueReceived(device, value);
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@
|
||||
<!-- Application section -->
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
style="@style/Widget.List"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -131,6 +132,15 @@
|
||||
</TableLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_set_name"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_below="@+id/container"
|
||||
android:text="@string/template_action"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_connect"
|
||||
style="@style/Widget.Connect"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<string name="template_section_header">Values</string>
|
||||
<string name="template_value_title">Value</string>
|
||||
<string name="template_unit_bpm">bpm</string>
|
||||
<string name="template_action">An action</string>
|
||||
|
||||
<string name="template_notification_action_disconnect">Disconnect</string>
|
||||
<string name="template_notification_connected_message">%s is connected.</string>
|
||||
|
||||
Reference in New Issue
Block a user