All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.getpebble.android.kit.PebbleKit Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
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; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy