Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.getpebble.android.kit;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.Base64;
import android.util.Log;
import com.getpebble.android.kit.Constants.*;
import com.getpebble.android.kit.util.PebbleDictionary;
import com.google.common.primitives.UnsignedInteger;
import org.json.JSONException;
import java.util.UUID;
import static com.getpebble.android.kit.Constants.*;
/**
* A helper class providing methods for interacting with third-party Pebble Smartwatch applications. Pebble-enabled
* Android applications may use this class to assist in sending/receiving data between the watch and the phone.
*/
public final class PebbleKit {
/**
* The Constant NAME_MAX_LENGTH.
*/
private static final int NAME_MAX_LENGTH = 32;
/**
* The Constant ICON_MAX_DIMENSIONS.
*/
private static final int ICON_MAX_DIMENSIONS = 32;
/**
* Instantiates a new pebble kit.
*/
private PebbleKit() {
}
/**
* Send a message to the connected Pebble to "customize" a built-in PebbleKit watch-app. This is intended to allow
* third-party Android applications to apply custom branding (both name & icon) on the watch without needing to
* distribute a complete watch-app.
*
* @param context
* The context used to send the broadcast. (Protip: pass in the ApplicationContext here.)
* @param appType
* The watch-app to be configured. Options are either
* @param name
* The custom name to be applied to the watch-app. Names must be less than 32 characters in length.
* @param icon
* The custom icon to be applied to the watch-app. Icons must be black-and-white bitmaps no larger than 32px
* in either dimension.
*
* @throws IllegalArgumentException
* Thrown if the specified name or icon are invalid. {@link PebbleAppType#SPORTS} or {@link
* PebbleAppType#GOLF}.
*/
public static void customizeWatchApp(final Context context, final PebbleAppType appType,
final String name, final Bitmap icon) throws IllegalArgumentException {
if (appType == null) {
throw new IllegalArgumentException("app type cannot be null");
}
if (name.length() > NAME_MAX_LENGTH) {
throw new IllegalArgumentException(String.format(
"app name exceeds maximum length (%d)", NAME_MAX_LENGTH));
}
if (icon.getHeight() > ICON_MAX_DIMENSIONS || icon.getWidth() > ICON_MAX_DIMENSIONS) {
throw new IllegalArgumentException(String.format(
"app icon exceeds maximum dimensions (32px x 32px); got (%dpx x %dpx)",
icon.getWidth(), icon.getHeight()));
}
final Intent customizeAppIntent = new Intent(INTENT_APP_CUSTOMIZE);
customizeAppIntent.putExtra(CUST_APP_TYPE, appType.ord);
customizeAppIntent.putExtra(CUST_NAME, name);
customizeAppIntent.putExtra(CUST_ICON, icon);
context.sendBroadcast(customizeAppIntent);
}
/**
* Synchronously query the Pebble application to see if an active Bluetooth connection to a watch currently exists.
*
* @param context
* The Android context used to perform the query.
*
* Protip: You probably want to use your ApplicationContext here.
*
* @return true if an active connection to the watch currently exists, otherwise false. This method will also return
* false if the Pebble application is not installed on the user's handset.
*/
public static boolean isWatchConnected(final Context context) {
Cursor c =
context.getContentResolver().query(
Uri.parse("content://com.getpebble.android.provider/state"), null, null,
null, null);
if (c == null || !c.moveToNext()) {
return false;
}
return c.getInt(KIT_STATE_COLUMN_CONNECTED) == 1;
}
/**
* Synchronously query the Pebble application to see if the connected watch is running a firmware version that
* supports PebbleKit messages.
*
* @param context
* The Android context used to perform the query.
*
* Protip: You probably want to use your ApplicationContext here.
*
* @return true if the watch supports PebbleKit messages, otherwise false. This method will always return false if
* no Pebble is currently connected to the handset.
*/
public static boolean areAppMessagesSupported(final Context context) {
Cursor c =
context.getContentResolver().query(
Uri.parse("content://com.getpebble.android.provider/state"), null, null,
null, null);
if (c == null || !c.moveToNext()) {
return false;
}
return c.getInt(KIT_STATE_COLUMN_APPMSG_SUPPORT) == 1;
}
/**
* Get the version information of the firmware running on a connected watch.
*
* @param context
* The Android context used to perform the query.
*
* Protip: You probably want to use your ApplicationContext here.
*
* @return null if the watch is disconnected or we can't get the version. Otherwise,
* a FirmwareVersionObject containing info on the watch FW version
*/
public static FirmwareVersionInfo getWatchFWVersion(final Context context) {
Cursor c =
context.getContentResolver().query(
Uri.parse("content://com.getpebble.android.provider/state"), null, null,
null, null);
if (c == null || !c.moveToNext()) {
return null;
}
int majorVersion = c.getInt(KIT_STATE_COLUMN_VERSION_MAJOR);
int minorVersion = c.getInt(KIT_STATE_COLUMN_VERSION_MINOR);
int pointVersion = c.getInt(KIT_STATE_COLUMN_VERSION_POINT);
String versionTag = c.getString(KIT_STATE_COLUMN_VERSION_TAG);
return new FirmwareVersionInfo(majorVersion, minorVersion, pointVersion, versionTag);
}
/**
* Synchronously query the Pebble application to see if the connected watch is running a firmware version that
* supports PebbleKit data logging.
*
* @param context
* The Android context used to perform the query.
*
* Protip: You probably want to use your ApplicationContext here.
*
* @return true if the watch supports PebbleKit messages, otherwise false. This method will always return false if
* no Pebble is currently connected to the handset.
*/
public static boolean isDataLoggingSupported(final Context context) {
Cursor c =
context.getContentResolver().query(
Uri.parse("content://com.getpebble.android.provider/state"),
null, null, null, null);
if (c == null || !c.moveToNext()) {
return false;
}
return c.getInt(KIT_STATE_COLUMN_DATALOGGING_SUPPORT) == 1;
}
/**
* Send a message to the connected Pebble to launch an application identified by a UUID. If another application is
* currently running it will be terminated and the new application will be brought to the foreground.
*
* @param context
* The context used to send the broadcast.
* @param watchappUuid
* A UUID uniquely identifying the target application. UUIDs for the stock PebbleKit applications are
* available in {@link Constants}.
*
* @throws IllegalArgumentException
* Thrown if the specified UUID is invalid.
*/
public static void startAppOnPebble(final Context context, final UUID watchappUuid)
throws IllegalArgumentException {
if (watchappUuid == null) {
throw new IllegalArgumentException("uuid cannot be null");
}
final Intent startAppIntent = new Intent(INTENT_APP_START);
startAppIntent.putExtra(APP_UUID, watchappUuid);
context.sendBroadcast(startAppIntent);
}
/**
* Send a message to the connected Pebble to close an application identified by a UUID. If this application is not
* currently running, the message is ignored.
*
* @param context
* The context used to send the broadcast.
* @param watchappUuid
* A UUID uniquely identifying the target application. UUIDs for the stock kit applications are available in
* {@link Constants}.
*
* @throws IllegalArgumentException
* Thrown if the specified UUID is invalid.
*/
public static void closeAppOnPebble(final Context context, final UUID watchappUuid)
throws IllegalArgumentException {
if (watchappUuid == null) {
throw new IllegalArgumentException("uuid cannot be null");
}
final Intent stopAppIntent = new Intent(INTENT_APP_STOP);
stopAppIntent.putExtra(APP_UUID, watchappUuid);
context.sendBroadcast(stopAppIntent);
}
/**
* Send one-or-more key-value pairs to the watch-app identified by the provided UUID. This is the primary method for
* sending data from the phone to a connected Pebble.
*
* The watch-app and phone-app must agree of the set and type of key-value pairs being exchanged. Type mismatches or
* missing keys will cause errors on the receiver's end.
*
* @param context
* The context used to send the broadcast.
* @param watchappUuid
* A UUID uniquely identifying the target application. UUIDs for the stock kit applications are available in
* {@link Constants}.
* @param data
* A dictionary containing one-or-more key-value pairs. For more information about the types of data that
* can be stored, see {@link PebbleDictionary}.
*
* @throws IllegalArgumentException
* Thrown in the specified PebbleDictionary or UUID is invalid.
*/
public static void sendDataToPebble(final Context context, final UUID watchappUuid,
final PebbleDictionary data) throws IllegalArgumentException {
sendDataToPebbleWithTransactionId(context, watchappUuid, data, -1);
}
/**
* Send one-or-more key-value pairs to the watch-app identified by the provided UUID.
*
* The watch-app and phone-app must agree of the set and type of key-value pairs being exchanged. Type mismatches or
* missing keys will cause errors on the receiver's end.
*
* @param context
* The context used to send the broadcast.
* @param watchappUuid
* A UUID uniquely identifying the target application. UUIDs for the stock kit applications are available in
* {@link Constants}.
* @param data
* A dictionary containing one-or-more key-value pairs. For more information about the types of data that
* can be stored, see {@link PebbleDictionary}.
* @param transactionId
* An integer uniquely identifying the transaction. This can be used to correlate messages sent to the
* Pebble and ACK/NACKs received from the Pebble.
*
* @throws IllegalArgumentException
* Thrown in the specified PebbleDictionary or UUID is invalid.
*/
public static void sendDataToPebbleWithTransactionId(final Context context,
final UUID watchappUuid, final PebbleDictionary data, final int transactionId)
throws IllegalArgumentException {
if (watchappUuid == null) {
throw new IllegalArgumentException("uuid cannot be null");
}
if (data == null) {
throw new IllegalArgumentException("data cannot be null");
}
if (data.size() == 0) {
return;
}
final Intent sendDataIntent = new Intent(INTENT_APP_SEND);
sendDataIntent.putExtra(APP_UUID, watchappUuid);
sendDataIntent.putExtra(TRANSACTION_ID, transactionId);
sendDataIntent.putExtra(MSG_DATA, data.toJsonString());
context.sendBroadcast(sendDataIntent);
}
/**
* Send a message to the connected watch acknowledging the receipt of a PebbleDictionary. To avoid protocol timeouts
* on the watch, applications must ACK or NACK all received messages.
*
* @param context
* The context used to send the broadcast.
* @param transactionId
* The transaction id of the message in which the data was received. Valid transaction IDs are between (0,
* 255).
*
* @throws IllegalArgumentException
* Thrown if an invalid transaction id is specified.
*/
public static void sendAckToPebble(final Context context, final int transactionId)
throws IllegalArgumentException {
if ((transactionId & ~0xff) != 0) {
throw new IllegalArgumentException(String.format(
"transaction id must be between (0, 255); got '%d'", transactionId));
}
final Intent ackIntent = new Intent(INTENT_APP_ACK);
ackIntent.putExtra(TRANSACTION_ID, transactionId);
context.sendBroadcast(ackIntent);
}
/**
* Send a message to the connected watch that the previously sent PebbleDictionary was not received successfully. To
* avoid protocol timeouts on the watch, applications must ACK or NACK all received messages.
*
* @param context
* The context used to send the broadcast.
* @param transactionId
* The transaction id of the message in which the data was received. Valid transaction IDs are between (0,
* 255).
*
* @throws IllegalArgumentException
* Thrown if an invalid transaction id is specified.
*/
public static void sendNackToPebble(final Context context, final int transactionId)
throws IllegalArgumentException {
if ((transactionId & ~0xff) != 0) {
throw new IllegalArgumentException(String.format(
"transaction id must be between (0, 255); got '%d'", transactionId));
}
final Intent nackIntent = new Intent(INTENT_APP_NACK);
nackIntent.putExtra(TRANSACTION_ID, transactionId);
context.sendBroadcast(nackIntent);
}
/**
* A convenience function to assist in programatically registering a broadcast receiver for the 'CONNECTED' intent.
*
* To avoid leaking memory, activities registering BroadcastReceivers must unregister them in the
* Activity's {@link android.app.Activity#onPause()} method.
*
* @param context
* The context in which to register the BroadcastReceiver.
* @param receiver
* The receiver to be registered.
*
* @return The registered receiver.
*
* @see Constants#INTENT_PEBBLE_CONNECTED
*/
public static BroadcastReceiver registerPebbleConnectedReceiver(final Context context,
final BroadcastReceiver receiver) {
return registerBroadcastReceiverInternal(context, INTENT_PEBBLE_CONNECTED, receiver);
}
/**
* A convenience function to assist in programatically registering a broadcast receiver for the 'DISCONNECTED'
* intent.
*
* Go avoid leaking memory, activities registering BroadcastReceivers must unregister them in the
* Activity's {@link android.app.Activity#onPause()} method.
*
* @param context
* The context in which to register the BroadcastReceiver.
* @param receiver
* The receiver to be registered.
*
* @return The registered receiver.
*
* @see Constants#INTENT_PEBBLE_DISCONNECTED
*/
public static BroadcastReceiver registerPebbleDisconnectedReceiver(final Context context,
final BroadcastReceiver receiver) {
return registerBroadcastReceiverInternal(context, INTENT_PEBBLE_DISCONNECTED, receiver);
}
/**
* A convenience function to assist in programatically registering a broadcast receiver for the 'RECEIVE' intent.
*
* To avoid leaking memory, activities registering BroadcastReceivers must unregister them in the
* Activity's {@link android.app.Activity#onPause()} method.
*
* @param context
* The context in which to register the BroadcastReceiver.
* @param receiver
* The receiver to be registered.
*
* @return The registered receiver.
*
* @see Constants#INTENT_APP_RECEIVE
*/
public static BroadcastReceiver registerReceivedDataHandler(final Context context,
final PebbleDataReceiver receiver) {
return registerBroadcastReceiverInternal(context, INTENT_APP_RECEIVE, receiver);
}
/**
* A convenience function to assist in programatically registering a broadcast receiver for the 'RECEIVE_ACK'
* intent.
*
* To avoid leaking memory, activities registering BroadcastReceivers must unregister them in the
* Activity's {@link android.app.Activity#onPause()} method.
*
* @param context
* The context in which to register the BroadcastReceiver.
* @param receiver
* The receiver to be registered.
*
* @return The registered receiver.
*
* @see Constants#INTENT_APP_RECEIVE_ACK
*/
public static BroadcastReceiver registerReceivedAckHandler(final Context context,
final PebbleAckReceiver receiver) {
return registerBroadcastReceiverInternal(context, INTENT_APP_RECEIVE_ACK, receiver);
}
/**
* A convenience function to assist in programatically registering a broadcast receiver for the 'RECEIVE_NACK'
* intent.
*
* To avoid leaking memory, activities registering BroadcastReceivers must unregister them in the
* Activity's {@link android.app.Activity#onPause()} method.
*
* @param context
* The context in which to register the BroadcastReceiver.
* @param receiver
* The receiver to be registered.
*
* @return The registered receiver.
*
* @see Constants#INTENT_APP_RECEIVE_NACK
*/
public static BroadcastReceiver registerReceivedNackHandler(final Context context,
final PebbleNackReceiver receiver) {
return registerBroadcastReceiverInternal(context, INTENT_APP_RECEIVE_NACK, receiver);
}
/**
* Register broadcast receiver internal.
*
* @param context
* the context
* @param action
* the action
* @param receiver
* the receiver
*
* @return the broadcast receiver
*/
private static BroadcastReceiver registerBroadcastReceiverInternal(final Context context,
final String action, final BroadcastReceiver receiver) {
if (receiver == null) {
return null;
}
IntentFilter filter = new IntentFilter(action);
context.registerReceiver(receiver, filter);
return receiver;
}
/**
* A special-purpose BroadcastReceiver that makes it easy to handle 'RECEIVE' intents broadcast from pebble.apk.
*/
public static abstract class PebbleDataReceiver extends BroadcastReceiver {
/**
* The subscribed uuid.
*/
private final UUID subscribedUuid;
/**
* Instantiates a new pebble data receiver.
*
* @param subscribedUuid
* the subscribed uuid
*/
protected PebbleDataReceiver(final UUID subscribedUuid) {
this.subscribedUuid = subscribedUuid;
}
/**
* Perform some work on the data received from the connected watch.
*
* @param context
* The BroadcastReceiver's context.
* @param transactionId
* The transaction ID of the message in which the data was received. This is required when ACK/NACKing
* the received message.
* @param data
* A dictionary of one-or-more key-value pairs received from the connected watch.
*/
public abstract void receiveData(final Context context, final int transactionId,
final PebbleDictionary data);
/**
* {@inheritDoc}
*/
@Override
public void onReceive(final Context context, final Intent intent) {
final UUID receivedUuid = (UUID) intent.getSerializableExtra(APP_UUID);
// Pebble-enabled apps are expected to be good citizens and only inspect broadcasts
// containing their UUID
if (!subscribedUuid.equals(receivedUuid)) {
return;
}
final int transactionId = intent.getIntExtra(TRANSACTION_ID, -1);
final String jsonData = intent.getStringExtra(MSG_DATA);
if (jsonData == null || jsonData.isEmpty()) {
return;
}
try {
final PebbleDictionary data = PebbleDictionary.fromJson(jsonData);
receiveData(context, transactionId, data);
} catch (JSONException e) {
e.printStackTrace();
return;
}
}
}
/**
* A special-purpose BroadcastReceiver that makes it easy to handle 'RECEIVE_ACK' intents broadcast from pebble
* .apk.
*/
public static abstract class PebbleAckReceiver extends BroadcastReceiver {
/**
* The subscribed uuid.
*/
private final UUID subscribedUuid;
/**
* Instantiates a new pebble ack receiver.
*
* @param subscribedUuid
* the subscribed uuid
*/
protected PebbleAckReceiver(final UUID subscribedUuid) {
this.subscribedUuid = subscribedUuid;
}
/**
* Handle the ACK received from the connected watch.
*
* @param context
* The BroadcastReceiver's context.
* @param transactionId
* The transaction ID of the message for which the ACK was received. This indicates which message was
* successfully received.
*/
public abstract void receiveAck(final Context context, final int transactionId);
/**
* {@inheritDoc}
*/
@Override
public void onReceive(final Context context, final Intent intent) {
final int transactionId = intent.getIntExtra(TRANSACTION_ID, -1);
receiveAck(context, transactionId);
}
}
/**
* A special-purpose BroadcastReceiver that makes it easy to handle 'RECEIVE_NACK' intents broadcast from pebble
* .apk.
*/
public static abstract class PebbleNackReceiver extends BroadcastReceiver {
/**
* The subscribed uuid.
*/
private final UUID subscribedUuid;
/**
* Instantiates a new pebble nack receiver.
*
* @param subscribedUuid
* the subscribed uuid
*/
protected PebbleNackReceiver(final UUID subscribedUuid) {
this.subscribedUuid = subscribedUuid;
}
/**
* Handle the NACK received from the connected watch.
*
* @param context
* The BroadcastReceiver's context.
* @param transactionId
* The transaction ID of the message for which the NACK was received. This indicates which message was
* not received.
*/
public abstract void receiveNack(final Context context, final int transactionId);
/**
* {@inheritDoc}
*/
@Override
public void onReceive(final Context context, final Intent intent) {
final int transactionId = intent.getIntExtra(TRANSACTION_ID, -1);
receiveNack(context, transactionId);
}
}
/**
* A special-purpose BroadcastReceiver that makes it easy to handle 'DATA_AVAILABLE' data logging intents broadcast from pebble.apk.
*/
public static abstract class PebbleDataLogReceiver extends BroadcastReceiver {
/**
* The subscribed uuid.
*/
private final UUID subscribedUuid;
/**
* The last data ID we've seen. Ignore subsequent intents for this same ID.
*/
private int lastDataId;
/**
* Instantiates a new pebble nack receiver.
*
* @param subscribedUuid
* the subscribed uuid
*/
protected PebbleDataLogReceiver(final UUID subscribedUuid) {
this.subscribedUuid = subscribedUuid;
}
/**
* Handle an UnsignedInteger data unit that was logged the watch and broadcast by pebble.apk.
*
* @param context
* The BroadcastReceiver's context.
* @param logUuid
* The UUID that uniquely identifies a data log.
* @param timestamp
* The timestamp when a data log was first created.
* @param tag
* The user-defined tag for the corresponding data log.
* @param data
* The unit of data that was logged on the watch.
* @throws UnsupportedOperationException
* Thrown if data is received and this handler is not implemented.
*/
public void receiveData(final Context context, UUID logUuid,
final UnsignedInteger timestamp, final UnsignedInteger tag,
final UnsignedInteger data) {
throw new UnsupportedOperationException("UnsignedInteger handler not implemented");
}
/**
* Handle a byte array data unit that was logged the watch and broadcast by pebble.apk.
*
* @param context
* The BroadcastReceiver's context.
* @param logUuid
* The UUID that uniquely identifies a data log.
* @param timestamp
* The timestamp when a data log was first created.
* @param tag
* The user-defined tag for the corresponding data log.
* @param data
* The unit of data that was logged on the watch.
* @throws UnsupportedOperationException
* Thrown if data is received and this handler is not implemented.
*/
public void receiveData(final Context context, UUID logUuid,
final UnsignedInteger timestamp, final UnsignedInteger tag,
final byte[] data) {
throw new UnsupportedOperationException("Byte array handler not implemented");
}
/**
* Handle an int data unit that was logged the watch and broadcast by pebble.apk.
*
* @param context
* The BroadcastReceiver's context.
* @param logUuid
* The UUID that uniquely identifies a data log.
* @param timestamp
* The timestamp when a data log was first created.
* @param tag
* The user-defined tag for the corresponding data log.
* @param data
* The unit of data that was logged on the watch.
* @throws UnsupportedOperationException
* Thrown if data is received and this handler is not implemented.
*/
public void receiveData(final Context context, UUID logUuid,
final UnsignedInteger timestamp, final UnsignedInteger tag, final int data) {
throw new UnsupportedOperationException("int handler not implemented");
}
/**
* Called when a session has been finished on the watch and all data has been transmitted by pebble.apk
*
* @param context
* The BroadcastReceiver's context.
* @param logUuid
* The UUID that uniquely identifies a data log.
* @param timestamp
* The timestamp when a data log was first created.
* @param tag
* The user-defined tag for the corresponding data log.
*/
public void onFinishSession(final Context context, UUID logUuid, final UnsignedInteger timestamp,
final UnsignedInteger tag) {
// Do nothing by default
}
private void handleReceiveDataIntent(final Context context, final Intent intent, final UUID logUuid,
final UnsignedInteger timestamp, final UnsignedInteger tag) {
final int dataId = intent.getIntExtra(PBL_DATA_ID, -1);
if (dataId < 0) throw new IllegalArgumentException();
Log.i("pebble", "DataID: " + dataId + " LastDataID: " + lastDataId);
if (dataId == lastDataId) {
// If we see the same dataId multiple times, just ignore it.
return;
}
final PebbleDataType type = PebbleDataType.fromByte(intent.getByteExtra(PBL_DATA_TYPE, PebbleDataType.INVALID.ord));
if (type == null) throw new IllegalArgumentException();
switch (type) {
case BYTES:
byte[] bytes = Base64.decode(intent.getStringExtra(PBL_DATA_OBJECT), Base64.NO_WRAP);
if (bytes == null) {
throw new IllegalArgumentException();
}
receiveData(context, logUuid, timestamp, tag, bytes);
break;
case UINT:
UnsignedInteger uint = (UnsignedInteger) intent.getSerializableExtra(PBL_DATA_OBJECT);
if (uint == null) {
throw new IllegalArgumentException();
}
receiveData(context, logUuid, timestamp, tag, uint);
break;
case INT:
Integer i = (Integer) intent.getSerializableExtra(PBL_DATA_OBJECT);
if (i == null) {
throw new IllegalArgumentException();
}
receiveData(context, logUuid, timestamp, tag, i.intValue());
break;
default:
throw new IllegalArgumentException("Invalid type:" + type.toString());
}
lastDataId = dataId;
final Intent ackIntent = new Intent(INTENT_DL_ACK_DATA);
ackIntent.putExtra(DATA_LOG_UUID, logUuid);
ackIntent.putExtra(PBL_DATA_ID, dataId);
context.sendBroadcast(ackIntent);
}
private void handleFinishSessionIntent(final Context context, final Intent intent, final UUID logUuid,
final UnsignedInteger timestamp, final UnsignedInteger tag) {
onFinishSession(context, logUuid, timestamp, tag);
}
/**
* {@inheritDoc}
*/
@Override
public void onReceive(final Context context, final Intent intent) {
final UUID receivedUuid = (UUID) intent.getSerializableExtra(APP_UUID);
// Pebble-enabled apps are expected to be good citizens and only inspect broadcasts
// containing their UUID
if (!subscribedUuid.equals(receivedUuid)) {
return;
}
try {
final UUID logUuid;
final UnsignedInteger timestamp;
final UnsignedInteger tag;
logUuid = (UUID) intent.getSerializableExtra(DATA_LOG_UUID);
if (logUuid == null) throw new IllegalArgumentException();
timestamp = (UnsignedInteger) intent.getSerializableExtra(DATA_LOG_TIMESTAMP);
if (timestamp == null) throw new IllegalArgumentException();
tag = (UnsignedInteger) intent.getSerializableExtra(DATA_LOG_TAG);
if (tag == null) throw new IllegalArgumentException();
if (intent.getAction() == INTENT_DL_RECEIVE_DATA) {
handleReceiveDataIntent(context, intent, logUuid, timestamp, tag);
} else if (intent.getAction() == INTENT_DL_FINISH_SESSION) {
handleFinishSessionIntent(context, intent, logUuid, timestamp, tag);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
}
}
}
/**
* A convenience function to assist in programatically registering a broadcast receiver for the 'DATA_AVAILABLE'
* intent.
*
* To avoid leaking memory, activities registering BroadcastReceivers must unregister them in the
* Activity's {@link android.app.Activity#onPause()} method.
*
* @param context
* The context in which to register the BroadcastReceiver.
* @param receiver
* The receiver to be registered.
*
* @return The registered receiver.
*
* @see Constants#INTENT_DL_RECEIVE_DATA
*/
public static BroadcastReceiver registerDataLogReceiver(final Context context,
final PebbleDataLogReceiver receiver) {
IntentFilter filter = new IntentFilter();
filter.addAction(INTENT_DL_RECEIVE_DATA);
filter.addAction(INTENT_DL_FINISH_SESSION);
context.registerReceiver(receiver, filter);
return receiver;
}
/**
* A convenience function to emit an intent to pebble.apk to request the data logs for a particular app. If data
* is available, pebble.apk will advertise the data via 'INTENT_DL_RECEIVE_DATA' intents.
*
* To avoid leaking memory, activities registering BroadcastReceivers must unregister them in the
* Activity's {@link android.app.Activity#onPause()} method.
*
* @param context
* The context in which to register the BroadcastReceiver.
* @param appUuid
* The app for which to request data logs.
*
* @return The registered receiver.
*
* @see Constants#INTENT_DL_RECEIVE_DATA
* @see Constants#INTENT_DL_REQUEST_DATA
*/
public static void requestDataLogsForApp(final Context context, final UUID appUuid) {
final Intent requestIntent = new Intent(INTENT_DL_REQUEST_DATA);
requestIntent.putExtra(APP_UUID, appUuid);
context.sendBroadcast(requestIntent);
}
public static class FirmwareVersionInfo {
private final int major;
private final int minor;
private final int point;
private final String tag;
FirmwareVersionInfo(int major, int minor, int point, String tag) {
this.major = major;
this.minor = minor;
this.point = point;
this.tag = tag;
}
public final int getMajor() {
return major;
}
public final int getMinor() {
return minor;
}
public final int getPoint() {
return point;
}
public final String getTag() {
return tag;
}
}
}