アプリの統合方法


アプリの統合方法

まず、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. AndroidManifest.xmlファイルを開き、以下に記載された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タグ内のname値をアプリのパッケージ名に置き換えます。 -->
     <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キーをアプリに追加する方法は以下のとおりです。

  1. プロジェクトのassetsフォルダにapi_key.txtという名前のファイルを作成します。必ずこのフォルダに同ファイルを配置するようにしてください。
  2. このapi_key.txtファイルにAPIキーを挿入します。これ以外のデータは含めないでください。

リリース(実稼働)版アプリでは、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();

        // インテント内のエクストラからメッセージと時刻を抽出します。
        // メッセージの配信や順序は保証されません。
        // ネットワーク状況の変化により、メッセージが複数回配信される場合もあります。
        // アプリ側でメッセージの重複インスタンスを処理できるようにしておく必要があります。
        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" /