よりリアルタイムな AppMessage API に加えて、Pebble SDK には Datalogging API も含まれています。これは、最も合理的と思われる時間間隔でデータをバッチで送信できるアプリケーションに有用です(たとえば、ウォッチがスリープに費やす時間を増やすことでバッテリー電力を節約するため)。
Datalogging では、接続が常に存在することを要求する代わりに、接続が利用可能になるまで最大 640 kB のデータをウォッチ上でバッファリングすることもできます。ウォッチが切断されている間にデータがログに記録された場合、次の機会に Pebble モバイルアプリにバッチで転送されて処理されます。その後、データは、それを処理したい PebbleKit Android または PebbleKit iOS (Discontinued) コンパニオンアプリに渡されます。
Datalogging は、DataLoggingItemType enum(バイト配列、符号なし整数、整数)値の 1 つと互換性のある任意の値をキャプチャでき、一般的なソースには加速度計データやコンパスデータが含まれます。
データは、一意の識別子またはタグを持つ「セッション」にログ記録されます。これにより、単一のアプリが異なるタイプのデータ用に複数のデータログを持つことができます。まず、適切な場所で使用する識別子を定義します:
// The log's ID. Only one required in this example
#define TIMESTAMP_LOG 1
次に、データをログ記録する前に、まずセッションを作成する必要があります。これは、アプリの初期化中、またはアプリが最初にデータをログ記録する必要がある直前に行う必要があります:
// The session reference variable
static DataLoggingSessionRef s_session_ref;
static void init() {
// Begin the session
s_session_ref = data_logging_create(TIMESTAMP_LOG, DATA_LOGGING_INT, sizeof(int), true);
/* ... */
}
注意:
data_logging_create()の最終パラメータを使用すると、各アプリ起動時にゼロから開始する代わりに、前のログセッションを継続できます。
ログが作成または再開されたら、データ収集を続行できます。data_logging_log() への各呼び出しは、提供された DataLoggingSessionRef 変数によって示されるログに新しいエントリを追加します。各ログ操作の成功は、返された DataLoggingResult を使用して確認できます:
const int value = 16;
const uint32_t num_values = 1;
// Log a single value
DataLoggingResult result = data_logging_log(s_session_ref, &value, num_values);
// Was the value successfully stored? If it failed, print the reason
if(result != DATA_LOGGING_SUCCESS) {
APP_LOG(APP_LOG_LEVEL_ERROR, "Error logging data: %d", (int)result);
}
すべてのデータがログ記録されたか、アプリが終了したら、セッションを終了して、データが接続された電話に転送される(利用可能な場合)か、後で送信するために保存されることを示す必要があります。
// Finish the session and sync data if appropriate
data_logging_finish(s_session_ref);
注意: セッションが終了したら、再開または新規に開始されるまで、その
DataLoggingSessionRefにデータをログ記録できません。
注意: Datalogging データは PebbleKit JS 経由で受信できません。
Datalogging API で収集されたデータは、PebbleKit Android または PebbleKit iOS を使用するモバイルコンパニオンアプリで受信および処理できます。これにより、健康研究用の加速度計データの詳細な分析や、サードパーティのウェブサービスへの送信など、幅広い一般的なアプリケーションで使用できます。
PebbleKit Android では、Activity または Service 内で PebbleDataLogReceiver を登録することでデータを収集できます。レシーバーを作成するときは、データ収集を行っているウォッチアプリの UUID と一致する正しい UUID を提供するように注意してください。たとえば:
// The UUID of the watchapp
private UUID APP_UUID = UUID.fromString("64fcb54f-76f0-418a-bd7d-1fc1c07c9fc1");
次のオーバーライドされたメソッドを使用して、データを収集し、ウォッチアプリによってセッションが終了したことを判断します。以下の例では、受信した各新しい整数はウォッチアプリのアップタイムを表し、Android TextView に表示されます:
// Create a receiver to collect logged data
PebbleKit.PebbleDataLogReceiver dataLogReceiver =
new PebbleKit.PebbleDataLogReceiver(APP_UUID) {
@Override
public void receiveData(Context context, UUID logUuid, Long timestamp,
Long tag, int data) {
// super() (removed from IDE-generated stub to avoid exception)
Log.i(TAG, "New data for session " + tag + "!");
// Cumulatively add the new data item to a TextView's current text
String current = dataView.getText().toString();
current += timestamp.toString() + ": " + data
+ "s since watchapp launch.\n";
dataView.setText(current);
}
@Override
public void onFinishSession(Context context, UUID logUuid, Long timestamp,
Long tag) {
Log.i(TAG, "Session " + tag + " finished!");
}
};
// Register the receiver
PebbleKit.registerDataLogReceiver(getApplicationContext(), dataLogReceiver);
重要
Java IDE がメソッドを作成するときに super() を呼び出すコード行を自動的に追加する場合、コードは UnsupportedOperationException になります。例外を回避するには、必ずこの行を削除してください。
Activity または Service が閉じているときは、レシーバーの登録を解除しようとする必要があります。ただし、これは常に必要なわけではなく(必要でないときに呼び出されると例外がスローされます)、try, catch ステートメントを使用してください:
@Override
protected void onPause() {
super.onPause();
try {
unregisterReceiver(dataLogReceiver);
} catch(Exception e) {
Log.w(TAG, "Receiver did not need to be unregistered");
}
}
PebbleKit iOS コンパニオンモバイルアプリ経由でデータを収集するプロセスは、PebbleKit Android を使用する場合と似ています。アプリが PBDataLoggingServiceDelegate のデリゲートになったら(詳細については PebbleKit iOS (Discontinued) を参照)、単にクラスを datalogging デリゲートとして登録します:
// Get datalogging data by becoming the delegate
[[PBPebbleCentral defaultCentral]
dataLoggingServiceForAppUUID:myAppUUID].delegate = self;
datalogging デリゲートになると、クラスは、新しいデータが利用可能なときとセッションがウォッチによって終了したときの 2 つの追加 callbacks を受け取ることができます。これらのコールバックを実装して新しいデータを読み取ります:
- (BOOL)dataLoggingService:(PBDataLoggingService *)service
hasSInt32s:(const SInt32 [])data
numberOfItems:(UInt16)numberOfItems
forDataLog:(PBDataLoggingSessionMetadata *)log {
NSLog(@"New data received!");
// Append newest data to displayed string
NSString *current = self.dataView.text;
NSString *newString = [NSString stringWithFormat:@"New item: %d", data[0]];
current = [current stringByAppendingString:newString];
self.dataView.text = current;
return YES;
}
- (void)dataLoggingService:(PBDataLoggingService *)service
logDidFinish:(PBDataLoggingSessionMetadata *)log {
NSLog(@"Finished data log: %@", log);
}
同じタイプのデータ(つまり、同じタグ/タイプ)を持つが異なるセッション(異なるタイムスタンプ)からのログを処理するロジックは、デリゲートコールバックを使用して開発者が作成する必要があります。
データが同じログに属しているかどうかを確認するには、PBDataLoggingSessionMetadata で -isEqual: を使用します。便宜上、PBDataLoggingSessionMetadata は NSCoding を使用してシリアル化できます。
複数のログを並行して使用する(たとえば、異なる種類の情報を転送するため)には、これらの異なるログからのデータを再関連付けするための追加のロジックが必要になります。これも開発者が実装する必要があります。