mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2025-12-21 16:34:23 +01:00
Template profile added
This commit is contained in:
@@ -7,8 +7,8 @@ android {
|
||||
applicationId "no.nordicsemi.android.nrftoolbox"
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 22
|
||||
versionCode 30
|
||||
versionName "1.12.1"
|
||||
versionCode 31
|
||||
versionName "1.13.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="no.nordicsemi.android.nrftoolbox"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="30"
|
||||
android:versionName="1.12.1" >
|
||||
android:versionCode="31"
|
||||
android:versionName="1.13.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="18"
|
||||
@@ -59,6 +59,26 @@
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask" >
|
||||
</activity>
|
||||
|
||||
<!-- Template plugin activities -->
|
||||
<!-- Remember to add your plug-in Activities to the Android Manifest file. -->
|
||||
<activity
|
||||
android:name="no.nordicsemi.android.nrftoolbox.template.TemplateActivity"
|
||||
android:icon="@drawable/ic_template_feature"
|
||||
android:label="@string/template_feature_title" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="no.nordicsemi.android.nrftoolbox.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="no.nordicsemi.android.nrftoolbox.template.settings.SettingsActivity"
|
||||
android:label="@string/template_settings_title" />
|
||||
<service
|
||||
android:name="no.nordicsemi.android.nrftoolbox.template.TemplateService"
|
||||
android:label="@string/template_feature_title" />
|
||||
|
||||
<!-- Plug-in activities -->
|
||||
<activity
|
||||
android:name="no.nordicsemi.android.nrftoolbox.dfu.DfuActivity"
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.nrftoolbox.parser;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// TODO this method may be used for developing purposes to log the data from your device using the nRF Logger application.
|
||||
public class TemplateParser {
|
||||
// TODO add some flags, if needed
|
||||
private static final byte HEART_RATE_VALUE_FORMAT = 0x01; // 1 bit
|
||||
|
||||
/**
|
||||
* This method converts the value of the characteristic to the String. The String is then logged in the nRF logger log session
|
||||
* @param characteristic the characteristic to be parsed
|
||||
* @return human readable value of the characteristic
|
||||
*/
|
||||
public static String parse(final BluetoothGattCharacteristic characteristic) {
|
||||
int offset = 0;
|
||||
final int flags = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset++);
|
||||
|
||||
/*
|
||||
* In the template we are using the HRM values as an example.
|
||||
* false Heart Rate Value Format is set to UINT8. Units: beats per minute (bpm)
|
||||
* true Heart Rate Value Format is set to UINT16. Units: beats per minute (bpm)
|
||||
*/
|
||||
final boolean value16bit = (flags & HEART_RATE_VALUE_FORMAT) > 0;
|
||||
|
||||
// heart rate value is 8 or 16 bit long
|
||||
int value = characteristic.getIntValue(value16bit ? BluetoothGattCharacteristic.FORMAT_UINT16 : BluetoothGattCharacteristic.FORMAT_UINT8, offset++); // bits per minute
|
||||
if (value16bit)
|
||||
offset++;
|
||||
|
||||
// TODO parse more data
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("Template Measurement: ").append(value).append(" bpm");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
nRF Toolbox demonstrates how to implement the Bluetooth Smart features in an Android application.
|
||||
It consists of number of profiles, like Heart Rate, Blood Pressure etc. that may be use as is to communicate with real devices.
|
||||
They use the Bluetooth SIG adopted profiles, that may be found here: https://developer.bluetooth.org/gatt/profiles/Pages/ProfilesHome.aspx
|
||||
|
||||
The Template Profile has been created to give a quick start with implementing proprietary services. Just start modifying 4 classes inside
|
||||
the template package to implement features you need.
|
||||
|
||||
Below you will find a short step-by-step tutorial:
|
||||
|
||||
1. The template consists of the following files:
|
||||
- TemplateActivity - the main class that is responsible for managing the view of your profile
|
||||
- TemplateService - the service that is started whenever you connect to a device. I handles the Bluetooth Smart communication using the...
|
||||
- TemplateManager - the manager that handles all the BLE logic required to communicate with the device. The TemplateManager derives from
|
||||
the BleManager which handles most of the event itself and propagates the data-relevant to deriving class. You don't
|
||||
have to, or even shouldn't modify the BleManager (unless you want to change the default behaviour).
|
||||
- TemplateManagerCallbacks - the interface with a list of callbacks that the TemplateManager can call. Each method is usually related to one
|
||||
BLE event, e.g. receiving a new value of the characteristic.\
|
||||
- TemplateParser - an optional class in the .parser package that is responsible for converting the characteristic value to String.
|
||||
This is used only for debugging. The String returned by the parse(..) method is then logged into the nRF Logger application
|
||||
(if such installed).
|
||||
- /settings/SettingsActivity and /settings/SettingsFragment - classes used to present user preferences. A stub implementation in the template.
|
||||
- /res/layout/activity_feature_template.xml - the layout file for the TemplateActivity
|
||||
- /res/values/strings_template.xml - a set of strings used in the layout file
|
||||
- /res/xml/settings/template.xml - the user settings configuration
|
||||
- /res/drawable/(x)hdpi/ic_template_feature.png - the template profile icon (HDPI, XHDPI). Please, keep the files size.
|
||||
- /res/drawable/(x)hdpi/ic_stat_notify_template - the icon that is used in the notification
|
||||
|
||||
2. The communication between the components goes as follows:
|
||||
- User clicks the CONNECT button and selects a target device on TemplateActivity.
|
||||
- The base class of the TemplateActivity starts the service given by getServiceClass() method.
|
||||
- The service starts and initializes the TemplateManager. TemplateActivity binds to the service and is being given the TemplateBinder object (the service API) as a result.
|
||||
- The manager connects to the device using Bluetooth Smart and discovers its services.
|
||||
- The manager initializes the device. Initialization is done using the list of actions given by the initGatt(..) method in the TemplateManager.
|
||||
Initialization usually contains enabling notifications, writing some initial values etc.
|
||||
- When initialization is complete the manager calls the onDeviceReady() callback.
|
||||
- The service sends the BROADCAST_DEVICE_READY broadcast to the activity. Communication from the Service to the Activity is always done using the LocalBroadcastManager broadcasts.
|
||||
- The base class of the TemplateActivity listens to the broadcasts and calls appropriate methods.
|
||||
|
||||
- When a custom event occurs, for example a notification is received, the manager parses the incoming data and calls the proper callback.
|
||||
- The callback implementation in the TemplateService sends a broadcast message with values given in parameters.
|
||||
- The TemplateActivity, which had registered a broadcast receiver before, listens to the broadcasts, reads the values and present them to users.
|
||||
|
||||
- Communication Activity->Service is done using the API in the TemplateBinder. You may find the example of how to use it in the ProximityActivity.
|
||||
|
||||
3. Please read the files listed above and the TODO messages for more information what to modify in the files.
|
||||
|
||||
4. Remember to add your activities and the service in the AndroidManifest.xml file. The nRF Toolbox lists all activities with the following intent filter:
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="no.nordicsemi.android.nrftoolbox.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
5. Feel free to rename the nRF Toolbox application (/res/values/strings.xml ->app_name), change the toolbar colors (/res/values/color.xml -> actionBarColor, actionBarColorDark).
|
||||
In order to remove unused profiles from the main FeaturesActivity just comment out their intent-filter tags in the AndroidManifest.xml file.
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.nrftoolbox.template;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.view.Menu;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import no.nordicsemi.android.nrftoolbox.R;
|
||||
import no.nordicsemi.android.nrftoolbox.profile.BleProfileService;
|
||||
import no.nordicsemi.android.nrftoolbox.profile.BleProfileServiceReadyActivity;
|
||||
import no.nordicsemi.android.nrftoolbox.template.settings.SettingsActivity;
|
||||
|
||||
/**
|
||||
* Modify the Template Activity to match your needs.
|
||||
*/
|
||||
public class TemplateActivity extends BleProfileServiceReadyActivity<TemplateService.TemplateBinder> {
|
||||
@SuppressWarnings("unused")
|
||||
private final String TAG = "TemplateActivity";
|
||||
|
||||
// TODO change view references to match your need
|
||||
private TextView mValueView;
|
||||
private TextView mValueUnitView;
|
||||
|
||||
@Override
|
||||
protected void onCreateView(final Bundle savedInstanceState) {
|
||||
// TODO modify the layout file(s). By default the activity shows only one field - the Heart Rate value as a sample
|
||||
setContentView(R.layout.activity_feature_template);
|
||||
setGUI();
|
||||
}
|
||||
|
||||
private void setGUI() {
|
||||
// TODO assign your views to fields
|
||||
mValueView = (TextView) findViewById(R.id.value);
|
||||
mValueUnitView = (TextView) findViewById(R.id.value_unit);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize(final Bundle savedInstanceState) {
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, makeIntentFilter());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultUI() {
|
||||
// TODO clear your UI
|
||||
mValueView.setText(R.string.not_available_value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceBinded(final TemplateService.TemplateBinder binder) {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceUnbinded() {
|
||||
// not used
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLoggerProfileTitle() {
|
||||
return R.string.template_feature_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getAboutTextId() {
|
||||
return R.string.template_about_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(final Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.settings_and_about, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onOptionsItemSelected(final int itemId) {
|
||||
switch (itemId) {
|
||||
case R.id.action_settings:
|
||||
final Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivity(intent);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getDefaultDeviceName() {
|
||||
return R.string.template_default_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UUID getFilterUUID() {
|
||||
// TODO this method may return the UUID of the service that is required to be in the advertisement packet of a device in order to be listed on the Scanner dialog.
|
||||
// If null is returned no filtering is done.
|
||||
return TemplateManager.SERVICE_UUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends BleProfileService> getServiceClass() {
|
||||
return TemplateService.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServicesDiscovered(boolean optionalServicesFound) {
|
||||
// this may notify user or show some views
|
||||
}
|
||||
|
||||
private void setValueOnView(final int value) {
|
||||
// TODO assign the value to a view
|
||||
mValueView.setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (TemplateService.BROADCAST_TEMPLATE_MEASUREMENT.equals(action)) {
|
||||
final int value = intent.getIntExtra(TemplateService.EXTRA_DATA, 0);
|
||||
// Update GUI
|
||||
setValueOnView(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static IntentFilter makeIntentFilter() {
|
||||
final IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(TemplateService.BROADCAST_TEMPLATE_MEASUREMENT);
|
||||
return intentFilter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.nrftoolbox.template;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
|
||||
import no.nordicsemi.android.log.Logger;
|
||||
import no.nordicsemi.android.nrftoolbox.parser.TemplateParser;
|
||||
import no.nordicsemi.android.nrftoolbox.profile.BleManager;
|
||||
|
||||
/**
|
||||
* Modify to template manager to match your requirements.
|
||||
*/
|
||||
public class TemplateManager extends BleManager<TemplateManagerCallbacks> {
|
||||
private static final String TAG = "TemplateManager";
|
||||
|
||||
/** 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
|
||||
|
||||
// TODO add more services and characteristics, if required
|
||||
private BluetoothGattCharacteristic mCharacteristic;
|
||||
|
||||
public TemplateManager(final Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BleManagerGattCallback getGattCallback() {
|
||||
return mGattCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* BluetoothGatt callbacks for connection/disconnection, service discovery, receiving indication, etc
|
||||
*/
|
||||
private final BleManagerGattCallback mGattCallback = new BleManagerGattCallback() {
|
||||
|
||||
@Override
|
||||
protected Queue<Request> initGatt(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.push(Request.newEnableNotificationsRequest(mCharacteristic));
|
||||
return requests;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRequiredServiceSupported(final BluetoothGatt gatt) {
|
||||
final BluetoothGattService service = gatt.getService(SERVICE_UUID);
|
||||
if (service != null) {
|
||||
mCharacteristic = service.getCharacteristic(MEASUREMENT_CHARACTERISTIC_UUID);
|
||||
}
|
||||
return mCharacteristic != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeviceDisconnected() {
|
||||
mCharacteristic = null;
|
||||
}
|
||||
|
||||
// TODO implement data handlers. Methods below are called after the initialization is complete.
|
||||
|
||||
@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.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCharacteristicNotified(final BluetoothGatt gatt, 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
|
||||
|
||||
if (mLogSession != null)
|
||||
Logger.a(mLogSession, TemplateParser.parse(characteristic));
|
||||
|
||||
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(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCharacteristicIndicated(final BluetoothGatt gatt, 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(final BluetoothGatt gatt, 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(final BluetoothGatt gatt, 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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.nrftoolbox.template;
|
||||
|
||||
import no.nordicsemi.android.nrftoolbox.profile.BleManagerCallbacks;
|
||||
|
||||
/**
|
||||
* Interface {@link TemplateManagerCallbacks} must be implemented by {@link TemplateActivity} in order to receive callbacks from {@link TemplateManager}
|
||||
*/
|
||||
public interface TemplateManagerCallbacks extends BleManagerCallbacks {
|
||||
|
||||
// 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 value
|
||||
* the new value
|
||||
*/
|
||||
public void onSampleValueReceived(int value);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.nrftoolbox.template;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import no.nordicsemi.android.log.Logger;
|
||||
import no.nordicsemi.android.nrftoolbox.FeaturesActivity;
|
||||
import no.nordicsemi.android.nrftoolbox.R;
|
||||
import no.nordicsemi.android.nrftoolbox.profile.BleManager;
|
||||
import no.nordicsemi.android.nrftoolbox.profile.BleProfileService;
|
||||
|
||||
public class TemplateService extends BleProfileService implements TemplateManagerCallbacks {
|
||||
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";
|
||||
|
||||
private final static String ACTION_DISCONNECT = "no.nordicsemi.android.nrftoolbox.template.ACTION_DISCONNECT";
|
||||
|
||||
private final static int NOTIFICATION_ID = 864;
|
||||
private final static int OPEN_ACTIVITY_REQ = 0;
|
||||
private final static int DISCONNECT_REQ = 1;
|
||||
|
||||
private TemplateManager mManager;
|
||||
|
||||
private final LocalBinder mBinder = new TemplateBinder();
|
||||
|
||||
/**
|
||||
* This local binder is an interface for the bonded activity to operate with the HTS sensor
|
||||
*/
|
||||
public class TemplateBinder extends LocalBinder {
|
||||
// empty
|
||||
// TODO add some service API that mey be used from the Activity
|
||||
|
||||
// public void setLights(final boolean on) {
|
||||
// Logger.v(getLogSession(), "Light set to: " + on);
|
||||
// mManager.setLights(on);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LocalBinder getBinder() {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BleManager<TemplateManagerCallbacks> initializeManager() {
|
||||
return mManager = new TemplateManager(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ACTION_DISCONNECT);
|
||||
registerReceiver(mDisconnectActionBroadcastReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
// when user has disconnected from the sensor, we have to cancel the notification that we've created some milliseconds before using unbindService
|
||||
cancelNotification();
|
||||
unregisterReceiver(mDisconnectActionBroadcastReceiver);
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRebind() {
|
||||
// when the activity rebinds to the service, remove the notification
|
||||
cancelNotification();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUnbind() {
|
||||
// when the activity closes we need to show the notification that user is connected to the sensor
|
||||
createNotification(R.string.template_notification_connected_message, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceStarted() {
|
||||
// logger is now available. Assign it to the manager
|
||||
mManager.setLogger(getLogSession());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSampleValueReceived(final int value) {
|
||||
final Intent broadcast = new Intent(BROADCAST_TEMPLATE_MEASUREMENT);
|
||||
broadcast.putExtra(EXTRA_DATA, value);
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||
|
||||
if (!mBinded) {
|
||||
// Here we may update the notification to display the current value.
|
||||
// TODO modify the notification here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
parentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
final Intent targetIntent = new Intent(this, TemplateActivity.class);
|
||||
|
||||
final Intent disconnect = new Intent(ACTION_DISCONNECT);
|
||||
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 Notification.Builder builder = new Notification.Builder(this).setContentIntent(pendingIntent);
|
||||
builder.setContentTitle(getString(R.string.app_name)).setContentText(getString(messageResId, getDeviceName()));
|
||||
builder.setSmallIcon(R.drawable.ic_stat_notify_template);
|
||||
builder.setShowWhen(defaults != 0).setDefaults(defaults).setAutoCancel(true).setOngoing(true);
|
||||
builder.addAction(R.drawable.ic_action_bluetooth, getString(R.string.template_notification_action_disconnect), disconnectAction);
|
||||
|
||||
final Notification notification = builder.build();
|
||||
final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nm.notify(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the existing notification. If there is no active notification this method does nothing
|
||||
*/
|
||||
private void cancelNotification() {
|
||||
final NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
nm.cancel(NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* This broadcast receiver listens for {@link #ACTION_DISCONNECT} that may be fired by pressing Disconnect action button on the notification.
|
||||
*/
|
||||
private final BroadcastReceiver mDisconnectActionBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
Logger.i(getLogSession(), "[Notification] Disconnect action pressed");
|
||||
if (isConnected())
|
||||
getBinder().disconnect();
|
||||
else
|
||||
stopSelf();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.nrftoolbox.template.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.MenuItem;
|
||||
|
||||
public class SettingsActivity extends ActionBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Display the fragment as the main content.
|
||||
getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.nrftoolbox.template.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceFragment;
|
||||
|
||||
import no.nordicsemi.android.nrftoolbox.R;
|
||||
|
||||
public class SettingsFragment extends PreferenceFragment {
|
||||
public static final String SETTINGS_DATA = "settings_template_data"; // TODO values matching those in settings_template.xml file in /res/xml
|
||||
public static final int SETTINGS_VARIANT_A = 0;
|
||||
public static final int SETTINGS_VARIANT_B = 1;
|
||||
public static final int SETTINGS_VARIANT_DEFAULT = SETTINGS_VARIANT_A;
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.settings_template);
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_stat_notify_template.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_stat_notify_template.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 546 B |
BIN
app/src/main/res/drawable-hdpi/ic_template_feature.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_template_feature.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_stat_notify_template.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_stat_notify_template.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 658 B |
BIN
app/src/main/res/drawable-xhdpi/ic_template_feature.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_template_feature.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
136
app/src/main/res/layout/activity_feature_template.xml
Normal file
136
app/src/main/res/layout/activity_feature_template.xml
Normal file
@@ -0,0 +1,136 @@
|
||||
<!--
|
||||
~ Copyright (c) 2015, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
~
|
||||
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~
|
||||
~ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
~ software without specific prior written permission.
|
||||
~
|
||||
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
~ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
~ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
~ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".HTSActivity" >
|
||||
|
||||
<!-- The size of text below must be fixed, therefore dp are used instead of sp -->
|
||||
|
||||
<no.nordicsemi.android.nrftoolbox.widget.TrebuchetBoldTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/template_feature_title_long_margin"
|
||||
android:rotation="270"
|
||||
android:text="@string/template_feature_title_long"
|
||||
android:textColor="@color/darkGray"
|
||||
android:textSize="32dp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginLeft="@dimen/feature_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/feature_device_name_margin_top"
|
||||
android:background="@drawable/battery"
|
||||
android:freezesText="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/not_available"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<no.nordicsemi.android.nrftoolbox.widget.TrebuchetTextView
|
||||
android:id="@+id/device_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_toRightOf="@+id/battery"
|
||||
android:layout_marginTop="@dimen/feature_device_name_margin_top"
|
||||
android:ellipsize="end"
|
||||
android:freezesText="true"
|
||||
android:maxLines="1"
|
||||
android:text="@string/template_default_name"
|
||||
android:textAllCaps="true"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<!-- Application section -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin_bottom"
|
||||
android:layout_marginLeft="@dimen/feature_horizontal_margin"
|
||||
android:layout_marginRight="@dimen/feature_horizontal_margin"
|
||||
android:layout_marginTop="@dimen/feature_vertical_margin_top"
|
||||
style="@style/Widget.List"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<no.nordicsemi.android.nrftoolbox.widget.TrebuchetBoldTextView
|
||||
style="@style/Widget.ListTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/template_section_header" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/feature_section_padding" >
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<no.nordicsemi.android.nrftoolbox.widget.TrebuchetTextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/template_value_title" />
|
||||
|
||||
<no.nordicsemi.android.nrftoolbox.widget.TrebuchetBoldTextView
|
||||
android:id="@+id/value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:freezesText="true"
|
||||
android:gravity="right"
|
||||
android:text="@string/not_available_value"
|
||||
android:textSize="36sp" />
|
||||
|
||||
<no.nordicsemi.android.nrftoolbox.widget.TrebuchetTextView
|
||||
android:id="@+id/value_unit"
|
||||
android:layout_width="45dp"
|
||||
android:layout_height="match_parent"
|
||||
android:freezesText="true"
|
||||
android:gravity="bottom"
|
||||
android:text="@string/template_unit_bpm" />
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_connect"
|
||||
style="@style/Widget.Connect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/activity_vertical_margin_bottom"
|
||||
android:onClick="onConnectClicked"
|
||||
android:text="@string/action_connect" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
52
app/src/main/res/values/strings_template.xml
Normal file
52
app/src/main/res/values/strings_template.xml
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
~
|
||||
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~
|
||||
~ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
~ software without specific prior written permission.
|
||||
~
|
||||
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
~ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
~ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
~ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<resources>
|
||||
<string name="template_feature_title">Template</string>
|
||||
<string name="template_settings_title">Template Settings</string>
|
||||
|
||||
<string name="template_feature_title_long">TEMPLATE</string>
|
||||
<dimen name="template_feature_title_long_margin">-62dp</dimen>
|
||||
|
||||
<string name="template_default_name">DEFAULT DEVICE</string>
|
||||
<string name="template_section_header">Values</string>
|
||||
<string name="template_value_title">Value</string>
|
||||
<string name="template_unit_bpm">bpm</string>
|
||||
|
||||
<string name="template_notification_action_disconnect">Disconnect</string>
|
||||
<string name="template_notification_connected_message">%s is connected.</string>
|
||||
|
||||
<string name="template_settings_units_title">Some data</string>
|
||||
<string name="template_settings_units_summary">%s</string>
|
||||
<string-array name="template_settings_units">
|
||||
<item>Variant A</item>
|
||||
<item>Variant B</item>
|
||||
</string-array>
|
||||
<string-array name="template_settings_units_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
</string-array>
|
||||
|
||||
<string name="template_about_text">This is an empty profile that may be easily adopted to match customer requirements.
|
||||
The Bluetooth Smart connection is handled by the Manager in Template Service.
|
||||
\n\nBy default this profile displays the Heart Rate value.</string>
|
||||
</resources>
|
||||
@@ -24,8 +24,8 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<ListPreference
|
||||
android:title="@string/csc_settings_units_title"
|
||||
android:summary="@string/csc_settings_units_summary"
|
||||
android:title="@string/hts_settings_units_title"
|
||||
android:summary="@string/hts_settings_units_summary"
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/hts_settings_units"
|
||||
android:entryValues="@array/hts_settings_units_values"
|
||||
|
||||
34
app/src/main/res/xml/settings_template.xml
Normal file
34
app/src/main/res/xml/settings_template.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
~ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
~
|
||||
~ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
~
|
||||
~ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
~ documentation and/or other materials provided with the distribution.
|
||||
~
|
||||
~ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
~ software without specific prior written permission.
|
||||
~
|
||||
~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
~ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
~ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
~ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
~ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<ListPreference
|
||||
android:title="@string/template_settings_units_title"
|
||||
android:summary="@string/template_settings_units_summary"
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/template_settings_units"
|
||||
android:entryValues="@array/template_settings_units_values"
|
||||
android:key="settings_template_data" />
|
||||
|
||||
</PreferenceScreen>
|
||||
Reference in New Issue
Block a user