アプリを統合する


アプリを統合する

まず、Amazon Device Messaging(ADM)の使用に必要な認証情報を取得します。次に開発環境でADMのセットアップを行い、アプリに組み込みます。アプリとサーバーコードにADMを組み込むプロセスの概要に関しては、Amazon Device Messaging(ADM)についてを参照してください。

テストに関する注意事項

アプリによるADMの使用をテストする場合は、以下の点に注意してください。

  • 第1世代のKindle Fireタブレットは、ADM非対応です。
  • 第2世代のKindle FireタブレットはADM対応ですが、以下のシステムバージョンの搭載が必須です。システムバージョンを確認するには、[設定] > [端末] > [バージョン情報] の順にクリックします。
    • Kindle Fire HD 8.9" - システムバージョン8.3.0以降
    • Kindle Fire HD 7" - システムバージョン7.3.0以降
    • Kindle Fire(第2世代)- システムバージョン10.3.0以降。第2世代のタブレットでは、企業のファイアウォールによってADMへのネットワークアクセスがブロックされる可能性があります。以下のポートのいずれかでUDPを使用して、アプリが企業ネットワーク外のサーバーと通信できるようにしてください。

      • 49317
      • 33434
      • 40317
  • そのほかのFireタブレット、Fire Phone、Fire TVデバイスでは、すべてのシステムバージョンがADMをサポートしています。

アプリのマニフェストを更新する

ADM経由で送信されたメッセージを受信するには、まずAndroidManifest.xmlファイルの更新が必要です。既存のファイルを次のように変更してください。

  1. Amazonの名前空間を追加します。

    xmlns:amazon="http://schemas.amazon.com/apk/res/android"
    
  2. ADMのサポートに必要なパーミッションを宣言するには、permission要素とuses-permission要素をmanifest要素の後に追加します。

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:amazon="http://schemas.amazon.com/apk/res/android"
       package="[パッケージ名]"
       android:versionCode="1"
       android:versionName="1.0">
    <!-- このパーミッションにより、ADMメッセージがほかのアプリにインターセプトされる
    危険性が回避されます。 -->
    <permission
         android:name="[パッケージ名].permission.RECEIVE_ADM_MESSAGE"
         android:protectionLevel="signature" />
    <uses-permission android:name="[パッケージ名].permission.RECEIVE_ADM_MESSAGE" />
    
    <!-- このパーミッションにより、ADMからのプッシュ通知をアプリが受信できるように
    なります。 -->
    <uses-permission android:name="com.amazon.device.messaging.permission.RECEIVE" />
    
    <!-- メッセージ受信時にプロセッサがスリープ状態になるのを防ぐため、ADMはWAKE_LOCKを使用します。 -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    ...
    </manifest>
    
  3. 明示的にADMを有効化し、アプリにADMが必要(android:required="true")か、もしくはADMがなくても動作する(android:required="false")かを宣言します。ここでandroid:required="false"を指定した場合、ADM不使用時にアプリの機能が適切に制限される仕様にする必要があります。マニフェストのapplicationノードで、amazon:enable-feature要素を追加してください。

    ...
    <application
          android:icon="@drawable/ic_launcher"
          android:label="@string/app_name"
          android:theme="@style/AppTheme">
    
          <!-- 明示的にADMを有効化し、アプリにADMが必要
             (android:required="true")か、もしくはADMがなくても動作する(android:required="false")かを宣言してください。
             ここでandroid:required="false"を指定した場合、ADM不使用時にアプリの機能が
             適切に制限される仕様にする必要があります。 -->
             <amazon:enable-feature
    	  android:name="com.amazon.device.messaging"
                 android:required="true"/>
    ...
    
  4. ADMから送信されるREGISTRATIONインテントとRECEIVEインテントを処理するために、ブロードキャストレシーバーを宣言します。レシーバーはプログラムではなく、AndroidManifest.xmlファイルで定義する必要があります。amazon:enable-featureの直後に、以下の要素を追加してください。

     <!-- serviceタグとreceiverタグ内のname値は、パッケージで使用する
         適切な名前に置き換えてください。 -->
    
     <service
         android:name="[サービス名]"
         android:exported="false" />
    
     <receiver
         android:name="[レシーバー名]"
    
         <!-- このパーミッションにより、ADMのみがアプリ登録ブロードキャストを送信できます-->
         android:permission="com.amazon.device.messaging.permission.SEND" >
    
         <!-- アプリがADMとやり取りを行うには、以下のインテントをリッスンする必要があります。 -->
         <intent-filter>
     <action android:name="com.amazon.device.messaging.intent.REGISTRATION" />
     <action android:name="com.amazon.device.messaging.intent.RECEIVE" />
    
     <!-- categoryタグ内の名前をアプリのパッケージ名に置き換えます。 -->
     <category android:name="[パッケージ名]" />
         </intent-filter>
     </receiver>
    
  5. AndroidManifest.xmlファイルの更新後、ADMManifest.checkManifestAuthoredProperly()を呼び出して、変更が適切かどうかを確認します。

    java.lang.NoClassDefFoundError: com.amazon.device.messaging.ADMエラーが発生した場合は、マニフェストを調べて、手順3で指定された場所にamazon:enable-feature要素が追加されているかを確認します。

以下のコードは、ADMに対応したAndroidManifest.xmlファイルの一例です。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:amazon="http://schemas.amazon.com/apk/res/android"
   package="[パッケージ名]"
   android:versionCode="1"
   android:versionName="1.0" >

   <uses-sdk
      android:minSdkVersion="15"
      android:targetSdkVersion="15" />

   <permission
      android:name="[パッケージ名].permission.RECEIVE_ADM_MESSAGE"
      android:protectionLevel="signature" />
   <uses-permission android:name="[パッケージ名].permission.RECEIVE_ADM_MESSAGE" />

   <uses-permission android:name="com.amazon.device.messaging.permission.RECEIVE" />

   <uses-permission android:name="android.permission.WAKE_LOCK" />

   <application
      android:icon="@drawable/ic_launcher"
      android:label="@string/app_name"
      android:theme="@style/AppTheme" >

      <amazon:enable-feature
         android:name="com.amazon.device.messaging"
         android:required="true"/>

      <service
         android:name="[サービス名]"
         android:exported="false" />

      <receiver
         android:name="[レシーバー名]"
         android:permission="com.amazon.device.messaging.permission.SEND" >

         <intent-filter>
         <action android:name="com.amazon.device.messaging.intent.REGISTRATION" />
         <action android:name="com.amazon.device.messaging.intent.RECEIVE" />

         <category android:name="[パッケージ名]" />
         </intent-filter>

      </receiver>
   </application>
</manifest>

APIキーをアセットとして格納する

アプリでメッセージを受信するには、アプリに有効なAPIキーが含まれている必要があります。APIキーの作成プロセスについては認証情報を取得する、APIキーの詳細についてはAmazon Device Messaging(ADM)についてを参照してください。

プレリリース(デバッグ)版アプリの場合は、APIキーを作成し、それをapi_key.txtと名付けたファイルに唯一のデータとして保存する必要があります。api_key.txtファイルは、プロジェクトのassetsフォルダ内に必ず置いてください。

リリース(実稼働)版アプリでは、APIキーの作成が不要な場合があります。独自の証明書を使用してリリース版に署名する場合のみ、追加のAPIキー作成が必要になります。アプリへの署名をAmazonに任せる場合は、新たなAPIキーの作成は不要です。

アプリのメインアクティビティにADMを統合する

次のことを行うために、com.amazon.device.messaging.ADMクラス内のメソッドの使用方法を示したコードの例を紹介します。

  • ADMコンテキストのインスタンスを作成する
  • 現在のアプリインスタンス用にADMへの登録を開始する
final ADM adm = new ADM(this);
if (adm.getRegistrationId() == null)
{
   // startRegister()は非同期です。アプリへの通知は、登録IDが利用できるようになると、
   // onRegistered()コールバックで行われます。
   adm.startRegister();
}

このコードをonCreate()メソッド内に配置して、アプリを起動するたびに同コードを実行してください。アプリが登録済みであれば、getRegistrationId()によって現在のアプリインスタンスの登録IDが返され、startRegister()は呼び出されません。デバイスでアプリを初めて起動する場合や、以前の登録が失敗した場合は、このコードによって登録プロセスが開始されます。

登録とメッセージの処理を実装する

マニフェストで宣言されたブロードキャストレシーバーは、インテントをリッスンし、インテント受信時にアプリを起動させます。アプリは、com.amazon.device.messaging.ADMMessageHandlerBaseクラス内で定義された以下のコールバックメソッドを介して、ブロードキャストレシーバーとのやり取りを行います。

  • onRegistered。アプリインスタンスの登録IDが利用可能になると呼び出されます。アプリ側はこの登録IDを開発者サーバーに送信する必要があり、そうすることで開発者サーバーがアプリインスタンスにメッセージを送信できるようになります

  • onUnregistered。アプリインスタンスがADMから登録解除された場合に呼び出されます。

  • onRegistrationError。アプリのADM登録リクエストが何らかの理由(デバイスにサインインしているAmazonユーザーがいないなど)で失敗した場合に呼び出されます。

  • onMessage。ADMクライアントがアプリインスタンスにメッセージを配信する際に呼び出されます。

com.amazon.device.messaging.ADMMessageHandlerBasecom.amazon.device.messaging.ADMMessageReceiverのサブクラスを実装する場合は、アプリ側でこれらのコールバックをオーバーライドする必要があります。以下のコードサンプルを参照してください。

public class MyADMMessageHandler extends ADMMessageHandlerBase
{
    public static class Receiver extends ADMMessageReceiver
    {
        public Receiver()
        {
            super(MyADMMessageHandler.class);
        }

    // ここではほかに何も必要ありません。ブロードキャストレシーバーは、処理用に
    // インテントを自動でサービスに送信します。
    }

    @Override
    protected void onRegistered(final String newRegistrationId)
        {
        // メインアクティビティでstartRegister()を呼び出すことで登録プロセスを
        // 開始します。登録IDが利用可能になると、ADMはアプリのonRegistered()を
        // 呼び出します。開発者サーバーが現在のアプリインスタンスに対してメッセージ送信ができるように、
        // 渡された登録IDを開発者サーバーに送信します。onRegistered()は、何らかの理由で
        // 登録IDのローテーションまたは変更が行われた場合にも呼び出されます。
        // その場合、アプリ側は新しい登録IDを開発者サーバーに渡す必要があります。
        // 開発者サーバーには、最大1,536文字までの登録IDを処理できる能力が
        // 求められます。

        // ヘッダーのキーと値のペアを使用してHTTPで登録IDを
        // 開発者サーバーに送信する例を以下に用意しました。
        URL url = new URL(YOUR_WEBSERVER_URL);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setDoInput(true);
        con.setUseCaches(false);
        con.setRequestMethod("POST");
        con.setRequestProperty("RegistrationId", newRegistrationId);
        con.getResponse();
        }

    @Override
    protected void onUnregistered(final String registrationId)
    {
        // このデバイスでアプリが登録解除されている場合は、現在のアプリインスタンスが
        // メッセージの有効なターゲットではなくなっていることを開発者サーバーに通知します。
    }

    @Override
    protected void onRegistrationError(final String errorId)
    {
        // 登録エラーは致命的であるとみなす必要があります。その対応として、
        // アプリの機能を適切に制限するか、アプリの機能のうちこの部分が使用できないことを
        // ユーザーに通知することができます。
    }

    @Override
    protected void onMessage(final Intent intent)
    {
        // com.amazon.device.messaging.intent.RECEIVEインテントに
        // アタッチされているエクストラからメッセージコンテンツを抽出します。

        // JSONデータのメッセージフィールドとタイムスタンプフィールドにアクセスするための文字列を作成します。
        final String msgKey = getString(R.string.json_data_msg_key);
        final String timeKey = getString(R.string.json_data_time_key);

        // onMessage()コールバックでトリガーされるインテントアクションを取得します。
        final String intentAction = getString(R.string.intent_msg_action);

        // インテントに含まれていたエクストラを取得します。
        final Bundle extras = intent.getExtras();

        // インテント内のエクストラからメッセージと時刻を抽出します。
        // ADMではメッセージの配信や順序が保証されません。
        // ネットワーク状況の変化により、メッセージが複数回配信される場合もあります。
        // アプリ側でメッセージの重複インスタンスを処理できるようにしておく必要があります。
        final String msg = extras.getString(msgKey);
        final String time = extras.getString(timeKey);
    }
}

ADMを使用できない場合の適切な制限

マニフェストファイルでは、ADMを使用できない場合にアプリが動作する(android:required="false")か、動作しない(android:required="true")かを宣言します。ここでandroid:required="false"を指定した場合、ADM不使用時にアプリの機能が適切に制限される仕様にする必要があります。

ADMがなくても動作するアプリを設計すると、単一のAPKを構築するだけで、ADMのありなしにかかわらずデバイスにインストールして実行することができます。

適切な機能制限が行われるようにアプリを修正するには

  1. 次のようなコードを使用してADMの存在を確認します。

    ADMAvailable = false ;
    try
    {
        Class.forName( "com.amazon.device.messaging.ADM" );
        ADMAvailable = true ;
    }
    catch (ClassNotFoundException e)
    {
        // 例外を処理します。
    }
    
  2. ADMライブラリランタイムを必要とするコードに、次のコードを追加します。

    if (ADMAvailable)
    {
        // ADMを必要とするコードをここに挿入します。
    }
    
  3. AndroidManifest.xmlファイル内のapplication要素において、次のような指定がなされていることを確認します。

    amazon:enable-feature android:name="com.amazon.device.messaging" android:required="false" /