mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2026-01-21 23:54:33 +01:00
Android Wear support added to UART profile
This commit is contained in:
@@ -32,9 +32,9 @@ 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.BloodPressureMeasurementParser;
|
||||
import no.nordicsemi.android.nrftoolbox.parser.IntermediateCuffPressureParser;
|
||||
import no.nordicsemi.android.nrftoolbox.profile.BleManager;
|
||||
|
||||
public class BPMManager extends BleManager<BPMManagerCallbacks> {
|
||||
/** Blood Pressure service UUID */
|
||||
|
||||
@@ -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<CSCService.CSCBinder> {
|
||||
|
||||
@@ -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<CSCManagerCallbacks> {
|
||||
/** Cycling Speed and Cadence service UUID */
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.</li>
|
||||
* <li>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.</li>
|
||||
* <li>Afterwards, the manager initializes the device using given queue of commands. See {@link BleManagerGattCallback#initGatt(android.bluetooth.BluetoothGatt)} method for more details.</li>
|
||||
* <li>Afterwards, the manager initializes the device using given queue of commands. See {@link BleManagerGattCallback#initGatt(BluetoothGatt)} method for more details.</li>
|
||||
* <li>When initialization complete, the {@link BleManagerCallbacks#onDeviceReady()} callback is called.</li>
|
||||
* </ol>The manager also is responsible for parsing the Battery Level values and calling {@link BleManagerCallbacks#onBatteryValueReceived(int)} method.</p>
|
||||
* <p>Events from all profiles are being logged into the nRF Logger application,
|
||||
@@ -830,7 +830,7 @@ public abstract class BleManager<E extends BleManagerCallbacks> {
|
||||
final Queue<Request> 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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<RSCManagerCallbacks> {
|
||||
private static final byte INSTANTANEOUS_STRIDE_LENGTH_PRESENT = 0x01; // 1 bit
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<UARTService.UARTBinder> 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<UARTService.UAR
|
||||
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
mDatabaseHelper = new DatabaseHelper(this);
|
||||
ensureFirstConfiguration(mDatabaseHelper);
|
||||
mConfigurationsAdapter = new UARTConfigurationsAdapter(this, this, mDatabaseHelper.getServerConfigurationsNames());
|
||||
mConfigurationsAdapter = new UARTConfigurationsAdapter(this, this, mDatabaseHelper.getConfigurationsNames());
|
||||
|
||||
// Initialize Wearable synchronizer
|
||||
mWearableSynchronizer = UARTConfigurationSynchronizer.from(this, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when Google API Client connects to Wearable.API.
|
||||
*/
|
||||
@Override
|
||||
public void onConnected(final Bundle bundle) {
|
||||
if (!mPreferences.getBoolean(PREFS_WEAR_SYNCED, false)) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Cursor cursor = mDatabaseHelper.getConfigurations();
|
||||
try {
|
||||
while (cursor.moveToNext()) {
|
||||
final long id = cursor.getLong(0 /* _ID */);
|
||||
try {
|
||||
final String xml = cursor.getString(2 /* XML */);
|
||||
final Format format = new Format(new HyphenStyle());
|
||||
final Serializer serializer = new Persister(format);
|
||||
final UartConfiguration configuration = serializer.read(UartConfiguration.class, xml);
|
||||
mWearableSynchronizer.onConfigurationAddedOrEdited(id, configuration).await();
|
||||
} catch (final Exception e) {
|
||||
Log.w(TAG, "Deserializing configuration with id " + id + " failed", e);
|
||||
}
|
||||
}
|
||||
mPreferences.edit().putBoolean(PREFS_WEAR_SYNCED, true).apply();
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called then Google API client connection was suspended.
|
||||
* @param cause the cause of suspension
|
||||
*/
|
||||
@Override
|
||||
public void onConnectionSuspended(final int cause) {
|
||||
// dp nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mWearableSynchronizer.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -322,13 +382,18 @@ public class UARTActivity extends BleProfileServiceReadyActivity<UARTService.UAR
|
||||
}
|
||||
case R.id.action_remove: {
|
||||
mDatabaseHelper.removeDeletedServerConfigurations(); // just to be sure nothing has left
|
||||
mDatabaseHelper.deleteConfiguration(name);
|
||||
final UartConfiguration removedConfiguration = mConfiguration;
|
||||
final long id = mDatabaseHelper.deleteConfiguration(name);
|
||||
if (id >= 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<UARTService.UAR
|
||||
final String xml = writer.toString();
|
||||
|
||||
final long id = mDatabaseHelper.addConfiguration(name, xml);
|
||||
mWearableSynchronizer.onConfigurationAddedOrEdited(id, configuration);
|
||||
refreshConfigurations();
|
||||
selectConfiguration(mConfigurationsAdapter.getItemPosition(id));
|
||||
} catch (final Exception e) {
|
||||
@@ -548,6 +614,7 @@ public class UARTActivity extends BleProfileServiceReadyActivity<UARTService.UAR
|
||||
final String xml = writer.toString();
|
||||
|
||||
mDatabaseHelper.renameConfiguration(oldName, newName, xml);
|
||||
mWearableSynchronizer.onConfigurationAddedOrEdited(mPreferences.getLong(PREFS_CONFIGURATION, 0), mConfiguration);
|
||||
refreshConfigurations();
|
||||
} catch (final Exception e) {
|
||||
Log.e(TAG, "Error while renaming configuration", e);
|
||||
@@ -555,7 +622,7 @@ public class UARTActivity extends BleProfileServiceReadyActivity<UARTService.UAR
|
||||
}
|
||||
|
||||
private void refreshConfigurations() {
|
||||
mConfigurationsAdapter.swapCursor(mDatabaseHelper.getServerConfigurationsNames());
|
||||
mConfigurationsAdapter.swapCursor(mDatabaseHelper.getConfigurationsNames());
|
||||
mConfigurationsAdapter.notifyDataSetChanged();
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
@@ -634,6 +701,7 @@ public class UARTActivity extends BleProfileServiceReadyActivity<UARTService.UAR
|
||||
final String xml = writer.toString();
|
||||
|
||||
mDatabaseHelper.updateConfiguration(configuration.getName(), xml);
|
||||
mWearableSynchronizer.onConfigurationAddedOrEdited(mPreferences.getLong(PREFS_CONFIGURATION, 0), configuration);
|
||||
} catch (final Exception e) {
|
||||
Log.e(TAG, "Error while creating a new configuration", e);
|
||||
}
|
||||
@@ -659,6 +727,7 @@ public class UARTActivity extends BleProfileServiceReadyActivity<UARTService.UAR
|
||||
final String name = configuration.getName();
|
||||
if (!mDatabaseHelper.configurationExists(name)) {
|
||||
final long id = mDatabaseHelper.addConfiguration(name, xml);
|
||||
mWearableSynchronizer.onConfigurationAddedOrEdited(id, configuration);
|
||||
refreshConfigurations();
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -29,8 +29,17 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.wearable.MessageApi;
|
||||
import com.google.android.gms.wearable.Node;
|
||||
import com.google.android.gms.wearable.NodeApi;
|
||||
import com.google.android.gms.wearable.Wearable;
|
||||
|
||||
import no.nordicsemi.android.log.ILogSession;
|
||||
import no.nordicsemi.android.log.Logger;
|
||||
@@ -38,23 +47,32 @@ 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;
|
||||
import no.nordicsemi.android.nrftoolbox.wearable.common.Constants;
|
||||
|
||||
public class UARTService extends BleProfileService implements UARTManagerCallbacks {
|
||||
private static final String TAG = "UARTService";
|
||||
|
||||
public static final String BROADCAST_UART_TX = "no.nordicsemi.android.nrftoolbox.uart.BROADCAST_UART_TX";
|
||||
public static final String BROADCAST_UART_RX = "no.nordicsemi.android.nrftoolbox.uart.BROADCAST_UART_RX";
|
||||
public static final String EXTRA_DATA = "no.nordicsemi.android.nrftoolbox.uart.EXTRA_DATA";
|
||||
|
||||
/** A broadcast message with this action and the message in {@link Intent#EXTRA_TEXT} will be sent t the UART device. */
|
||||
private final static String ACTION_SEND = "no.nordicsemi.android.nrftoolbox.uart.ACTION_SEND";
|
||||
public final static String ACTION_SEND = "no.nordicsemi.android.nrftoolbox.uart.ACTION_SEND";
|
||||
/** A broadcast message with this action is triggered when a message is received from the UART device. */
|
||||
private final static String ACTION_RECEIVE = "no.nordicsemi.android.nrftoolbox.uart.ACTION_RECEIVE";
|
||||
/** Action send when user press the DISCONNECT button on the notification. */
|
||||
private final static String ACTION_DISCONNECT = "no.nordicsemi.android.nrftoolbox.uart.ACTION_DISCONNECT";
|
||||
public final static String ACTION_DISCONNECT = "no.nordicsemi.android.nrftoolbox.uart.ACTION_DISCONNECT";
|
||||
/** A source of an action. */
|
||||
public final static String EXTRA_SOURCE = "no.nordicsemi.android.nrftoolbox.uart.EXTRA_SOURCE";
|
||||
public final static int SOURCE_NOTIFICATION = 0;
|
||||
public final static int SOURCE_WEARABLE = 1;
|
||||
public final static int SOURCE_3RD_PARTY = 2;
|
||||
|
||||
private final static int NOTIFICATION_ID = 349; // random
|
||||
private final static int OPEN_ACTIVITY_REQ = 67; // random
|
||||
private final static int DISCONNECT_REQ = 97; // random
|
||||
|
||||
private GoogleApiClient mGoogleApiClient;
|
||||
private UARTManager mManager;
|
||||
|
||||
private final LocalBinder mBinder = new UARTBinder();
|
||||
@@ -87,6 +105,11 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
|
||||
registerReceiver(mDisconnectActionBroadcastReceiver, new IntentFilter(ACTION_DISCONNECT));
|
||||
registerReceiver(mIntentBroadcastReceiver, new IntentFilter(ACTION_SEND));
|
||||
|
||||
mGoogleApiClient = new GoogleApiClient.Builder(this)
|
||||
.addApi(Wearable.API)
|
||||
.build();
|
||||
mGoogleApiClient.connect();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -96,6 +119,8 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
unregisterReceiver(mDisconnectActionBroadcastReceiver);
|
||||
unregisterReceiver(mIntentBroadcastReceiver);
|
||||
|
||||
mGoogleApiClient.disconnect();
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@@ -117,6 +142,35 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
mManager.setLogger(getLogSession());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceConnected() {
|
||||
super.onDeviceConnected();
|
||||
sendMessageToWearables(Constants.UART.DEVICE_CONNECTED, notNull(getDeviceName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean stopWhenDisconnected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceDisconnected() {
|
||||
super.onDeviceDisconnected();
|
||||
sendMessageToWearables(Constants.UART.DEVICE_DISCONNECTED, notNull(getDeviceName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLinklossOccur() {
|
||||
super.onLinklossOccur();
|
||||
sendMessageToWearables(Constants.UART.DEVICE_LINKLOSS, notNull(getDeviceName()));
|
||||
}
|
||||
|
||||
private String notNull(final String name) {
|
||||
if (!TextUtils.isEmpty(name))
|
||||
return name;
|
||||
return getString(R.string.not_available);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataReceived(final String data) {
|
||||
Logger.a(getLogSession(), "\"" + data + "\" received");
|
||||
@@ -140,6 +194,37 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the given message to all connected wearables. If the path is equal to {@link Constants.UART#DEVICE_DISCONNECTED} the service will be stopped afterwards.
|
||||
* @param path message path
|
||||
* @param message the message
|
||||
*/
|
||||
private void sendMessageToWearables(final @NonNull String path, final @NonNull String message) {
|
||||
if(mGoogleApiClient.isConnected()) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
|
||||
for(Node node : nodes.getNodes()) {
|
||||
Logger.v(getLogSession(), "[WEAR] Sending message '" + path + "' to " + node.getDisplayName());
|
||||
final MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(mGoogleApiClient, node.getId(), path, message.getBytes()).await();
|
||||
if(result.getStatus().isSuccess()){
|
||||
Logger.i(getLogSession(), "[WEAR] Message sent");
|
||||
} else {
|
||||
Logger.w(getLogSession(), "[WEAR] Sending message failed: " + result.getStatus().getStatusMessage());
|
||||
Log.w(TAG, "Failed to send " + path + " to " + node.getDisplayName());
|
||||
}
|
||||
}
|
||||
if (Constants.UART.DEVICE_DISCONNECTED.equals(path))
|
||||
stopService();
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
if (Constants.UART.DEVICE_DISCONNECTED.equals(path))
|
||||
stopService();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the notification
|
||||
*
|
||||
@@ -155,6 +240,7 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
final Intent targetIntent = new Intent(this, UARTActivity.class);
|
||||
|
||||
final Intent disconnect = new Intent(ACTION_DISCONNECT);
|
||||
disconnect.putExtra(EXTRA_SOURCE, SOURCE_NOTIFICATION);
|
||||
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
|
||||
@@ -185,7 +271,15 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
private final BroadcastReceiver mDisconnectActionBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent intent) {
|
||||
Logger.i(getLogSession(), "[Notification] Disconnect action pressed");
|
||||
final int source = intent.getIntExtra(EXTRA_SOURCE, SOURCE_NOTIFICATION);
|
||||
switch (source) {
|
||||
case SOURCE_NOTIFICATION:
|
||||
Logger.i(getLogSession(), "[Notification] Disconnect action pressed");
|
||||
break;
|
||||
case SOURCE_WEARABLE:
|
||||
Logger.i(getLogSession(), "[WEAR] '" + Constants.ACTION_DISCONNECT + "' message received");
|
||||
break;
|
||||
}
|
||||
if (isConnected())
|
||||
getBinder().disconnect();
|
||||
else
|
||||
@@ -210,7 +304,16 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
}
|
||||
|
||||
if (message != null) {
|
||||
Logger.i(getLogSession(), "[Broadcast] " + ACTION_SEND + " broadcast received with data: \"" + message + "\"");
|
||||
final int source = intent.getIntExtra(EXTRA_SOURCE, SOURCE_3RD_PARTY);
|
||||
switch (source) {
|
||||
case SOURCE_WEARABLE:
|
||||
Logger.i(getLogSession(), "[WEAR] '" + Constants.UART.COMMAND + "' message received with data: \"" + message + "\"");
|
||||
break;
|
||||
case SOURCE_3RD_PARTY:
|
||||
default:
|
||||
Logger.i(getLogSession(), "[Broadcast] " + ACTION_SEND + " broadcast received with data: \"" + message + "\"");
|
||||
break;
|
||||
}
|
||||
mManager.send(message);
|
||||
return;
|
||||
}
|
||||
@@ -222,5 +325,4 @@ public class UARTService extends BleProfileService implements UARTManagerCallbac
|
||||
Logger.i(getLogSession(), "[Broadcast] " + ACTION_SEND + " broadcast received incompatible data type. Only String and int are supported.");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public class DatabaseHelper {
|
||||
private static final String[] ID_PROJECTION = new String[] { BaseColumns._ID };
|
||||
private static final String[] NAME_PROJECTION = new String[] { BaseColumns._ID, NameColumns.NAME };
|
||||
private static final String[] XML_PROJECTION = new String[] { BaseColumns._ID, ConfigurationContract.Configuration.XML };
|
||||
private static final String[] CONFIGURATION_PROJECTION = new String[] { BaseColumns._ID, NameColumns.NAME, ConfigurationContract.Configuration.XML };
|
||||
|
||||
private static final String ID_SELECTION = BaseColumns._ID + "=?";
|
||||
private static final String NAME_SELECTION = NameColumns.NAME + "=?";
|
||||
@@ -72,11 +73,19 @@ public class DatabaseHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all saved configurations.
|
||||
* @return cursor
|
||||
*/
|
||||
public Cursor getConfigurations() {
|
||||
return mDatabase.query(Tables.CONFIGURATIONS, CONFIGURATION_PROJECTION, NOT_DELETED_SELECTION, null, null, null, ConfigurationContract.Configuration.NAME + " ASC");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of names of all saved configurations.
|
||||
* @return cursor
|
||||
*/
|
||||
public Cursor getServerConfigurationsNames() {
|
||||
public Cursor getConfigurationsNames() {
|
||||
return mDatabase.query(Tables.CONFIGURATIONS, NAME_PROJECTION, NOT_DELETED_SELECTION, null, null, null, ConfigurationContract.Configuration.NAME + " ASC");
|
||||
}
|
||||
|
||||
@@ -132,26 +141,50 @@ public class DatabaseHelper {
|
||||
/**
|
||||
* Marks the configuration with given name as deleted. If may be restored or removed permanently afterwards.
|
||||
* @param name the configuration name
|
||||
* @return number of rows affected
|
||||
* @return id of the deleted configuration
|
||||
*/
|
||||
public int deleteConfiguration(final String name) {
|
||||
public long deleteConfiguration(final String name) {
|
||||
mSingleArg[0] = name;
|
||||
|
||||
final ContentValues values = mValues;
|
||||
values.clear();
|
||||
values.put(ConfigurationContract.Configuration.DELETED, 1);
|
||||
return mDatabase.update(Tables.CONFIGURATIONS, values, NAME_SELECTION, mSingleArg);
|
||||
mDatabase.update(Tables.CONFIGURATIONS, values, NAME_SELECTION, mSingleArg);
|
||||
|
||||
final Cursor cursor = mDatabase.query(Tables.CONFIGURATIONS, ID_PROJECTION, NAME_SELECTION, mSingleArg, null, null, null);
|
||||
try {
|
||||
if (cursor.moveToNext())
|
||||
return cursor.getLong(0 /* _ID */);
|
||||
return -1;
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public int removeDeletedServerConfigurations() {
|
||||
return mDatabase.delete(Tables.CONFIGURATIONS, DELETED_SELECTION, null);
|
||||
}
|
||||
|
||||
public int restoreDeletedServerConfigurations() {
|
||||
/**
|
||||
* Restores deleted configuration. Returns the ID of the first one.
|
||||
* @return the DI of the restored configuration.
|
||||
*/
|
||||
public long restoreDeletedServerConfiguration(final String name) {
|
||||
mSingleArg[0] = name;
|
||||
|
||||
final ContentValues values = mValues;
|
||||
values.clear();
|
||||
values.put(ConfigurationContract.Configuration.DELETED, 0);
|
||||
return mDatabase.update(Tables.CONFIGURATIONS, values, null, null);
|
||||
mDatabase.update(Tables.CONFIGURATIONS, values, NAME_SELECTION, mSingleArg);
|
||||
|
||||
final Cursor cursor = mDatabase.query(Tables.CONFIGURATIONS, ID_PROJECTION, NAME_SELECTION, mSingleArg, null, null, null);
|
||||
try {
|
||||
if (cursor.moveToNext())
|
||||
return cursor.getLong(0 /* _ID */);
|
||||
return -1;
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.uart.wearable;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.wearable.DataApi;
|
||||
import com.google.android.gms.wearable.DataMap;
|
||||
import com.google.android.gms.wearable.PutDataMapRequest;
|
||||
import com.google.android.gms.wearable.PutDataRequest;
|
||||
import com.google.android.gms.wearable.Wearable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import no.nordicsemi.android.nrftoolbox.wearable.common.Constants;
|
||||
import no.nordicsemi.android.nrftoolbox.uart.domain.Command;
|
||||
import no.nordicsemi.android.nrftoolbox.uart.domain.UartConfiguration;
|
||||
|
||||
public class UARTConfigurationSynchronizer {
|
||||
private static final String WEAR_URI_PREFIX = "wear:"; // no / at the end as the path already has it
|
||||
|
||||
private static UARTConfigurationSynchronizer mInstance;
|
||||
private GoogleApiClient mGoogleApiClient;
|
||||
|
||||
/**
|
||||
* Initializes the synchronizer.
|
||||
* @param context the activity context
|
||||
* @param listener the connection callbacks listener
|
||||
*/
|
||||
public static UARTConfigurationSynchronizer from(final Context context, final GoogleApiClient.ConnectionCallbacks listener) {
|
||||
if (mInstance == null)
|
||||
mInstance = new UARTConfigurationSynchronizer();
|
||||
|
||||
mInstance.init(context, listener);
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
private UARTConfigurationSynchronizer() {
|
||||
// private constructor
|
||||
}
|
||||
|
||||
private void init(final Context context, final GoogleApiClient.ConnectionCallbacks listener) {
|
||||
if (mGoogleApiClient != null)
|
||||
return;
|
||||
|
||||
mGoogleApiClient = new GoogleApiClient.Builder(context)
|
||||
.addApi(Wearable.API)
|
||||
.addConnectionCallbacks(listener)
|
||||
.build();
|
||||
mGoogleApiClient.connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the synchronizer.
|
||||
*/
|
||||
public void close() {
|
||||
mGoogleApiClient.disconnect();
|
||||
mGoogleApiClient = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronizes the UART configurations between handheld and wearables.
|
||||
* Call this when configuration has been created or altered.
|
||||
* @return pending result
|
||||
*/
|
||||
public PendingResult<DataApi.DataItemResult> 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<DataMap> 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<DataApi.DeleteDataItemsResult> 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);
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* 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.utility;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import no.nordicsemi.android.nrftoolbox.BuildConfig;
|
||||
|
||||
public class DebugLogger {
|
||||
public static void v(final String tag, final String text) {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.v(tag, text);
|
||||
}
|
||||
|
||||
public static void d(final String tag, final String text) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(tag, text);
|
||||
}
|
||||
}
|
||||
|
||||
public static void i(final String tag, final String text) {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.i(tag, text);
|
||||
}
|
||||
|
||||
public static void w(final String tag, final String text) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.w(tag, text);
|
||||
}
|
||||
}
|
||||
|
||||
public static void e(final String tag, final String text) {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.e(tag, text);
|
||||
}
|
||||
|
||||
public static void e(final String tag, final String text, final Throwable e) {
|
||||
if (BuildConfig.DEBUG)
|
||||
Log.e(tag, text, e);
|
||||
}
|
||||
|
||||
public static void wtf(final String tag, final String text) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.wtf(tag, text);
|
||||
}
|
||||
}
|
||||
|
||||
public static void wtf(final String tag, final String text, final Throwable e) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.wtf(tag, text, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user