diff --git a/.idea/gradle.xml b/.idea/gradle.xml index c75a99ee..c99df1f6 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -11,6 +11,8 @@ diff --git a/.idea/modules.xml b/.idea/modules.xml index 27665145..bfd895e8 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,9 +3,10 @@ + + - - + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml index ea4ba425..517941ff 100644 --- a/app/app.iml +++ b/app/app.iml @@ -71,9 +71,12 @@ - - + + + + + @@ -92,15 +95,18 @@ - - + + + - - - + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 462efc49..5eb16d6f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,13 +2,14 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion '23.0.0' + buildToolsVersion '23.0.1' + defaultConfig { applicationId "no.nordicsemi.android.nrftoolbox" minSdkVersion 18 targetSdkVersion 23 - versionCode 37 - versionName "1.15.0" + versionCode 39 + versionName "1.16.0" } buildTypes { release { @@ -20,14 +21,17 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:23.0.0' - compile 'com.android.support:design:23.0.0' + compile 'com.google.android.gms:play-services-wearable:7.8.0' + compile 'com.android.support:appcompat-v7:23.0.1' + compile 'com.android.support:design:23.0.1' compile 'no.nordicsemi.android.support.v18:scanner:0.1.1' + compile 'no.nordicsemi.android:log:2.0.0' compile('org.simpleframework:simple-xml:2.7.1') { exclude group: 'stax', module: 'stax-api' exclude group: 'xpp3', module: 'xpp3' } - compile project(':dfu') compile files('libs/achartengine-1.1.0.jar') - compile files('libs/nrf-logger-v2.0.jar') + compile project(':dfu') + compile project(':common') + wearApp project(':wear') } diff --git a/app/libs/nrf-logger-v2.0.jar b/app/libs/nrf-logger-v2.0.jar deleted file mode 100644 index 8d37a964..00000000 Binary files a/app/libs/nrf-logger-v2.0.jar and /dev/null differ diff --git a/app/sources/nrf-logger-v2.0-source.jar b/app/sources/nrf-logger-v2.0-source.jar deleted file mode 100644 index e25ca909..00000000 Binary files a/app/sources/nrf-logger-v2.0-source.jar and /dev/null differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9d4ca83d..859597cf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -37,9 +37,14 @@ + + + + + + + + { /** Blood Pressure service UUID */ diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCActivity.java index 284b396c..d1f4fcaf 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCActivity.java @@ -36,9 +36,9 @@ 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.csc.settings.SettingsActivity; import no.nordicsemi.android.nrftoolbox.csc.settings.SettingsFragment; -import no.nordicsemi.android.nrftoolbox.profile.BleProfileService; import no.nordicsemi.android.nrftoolbox.profile.BleProfileServiceReadyActivity; public class CSCActivity extends BleProfileServiceReadyActivity { diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java index c9c10c26..f705fffc 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCManager.java @@ -32,8 +32,8 @@ import java.util.Queue; import java.util.UUID; import no.nordicsemi.android.log.Logger; -import no.nordicsemi.android.nrftoolbox.parser.CSCMeasurementParser; import no.nordicsemi.android.nrftoolbox.profile.BleManager; +import no.nordicsemi.android.nrftoolbox.parser.CSCMeasurementParser; public class CSCManager extends BleManager { /** Cycling Speed and Cadence service UUID */ diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCService.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCService.java index 89017f35..66b57e73 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCService.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/CSCService.java @@ -37,9 +37,9 @@ import android.support.v7.app.NotificationCompat; import no.nordicsemi.android.log.Logger; import no.nordicsemi.android.nrftoolbox.FeaturesActivity; import no.nordicsemi.android.nrftoolbox.R; -import no.nordicsemi.android.nrftoolbox.csc.settings.SettingsFragment; import no.nordicsemi.android.nrftoolbox.profile.BleManager; import no.nordicsemi.android.nrftoolbox.profile.BleProfileService; +import no.nordicsemi.android.nrftoolbox.csc.settings.SettingsFragment; public class CSCService extends BleProfileService implements CSCManagerCallbacks { private static final String TAG = "CSCService"; diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/settings/SettingsFragment.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/settings/SettingsFragment.java index c9aec844..2349da7c 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/settings/SettingsFragment.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/settings/SettingsFragment.java @@ -69,12 +69,16 @@ public class SettingsFragment extends PreferenceFragment implements DfuSettingsC final boolean disabled = !preferences.getBoolean(SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED, true); if (disabled) { new AlertDialog.Builder(getActivity()).setMessage(R.string.dfu_settings_dfu_number_of_packets_info).setTitle(R.string.dfu_settings_dfu_information) - .setNeutralButton(R.string.ok, null).show(); + .setPositiveButton(R.string.ok, null).show(); } } else if (SETTINGS_NUMBER_OF_PACKETS.equals(key)) { updateNumberOfPacketsSummary(); } else if (SETTINGS_MBR_SIZE.equals(key)) { updateMBRSize(); + } else if (SETTINGS_ASSUME_DFU_NODE.equals(key) && sharedPreferences.getBoolean(key, false)) { + new AlertDialog.Builder(getActivity()).setMessage(R.string.dfu_settings_dfu_assume_dfu_mode_info).setTitle(R.string.dfu_settings_dfu_information) + .setPositiveButton(R.string.ok, null) + .show(); } } @@ -93,7 +97,7 @@ public class SettingsFragment extends PreferenceFragment implements DfuSettingsC final int valueInt = Integer.parseInt(value); if (valueInt > 200) { new AlertDialog.Builder(getActivity()).setMessage(R.string.dfu_settings_dfu_number_of_packets_info).setTitle(R.string.dfu_settings_dfu_information) - .setNeutralButton(R.string.ok, null) + .setPositiveButton(R.string.ok, null) .show(); } } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java index 9f3e6925..f9a9f933 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/gls/GlucoseManager.java @@ -34,10 +34,10 @@ import java.util.Queue; import java.util.UUID; import no.nordicsemi.android.log.Logger; +import no.nordicsemi.android.nrftoolbox.profile.BleManager; import no.nordicsemi.android.nrftoolbox.parser.GlucoseMeasurementContextParser; import no.nordicsemi.android.nrftoolbox.parser.GlucoseMeasurementParser; import no.nordicsemi.android.nrftoolbox.parser.RecordAccessControlPointParser; -import no.nordicsemi.android.nrftoolbox.profile.BleManager; import no.nordicsemi.android.nrftoolbox.utility.DebugLogger; @SuppressWarnings("unused") diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java index 25aafa5e..6c3d826d 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hrs/HRSManager.java @@ -32,9 +32,9 @@ import java.util.UUID; import no.nordicsemi.android.log.Logger; import no.nordicsemi.android.nrftoolbox.R; +import no.nordicsemi.android.nrftoolbox.profile.BleManager; import no.nordicsemi.android.nrftoolbox.parser.BodySensorLocationParser; import no.nordicsemi.android.nrftoolbox.parser.HeartRateMeasurementParser; -import no.nordicsemi.android.nrftoolbox.profile.BleManager; /** * HRSManager class performs BluetoothGatt operations for connection, service discovery, enabling notification and reading characteristics. All operations required to connect to device with BLE HR diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java index d3bcb43b..f1b3507e 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java @@ -36,9 +36,9 @@ import java.text.DecimalFormat; import java.util.UUID; import no.nordicsemi.android.nrftoolbox.R; +import no.nordicsemi.android.nrftoolbox.profile.BleProfileService; import no.nordicsemi.android.nrftoolbox.hts.settings.SettingsActivity; import no.nordicsemi.android.nrftoolbox.hts.settings.SettingsFragment; -import no.nordicsemi.android.nrftoolbox.profile.BleProfileService; import no.nordicsemi.android.nrftoolbox.profile.BleProfileServiceReadyActivity; /** diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java index f0aeae0e..340aaf5a 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManager.java @@ -37,9 +37,9 @@ import android.os.Handler; import java.util.Queue; import java.util.UUID; -import no.nordicsemi.android.error.GattError; import no.nordicsemi.android.log.ILogSession; import no.nordicsemi.android.log.Logger; +import no.nordicsemi.android.nrftoolbox.error.GattError; import no.nordicsemi.android.nrftoolbox.utility.DebugLogger; import no.nordicsemi.android.nrftoolbox.utility.ParserUtils; @@ -52,7 +52,7 @@ import no.nordicsemi.android.nrftoolbox.utility.ParserUtils; * leaving this to the developers. *
  • The manager tries to read the Battery Level characteristic. No matter the result of this operation (for example the Battery Level characteristic may not have the READ property) * it tries to enable Battery Level notifications, to get battery updates from the device.
  • - *
  • Afterwards, the manager initializes the device using given queue of commands. See {@link BleManagerGattCallback#initGatt(android.bluetooth.BluetoothGatt)} method for more details.
  • + *
  • Afterwards, the manager initializes the device using given queue of commands. See {@link BleManagerGattCallback#initGatt(BluetoothGatt)} method for more details.
  • *
  • When initialization complete, the {@link BleManagerCallbacks#onDeviceReady()} callback is called.
  • * The manager also is responsible for parsing the Battery Level values and calling {@link BleManagerCallbacks#onBatteryValueReceived(int)} method.

    *

    Events from all profiles are being logged into the nRF Logger application, @@ -830,7 +830,7 @@ public abstract class BleManager { final Queue requests = mInitQueue; // Get the first request from the queue - final Request request = requests.poll(); + final Request request = requests != null ? requests.poll() : null; // Are we done? if (request == null) { diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManagerCallbacks.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManagerCallbacks.java index c7c4b65e..107d85f3 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManagerCallbacks.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleManagerCallbacks.java @@ -38,7 +38,7 @@ public interface BleManagerCallbacks { public void onDeviceDisconnecting(); /** - * Called when the device has disconnected (when the callback returned {@link BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} with state DISCONNECTED. + * Called when the device has disconnected (when the callback returned {@link BluetoothGattCallback#onConnectionStateChange(BluetoothGatt, int, int)} with state DISCONNECTED. */ public void onDeviceDisconnected(); diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleProfileService.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleProfileService.java index c0253762..578ea16b 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleProfileService.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/profile/BleProfileService.java @@ -35,7 +35,6 @@ import android.widget.Toast; import no.nordicsemi.android.log.ILogSession; import no.nordicsemi.android.log.Logger; -import no.nordicsemi.android.nrftoolbox.R; public abstract class BleProfileService extends Service implements BleManagerCallbacks { @SuppressWarnings("unused") @@ -132,7 +131,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal * * @return the log session */ - protected ILogSession getLogSession() { + public ILogSession getLogSession() { return mLogSession; } } @@ -278,6 +277,15 @@ public abstract class BleProfileService extends Service implements BleManagerCal LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast); } + /** + * This method should return false if the service needs to do some asynchronous work after if has disconnected from the device. + * In that case the {@link #stopService()} method must be called when done. + * @return true (default) to automatically stop the service when device is disconnected. False otherwise. + */ + protected boolean stopWhenDisconnected() { + return true; + } + @Override public void onDeviceDisconnected() { mConnected = false; @@ -288,6 +296,11 @@ public abstract class BleProfileService extends Service implements BleManagerCal broadcast.putExtra(EXTRA_CONNECTION_STATE, STATE_DISCONNECTED); LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast); + if (stopWhenDisconnected()) + stopService(); + } + + protected void stopService() { // user requested disconnection. We must stop the service Logger.v(mLogSession, "Stopping service..."); stopSelf(); @@ -335,7 +348,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal @Override public void onBondingRequired() { - showToast(R.string.bonding); + showToast(no.nordicsemi.android.nrftoolbox.common.R.string.bonding); final Intent broadcast = new Intent(BROADCAST_BOND_STATE); broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDING); @@ -344,7 +357,7 @@ public abstract class BleProfileService extends Service implements BleManagerCal @Override public void onBonded() { - showToast(R.string.bonded); + showToast(no.nordicsemi.android.nrftoolbox.common.R.string.bonded); final Intent broadcast = new Intent(BROADCAST_BOND_STATE); broadcast.putExtra(EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED); diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java index 00f1b4c3..358607a4 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityManager.java @@ -40,8 +40,8 @@ import java.util.Queue; import java.util.UUID; import no.nordicsemi.android.log.Logger; -import no.nordicsemi.android.nrftoolbox.parser.AlertLevelParser; import no.nordicsemi.android.nrftoolbox.profile.BleManager; +import no.nordicsemi.android.nrftoolbox.parser.AlertLevelParser; import no.nordicsemi.android.nrftoolbox.utility.DebugLogger; import no.nordicsemi.android.nrftoolbox.utility.ParserUtils; diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java index a7a7e921..6504b130 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java @@ -32,6 +32,7 @@ import android.media.AudioManager; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; +import android.support.v4.app.NotificationManagerCompat; import android.support.v7.app.NotificationCompat; import no.nordicsemi.android.log.Logger; @@ -232,13 +233,13 @@ public class ProximityService extends BleProfileService implements ProximityMana builder.setContentIntent(pendingIntent); builder.setContentTitle(getString(R.string.app_name)).setContentText(getString(messageResId, getDeviceName())); builder.setSmallIcon(R.drawable.ic_stat_notify_proximity); - builder.setShowWhen(defaults != 0).setDefaults(defaults).setAutoCancel(true).setOngoing(true); + builder.setShowWhen(defaults != 0).setDefaults(defaults).setAutoCancel(true).setOngoing(defaults == 0); // an ongoing notification would not be shown on Android Wear builder.addAction(new NotificationCompat.Action(R.drawable.ic_action_bluetooth, getString(R.string.proximity_notification_action_disconnect), disconnectAction)); if (isConnected()) builder.addAction(new NotificationCompat.Action(R.drawable.ic_stat_notify_proximity, getString(isImmediateAlertOn ? R.string.proximity_action_silentme : R.string.proximity_action_findme), secondAction)); final Notification notification = builder.build(); - final NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + final NotificationManagerCompat nm = NotificationManagerCompat.from(this); nm.notify(NOTIFICATION_ID, notification); } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java index 30e3c454..4c58586a 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java @@ -32,8 +32,8 @@ import java.util.Queue; import java.util.UUID; import no.nordicsemi.android.log.Logger; -import no.nordicsemi.android.nrftoolbox.parser.RSCMeasurementParser; import no.nordicsemi.android.nrftoolbox.profile.BleManager; +import no.nordicsemi.android.nrftoolbox.parser.RSCMeasurementParser; public class RSCManager extends BleManager { private static final byte INSTANTANEOUS_STRIDE_LENGTH_PRESENT = 0x01; // 1 bit diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java index 1c731c78..a8d4f76e 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/template/TemplateManager.java @@ -31,8 +31,8 @@ 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; +import no.nordicsemi.android.nrftoolbox.parser.TemplateParser; /** * Modify to template manager to match your requirements. diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTActivity.java index db731f4e..2625c499 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/uart/UARTActivity.java @@ -37,6 +37,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; +import android.database.Cursor; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.TransitionDrawable; @@ -60,6 +61,8 @@ import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; +import com.google.android.gms.common.api.GoogleApiClient; + import org.simpleframework.xml.Serializer; import org.simpleframework.xml.core.Persister; import org.simpleframework.xml.strategy.Strategy; @@ -84,28 +87,35 @@ import java.io.StringWriter; import java.util.UUID; import no.nordicsemi.android.nrftoolbox.R; -import no.nordicsemi.android.nrftoolbox.dfu.adapter.FileBrowserAppsAdapter; import no.nordicsemi.android.nrftoolbox.profile.BleProfileService; +import no.nordicsemi.android.nrftoolbox.dfu.adapter.FileBrowserAppsAdapter; import no.nordicsemi.android.nrftoolbox.profile.BleProfileServiceReadyActivity; import no.nordicsemi.android.nrftoolbox.uart.database.DatabaseHelper; import no.nordicsemi.android.nrftoolbox.uart.domain.Command; import no.nordicsemi.android.nrftoolbox.uart.domain.UartConfiguration; +import no.nordicsemi.android.nrftoolbox.uart.wearable.UARTConfigurationSynchronizer; import no.nordicsemi.android.nrftoolbox.utility.FileHelper; import no.nordicsemi.android.nrftoolbox.widget.ClosableSpinner; public class UARTActivity extends BleProfileServiceReadyActivity implements UARTInterface, - UARTNewConfigurationDialogFragment.NewConfigurationDialogListener, UARTConfigurationsAdapter.ActionListener, AdapterView.OnItemSelectedListener { + UARTNewConfigurationDialogFragment.NewConfigurationDialogListener, UARTConfigurationsAdapter.ActionListener, AdapterView.OnItemSelectedListener, + GoogleApiClient.ConnectionCallbacks { private final static String TAG = "UARTActivity"; private final static String PREFS_BUTTON_ENABLED = "prefs_uart_enabled_"; private final static String PREFS_BUTTON_COMMAND = "prefs_uart_command_"; private final static String PREFS_BUTTON_ICON = "prefs_uart_icon_"; + /** This preference keeps the ID of the selected configuration. */ private final static String PREFS_CONFIGURATION = "configuration_id"; + /** This preference is set to true when initial data synchronization for wearables has been completed. */ + private final static String PREFS_WEAR_SYNCED = "prefs_uart_synced"; private final static String SIS_EDIT_MODE = "sis_edit_mode"; private final static int SELECT_FILE_REQ = 2678; // random private final static int PERMISSION_REQ = 24; // random, 8-bit + UARTConfigurationSynchronizer mWearableSynchronizer; + /** The current configuration. */ private UartConfiguration mConfiguration; private DatabaseHelper mDatabaseHelper; @@ -162,7 +172,57 @@ public class UARTActivity extends BleProfileServiceReadyActivity= 0) + mWearableSynchronizer.onConfigurationDeleted(id); refreshConfigurations(); final Snackbar snackbar = Snackbar.make(mSlider, R.string.uart_configuration_deleted, Snackbar.LENGTH_INDEFINITE).setAction(R.string.uart_action_undo, new View.OnClickListener() { @Override public void onClick(final View v) { - mDatabaseHelper.restoreDeletedServerConfigurations(); + final long id = mDatabaseHelper.restoreDeletedServerConfiguration(name); + if (id >= 0) + mWearableSynchronizer.onConfigurationAddedOrEdited(id, removedConfiguration); refreshConfigurations(); } }); @@ -521,6 +586,7 @@ public class UARTActivity extends BleProfileServiceReadyActivity onConfigurationAddedOrEdited(final long id, final UartConfiguration configuration) { + if (mGoogleApiClient == null || !mGoogleApiClient.isConnected()) + return null; + + final PutDataMapRequest mapRequest = PutDataMapRequest.create(Constants.UART.CONFIGURATIONS + "/" + id); + final DataMap map = mapRequest.getDataMap(); + map.putString(Constants.UART.Configuration.NAME, configuration.getName()); + final ArrayList commands = new ArrayList<>(UartConfiguration.COMMANDS_COUNT); + for (Command command : configuration.getCommands()) { + if (command != null && command.isActive()) { + final DataMap item = new DataMap(); + item.putInt(Constants.UART.Configuration.Command.ICON_ID, command.getIconIndex()); + item.putString(Constants.UART.Configuration.Command.MESSAGE, command.getCommand()); + commands.add(item); + } + } + map.putDataMapArrayList(Constants.UART.Configuration.COMMANDS, commands); + final PutDataRequest request = mapRequest.asPutDataRequest(); + return Wearable.DataApi.putDataItem(mGoogleApiClient, request); + } + + /** + * Synchronizes the UART configurations between handheld and wearables. + * Call this when configuration has been deleted. + * @return pending result + */ + public PendingResult onConfigurationDeleted(final long id) { + if (mGoogleApiClient == null || !mGoogleApiClient.isConnected()) + return null; + return Wearable.DataApi.deleteDataItems(mGoogleApiClient, id2Uri(id)); + } + + /** + * Creates URI without nodeId. + * @param id the configuration id in the database + * @return Uri that may be used to delete the associated DataMap. + */ + private Uri id2Uri(final long id) { + return Uri.parse(WEAR_URI_PREFIX + Constants.UART.CONFIGURATIONS + "/" + id); + } +} diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/wearable/MainWearableListenerService.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/wearable/MainWearableListenerService.java new file mode 100644 index 00000000..a9d43335 --- /dev/null +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/wearable/MainWearableListenerService.java @@ -0,0 +1,69 @@ +/* + * 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.wearable; + +import android.content.Intent; + +import com.google.android.gms.wearable.MessageEvent; +import com.google.android.gms.wearable.WearableListenerService; + +import no.nordicsemi.android.nrftoolbox.wearable.common.Constants; +import no.nordicsemi.android.nrftoolbox.uart.UARTService; + +/** + * The main listener for messages from Wearable devices. There may be only one such service per application so it has to handle messages from all profiles. + */ +public class MainWearableListenerService extends WearableListenerService { + + @Override + public void onMessageReceived(final MessageEvent messageEvent) { + switch (messageEvent.getPath()) { + case Constants.ACTION_DISCONNECT: { + // A disconnect message was sent. The information which profile should be disconnected is in the data. + final String profile = new String(messageEvent.getData()); + + switch (profile) { + // Currently only UART profile has Wear support + case Constants.UART.PROFILE: { + final Intent disconnectIntent = new Intent(UARTService.ACTION_DISCONNECT); + disconnectIntent.putExtra(UARTService.EXTRA_SOURCE, UARTService.SOURCE_WEARABLE); + sendBroadcast(disconnectIntent); + break; + } + } + break; + } + case Constants.UART.COMMAND: { + final String command = new String(messageEvent.getData()); + + final Intent intent = new Intent(UARTService.ACTION_SEND); + intent.putExtra(UARTService.EXTRA_SOURCE, UARTService.SOURCE_WEARABLE); + intent.putExtra(Intent.EXTRA_TEXT, command); + sendBroadcast(intent); + } + default: + super.onMessageReceived(messageEvent); + break; + } + } +} diff --git a/app/src/main/res/drawable-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-hdpi/ic_launcher.png rename to app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/app/src/main/res/drawable-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-mdpi/ic_launcher.png rename to app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-xhdpi/ic_launcher.png rename to app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from app/src/main/res/drawable-xxhdpi/ic_launcher.png rename to app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cbee8212..55af6d9f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -59,10 +59,7 @@ BONDED DEVICES: AVAILABLE DEVICES: Since Android 6.0 Marshmallow system requires granting access to device\'s location in order to scan for Bluetooth Smart devices. Bluetooth beacons may be used to determine the phone\'s and user\'s location. - - Bonding with the device… - The device is now bonded. - + %1$tR:%1$tS.%1$tL Permission required diff --git a/app/src/main/res/values/strings_dfu.xml b/app/src/main/res/values/strings_dfu.xml index 7d355a8a..d619b440 100644 --- a/app/src/main/res/values/strings_dfu.xml +++ b/app/src/main/res/values/strings_dfu.xml @@ -21,103 +21,106 @@ ~ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> - DFU - nRF Toolbox DFU Proxy - DFU Settings - - DEVICE FIRMWARE UPDATE - -186dp - - Example HEX files were copied to /sdcard/Nordic Semiconductor. - New example HEX files were copied to /sdcard/Nordic Semiconductor. - DFU script files were copied to /sdcard/Nordic Semiconductor. - - APPLICATION - File Name: - File Type: - File Size: - Status: - %d bytes - OK - OK (Init file selected) - File not loaded - Invalid file - Reading file failed - Please, select valid HEX file - Info - - SELECT FILE - - File Browser not found - File browser application has not been found on your device. Would you like to download one? - - Drive - File Manager - Total Commander - Search for others - - - market://details?id=com.google.android.apps.docs - market://details?id=com.rhmsoft.fm - market://details?id=com.ghisler.android.TotalCommander - market://search?q=file manager - - - DEVICE FIRMWARE UPDATE - UPLOAD - CANCEL - - DFU options - Packets receipt notification procedure - Number of packets - MBR size - MBR size (4096 on nRF51, 12288 on nRF52) + DFU + nRF Toolbox DFU Proxy + DFU Settings + + DEVICE FIRMWARE UPDATE + -186dp + + Example HEX files were copied to /sdcard/Nordic Semiconductor. + New example HEX files were copied to /sdcard/Nordic Semiconductor. + DFU script files were copied to /sdcard/Nordic Semiconductor. + + APPLICATION + File Name: + File Type: + File Size: + Status: + %d bytes + OK + OK (Init file selected) + File not loaded + Invalid file + Reading file failed + Please, select valid HEX file + Info + + SELECT FILE + + File Browser not found + File browser application has not been found on your device. Would you like to download one? + + Drive + File Manager + Total Commander + Search for others + + + market://details?id=com.google.android.apps.docs + market://details?id=com.rhmsoft.fm + market://details?id=com.ghisler.android.TotalCommander + market://search?q=file manager + + + DEVICE FIRMWARE UPDATE + UPLOAD + CANCEL + + DFU options + Packets receipt notification procedure + Number of packets + MBR size + MBR size (4096 on nRF51, 12288 on nRF52) Keep bond information - About DFU - DFU documentation on Nordic\'s Developer Zone - Information - During a DFU operation a lot of data packets are being sent to the target. The onCharacteristicWrite(...) + External MCU DFU + Check this switch to ON if you want to perform a DFU operation without jumping to the bootloader mode on a device + with a DFU implementation from SDK 6.1 or older. To achieve the same result on any newer implementation the DFU Version characteristic should return value other than 0x0100. + About DFU + DFU documentation on Nordic\'s Developer Zone + Information + During a DFU operation a lot of data packets are being sent to the target. The onCharacteristicWrite(...) callback in Android API is invoked when the data has been written to the outgoing queue, not when physically sent. Packet receipt notifications were introduced to prevent from overflowing the queue. Depending on the device model, disabling the notifications or setting the value to “high” (> ~300) may make the DFU process freeze at some point. - - Select file type - + + Select file type + Distribution packet (ZIP) Soft Device Bootloader Application - - Init packet - Do you want to select the Init packet file?\n + + Init packet + Do you want to select the Init packet file?\n The Init packet file (*.dat) should contain the device type and revision, application version, list of supported Soft Devices and the firmware CRC in binary format or, with old versions of the DFU bootloader, only the CRC (CRC-CCITT-16). With the new version of the bootloader the extended Init packet is required. - - unnamed device - 0% - %d%% - DEFAULT DFU - Application Uploading - Are you sure to cancel upload? - Application has been transferred successfully. - Uploading of the application has been canceled. - - Select file - A file browser application must be installed on the device before selecting the file. - \n\nThere are number of applications available on Google Play store, e.g. Total Commander or File Manager, that allow you to pick a file from internal memory of the device. To upload - a file from the Internet you may use f.e. Drive or Dropbox application. - \n\nYou will be asked to select an application if more than one is installed. A single application will be launched automatically. - \n\nSince Android KitKat you may use the preinstalled document picker application. Ensure Display advanced devices option is enabled in settings to use the Internal storage. - \n\nSample applications were copied to Nordic Semiconductor folder in the internal storage. - - Starting from nRF Toolbox v1.12 the new Distribution packet (ZIP) is the recommended method for distributing firmware upgrades. + + unnamed device + 0% + %d%% + DEFAULT DFU + Application Uploading + Are you sure to cancel upload? + Application has been transferred successfully. + Uploading of the application has been canceled. + + Select file + A file browser application must be installed on the device before selecting the file. + \n\nThere are number of applications available on Google Play store, e.g. Total Commander or File Manager, that allow you to pick a file from internal memory of the device. To upload + a file from the Internet you may use f.e. Drive or Dropbox application. + \n\nYou will be asked to select an application if more than one is installed. A single application will be launched automatically. + \n\nSince Android KitKat you may use the preinstalled document picker application. Ensure Display advanced devices option is enabled in settings to use the Internal storage. + \n\nSample applications were copied to Nordic Semiconductor folder in the internal storage. + + Starting from nRF Toolbox v1.12 the new Distribution packet (ZIP) is the recommended method for distributing firmware upgrades. You can create the ZIP file using the nrf utility tool, which is part of Master Control Panel 3.8.0+. For more detailed information, see the DFU documentation. \n\nBackward compatibility \nThe nRF Toolbox also supports all old file formats: HEX and BIN files, separate DAT files and ZIP files without a manifest file but with a fixed naming convention: - The Device Firmware Update (DFU) app allows you to update the firmware of your Bluetooth Smart device over-the-air (OTA). + The Device Firmware Update (DFU) app allows you to update the firmware of your Bluetooth Smart device over-the-air (OTA). It is compatible with Nordic Semiconductor nRF51822 or nRF51422 devices with S110 SoftDevice and DFU bootloader enabled. With SoftDevice s110 7.0.0+, the SoftDevice itself and/or a bootloader may also be updated. - \n\nFor more information about the DFU, see the About DFU section in Settings. + \n\nFor more information about the DFU, see the About DFU section in Settings. diff --git a/app/src/main/res/values/strings_uart.xml b/app/src/main/res/values/strings_uart.xml index d4fac1a6..843e4273 100644 --- a/app/src/main/res/values/strings_uart.xml +++ b/app/src/main/res/values/strings_uart.xml @@ -43,7 +43,7 @@ No data to display. Rename configuration - New GATT configuration + New configuration Configuration name Please, provide a unique configuration name: Name must not be empty. diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 075ae4f0..f5c30279 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -120,6 +120,7 @@ @color/actionBarColorDark @color/actionBarColorDark @style/Widget.Button + @style/Widget.AppCompat.Spinner