pebble
  • Tutorials
  • Get the SDK
  • Guides
  • Documentation
  • Examples
  • Community
  • Blog
  • More
Privacy
Cookies
Publish

Guides

  • Table of Contents
  • App Resources
  • Appstore Publishing
  • Best Practices
    • Building for Every Pebble
    • Conserving Battery Life - バッテリー寿命の節約
    • Modular App Architecture
  • Communication
  • Debugging
  • Design and Interaction
  • Events and Services
  • Graphics and Animations
  • Migrating Older Apps
  • Pebble Packages
  • Pebble Timeline
  • Rocky.js
  • Smartstraps
  • Tools and Resources
  • User Interfaces

Building for Every Pebble

さまざまな Pebble ハードウェア プラットフォーム間の機能の違いは、Hardware Information に記載されています。たとえば、Basalt、Chalk、Emery プラットフォームは 64 色をサポートしていますが、Aplite と Diorite プラットフォームは 2 色のみをサポートしています。これにより、他の非カラーハードウェアとの互換性を考慮する場合、豊富なカラーレイアウトを持つアプリの開発が困難になる可能性があります。もう 1 つの例は、Health や Dictation などのプラットフォーム固有の API を使用することです。

ユーザーの利便性を高めるため、開発者はすべてのプラットフォームで使用できる 1 つのアプリを作成するよう努めるべきです。開発者がこのタスクをより簡単に行えるように、Pebble SDK は、コード内でさまざまなハードウェア機能に対応するための多数のメソッドを提供しています。

プリプロセッサ ディレクティブ

#ifdef プリプロセッサステートメントを使用して、特定の目的のためにコンパイルされる特定のコードブロックを指定することができます。たとえば、Dictation API は、マイクがないプラットフォームでは除外する必要があります:

#if defined(PBL_MICROPHONE)
  // Start dictation UI
  dictation_session_start(s_dictation_session);
#else
  // Microphone is not available
  text_layer_set_text(s_some_layer, "Dictation not available!");
#endif

UI レイアウトを設計する場合、互換性のあるプラットフォームでの色の使用は、非カラープラットフォームでは黒または白のいずれかに適応できます。適切な機能が利用可能な場合、コンパイル時に PBL_COLOR と PBL_BW シンボルが定義されます:

#if defined(PBL_COLOR)
  text_layer_set_text_color(s_text_layer, GColorRed);
  text_layer_set_background_color(s_text_layer, GColorChromeYellow);
#else
  text_layer_set_text_color(s_text_layer, GColorWhite);
  text_layer_set_background_color(s_text_layer, GColorBlack);
#endif

これは、カラー サポートの可用性に応じて変化する複数のステートメントのブロックに役立ちます。単一のステートメントの場合、PBL_IF_COLOR_ELSE() マクロを使用してこれを実現することもできます。

window_set_background_color(s_main_window, PBL_IF_COLOR_ELSE(GColorJaegerGreen, GColorBlack));

利用可能な定義とマクロの完全なリストについては、以下を参照してください。

利用可能な定義とマクロ

以下の表は、機能依存のコードを条件付きでコンパイルまたは省略するために利用可能なすべての定義と関連するマクロの完全な概要を示しています。マクロは個々の値の選択に適していますが、定義はコード ブロック全体を選択するのに適しています。

Define MACRO Available
PBL_BW PBL_IF_BW_ELSE() 白黒のみをサポートするハードウェアで実行中。
PBL_COLOR PBL_IF_COLOR_ELSE() 64 色をサポートするハードウェアで実行中。
PBL_MICROPHONE PBL_IF_MICROPHONE_ELSE() マイクを含むハードウェアで実行中。
PBL_COMPASS None コンパスを含むハードウェアで実行中。
PBL_SMARTSTRAP PBL_IF_SMARTSTRAP_ELSE() smartstrap コネクタを含むハードウェアで実行中だが、コネクタが電力を供給できることは示されていない。
PBL_SMARTSTRAP_POWER None 電力を供給できる smartstrap コネクタを含むハードウェアで実行中。
PBL_HEALTH PBL_IF_HEALTH_ELSE() Pebble Health と HealthService API をサポートするハードウェアで実行中。
PBL_RECT PBL_IF_RECT_ELSE() 長方形のディスプレイを持つハードウェアで実行中。
PBL_ROUND PBL_IF_ROUND_ELSE() 丸型のディスプレイを持つハードウェアで実行中。
PBL_DISPLAY_WIDTH None 画面の幅をピクセル単位で決定。
PBL_DISPLAY_HEIGHT None 画面の高さをピクセル単位で決定。
PBL_PLATFORM_APLITE None Pebble/Pebble Steel 用にビルド。
PBL_PLATFORM_BASALT None Pebble Time/Pebble Time Steel 用にビルド。
PBL_PLATFORM_CHALK None Pebble Time Round 用にビルド。
PBL_PLATFORM_DIORITE None Pebble 2 用にビルド。
PBL_PLATFORM_EMERY None Pebble Time 2 用にビルド。
PBL_SDK_2 None SDK 2.x でコンパイル(非推奨)。
PBL_SDK_3 None SDK 3.x または 4.x でコンパイル。

注意: できるだけ具体的にするために、PBL_PLATFORM 定義ではなく、該当する機能定義を使用してコードを条件付きでコンパイルすることを強くお勧めします。

API 検出

プラットフォームと機能の検出に加えて、特定の API メソッドが利用可能かどうかを検出する API 検出を提供するようになりました。プラットフォームと機能は変化する可能性があるため、このアプローチは将来性があると考えられます。簡単な例を見てみましょう:

#if PBL_API_EXISTS(health_service_peek_current_value)
// Do something if specific Health API exists
#endif

ハードコードされたレイアウト値を避ける

複数のディスプレイの形状と解像度が利用可能であるため、開発者はレイアウト値のハードコーディングを避けるよう努めるべきです。以下の例を考えてみましょう:

static void window_load(Window *window) {
  // Create a full-screen Layer - BAD
  s_some_layer = layer_create(GRect(0, 0, 144, 168));
}

このレイヤーのハードコードされた幅と高さは、Aplite、Basalt、Diorite では画面全体をカバーしますが、Chalk や Emery ではカバーしません。この種の画面サイズ依存の計算では、Window 自体の UnobstructedArea 境界を使用する必要があります:

static void window_load(Window *window) {
  // Get the unobstructed bounds of the Window
  Layer window_layer = window_get_root_layer(window);
  GRect window_bounds = layer_get_unobstructed_bounds(window_layer);

  // Properly create a full-screen Layer - GOOD
  s_some_layer = layer_create(window_bounds);
}

この種の構造のもう 1 つの一般的な用途は、遮られない画面の高さの半分の Layer を作成することです。これも、Window の遮られない境界を使用して正しく実現できます:

GRect layer_bounds = window_bounds;
layer_bounds.size.h /= 2;

// Create a Layer that is half the screen height
s_some_layer = layer_create(layer_bounds);

このアプローチは、Window の遮られない境界が変化したときに比例レイアウト値が適切に適応するため、将来の新しい画面サイズ用にアプリを更新する際の簡素化にも有利です。

画面サイズ

Emery プラットフォームの導入を容易にするため、Pebble SDK は、開発者が画面の幅と高さを決定できるようにする新しいコンパイラディレクティブを導入しました。これは、複数のプラットフォームが同じ画面の幅と高さを共有しているため、プラットフォーム検出を使用するよりも望ましいです。

#if PBL_DISPLAY_HEIGHT == 228
  uint8_t offset_y = 100;
#elif PBL_DISPLAY_HEIGHT == 180
  uint8_t offset_y = 80;
#else
  uint8_t offset_y = 60;
#endif

注意: この方法はプラットフォーム検出よりも望ましいですが、ルートレイヤーの遮られない境界に基づいてディスプレイの幅と高さを動的に計算する方が良いです。

Pebble C WatchInfo

WatchInfo API を使用すると、アプリが実行されている Pebble のモデルと色を正確に判断できます。アプリは、この情報を使用して、ユーザーが着用している Pebble に応じてレイアウトや動作を動的に変更できます。

たとえば、Pebble Steel のディスプレイは、Pebble Time と比較して、ボタンに対して異なる垂直位置にあります。WatchInfoModel を使用して、これを補正するために画面上のボタンヒントを調整できます。

static void window_load(Window *window) {
  Layer window_layer = window_get_root_layer(window);
  GRect window_bounds = layer_get_bounds(window_layer);

  int button_height, y_offset;

  // Conditionally set layout parameters
  switch(watch_info_get_model()) {
    case WATCH_INFO_MODEL_PEBBLE_STEEL:
      y_offset = 64;
      button_height = 44;
      break;
    case WATCH_INFO_MODEL_PEBBLE_TIME:
      y_offset = 58;
      button_height = 56;
      break;

    /* Other cases */

    default:
      y_offset = 0;
      button_height = 0;
      break;

  }

  // Set the Layer frame
  GRect layer_frame = GRect(0, y_offset, window_bounds.size.w, button_height);

  // Create the Layer
  s_label_layer = text_layer_create(layer_frame);
  layer_add_child(window_layer, text_layer_get_layer(s_label_layer));

  /* Other UI code */

}

開発者は、WatchInfoColor 値を使用して、利用可能な Pebble の各色に対してアプリをテーマ化することもできます。

static void window_load(Window *window) {
  GColor text_color, background_color;

  // Choose different theme colors per watch color
  switch(watch_info_get_color()) {
    case WATCH_INFO_COLOR_RED:
      // Red theme
      text_color = GColorWhite;
      background_color = GColorRed;
      break;
    case WATCH_INFO_COLOR_BLUE:
      // Blue theme
      text_color = GColorBlack;
      background_color = GColorVeryLightBlue;
      break;

    /* Other cases */

    default:
      text_color = GColorBlack;
      background_color = GColorWhite;
      break;

  }

  // Use the conditionally set value
  text_layer_set_text_color(s_label_layer, text_color);
  text_layer_set_background_color(s_label_layer, background_color);

  /* Other UI code */

}

PebbleKit JS Watch Info

上記の Pebble C WatchInfo と同様に、PebbleKit JS の Pebble.getActiveWatchInfo() メソッドを使用すると、開発者はユーザーが着用している Pebble のモデルと色、および実行されているファームウェア バージョンを判断できます。たとえば、ウォッチのモデルを取得するには:

注意: 古いアプリバージョンでこの関数を使用する際の問題を回避するには、以下のセクションを参照してください。

// Get the watch info
var info = Pebble.getActiveWatchInfo();

console.log("Pebble model: " + info.model);

プラットフォーム固有の JS 機能の検出

PebbleKit JS の多くの機能(Pebble.timelineSubscribe() や Pebble.getActiveWatchInfo() など)は SDK 3.x に存在します。アプリがこれらを利用できない古い Pebble モバイルアプリバージョンで使用しようとすると、JS アプリがクラッシュします。

これを防ぐには、関数を呼び出す前に、関数の可用性を必ず確認してください。たとえば、Pebble.getActiveWatchInfo() の場合:

if (Pebble.getActiveWatchInfo) {
  // Available.
  var info = Pebble.getActiveWatchInfo();

  console.log("Pebble model: " + info.model);
} else {
  // Gracefully handle no info available
}

プラットフォーム固有のリソース

Basalt、Chalk、Emery でカラー サポートが利用できるようになったため、開発者は以前に Pebble の白黒ディスプレイ用に前処理されていたリソースのカラーバージョンを含めることを希望する場合があります。リソースの両方のバージョンを含めることは、リソースストレージの観点からコストがかかり、複数のプラットフォーム用にビルドされた際に、Aplite または Diorite アプリに冗長なカラーリソースをパックする負担を負わせます。

この問題を解決するため、Pebble SDK を使用すると、開発者はファイル名に ~bw または ~color を追加して、各ディスプレイ タイプに使用する画像リソースのバージョンを指定できます。リソースは、各リソースの targetPlatforms プロパティを使用して、特定のプラットフォームにのみバンドルすることもできます。

各プラットフォームに固有のリソースのパッケージング、および ~color に類似した利用可能なその他のタグの詳細については、Platform-specific Resources - 特定のプラットフォーム向けリソースの設定 をお読みください。

複数のディスプレイ形状

Chalk プラットフォームの導入により、ピクセル解像度が向上した新しい丸型ディスプレイタイプが利用可能になりました。2 つの可能なディスプレイの形状を区別するために、開発者は定義を使用してコードセグメントを条件付きで含めることができます:

#if defined(PBL_RECT)
  printf("This is a rectangular display!");
#elif defined(PBL_ROUND)
  printf("This is a round display!");
#endif

この条件付きコンパイルへのもう 1 つのアプローチは、PBL_IF_RECT_ELSE() と PBL_IF_ROUND_ELSE() マクロを使用することです。これにより、前の例と同様の #define ステートメントのセットを必要とする可能性のある式に値を挿入できます。これは、実際には 1 行しか必要ないときに、4 行の余分なコードの不必要な冗長性をもたらすでしょう。これらは次のように使用されます:

// Conditionally print out the shape of the display
printf("This is a %s display!", PBL_IF_RECT_ELSE("rectangular", "round"));

このメカニズムは、ウィンドウ境界派生のレイアウトサイズと位置の値で最もよく使用されます。詳細については、上記の ハードコードされたレイアウト値を避ける セクションを参照してください。組み込みの Layer タイプをうまく利用することも、ディスプレイの形状とサイズの変更からアプリを保護するのに役立ちます。

もう 1 つ考慮すべきことは、丸型ディスプレイでのテキストのレンダリングです。丸い角のため、各水平テキスト行は、垂直位置に応じて異なる利用可能な幅を持ちます。

You need JavaScript enabled to read and post comments.

Overview

  • プリプロセッサ ディレクティブ
  • 利用可能な定義とマクロ
  • API 検出
  • ハードコードされたレイアウト値を避ける
  • 画面サイズ
  • Pebble C WatchInfo
  • PebbleKit JS Watch Info
  • プラットフォーム固有の JS 機能の検出
  • プラットフォーム固有のリソース
  • 複数のディスプレイ形状