79

Google Cloud Messaging のドキュメントには、次のように記載されています。

Android アプリケーションは、後で使用するためにこの ID を保存する必要があります (たとえば、既に登録されている場合に onCreate() をチェックするため)。Google は定期的に登録 ID を更新する場合があるため、com.google.android.c2dm.intent.REGISTRATION インテントが複数回呼び出される可能性があることを理解して Android アプリケーションを設計する必要があります。Android アプリケーションは、それに応じて応答できる必要があります。

次のコードを使用してデバイスを登録します。

GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String regID = gcm.register(senderID);

GoogleCloudMessaging クラスは、登録プロセスをカプセル化します。では、GoogleCloudMessaging クラスによって内部的に処理が行われるため、com.google.android.c2dm.intent.REGISTRATION をどのように処理すればよいのでしょうか?

4

3 に答える 3

137

それは興味深い質問です。

新しい登録プロセスに切り替えることをお勧めします:

モバイル デバイスで実行されている Android アプリケーションは、GoogleCloudMessaging メソッドの register(senderID...) を呼び出して、メッセージを受信するように登録します。このメソッドは、アプリケーションを GCM に登録し、登録 ID を返します。この合理化されたアプローチは、以前の GCM 登録プロセスに取って代わります。

という注記Google may periodically refresh the registration IDは、古い登録プロセスが表示されているページにのみ表示されるため、この注記はもはや関連性がない可能性があります。

安全を確保したい場合は、古い登録プロセスを引き続き使用できます。または、新しいプロセスを使用することもできますがcom.google.android.c2dm.intent.REGISTRATION、Google が登録 ID を更新することを決定した場合にカバーされるように、インテントを処理するコードを追加することもできます。

とは言っても、私はそのような更新を経験したことはなく、登録 ID の変更を経験した場合でも (通常、アプリをアンインストールしてから再インストールした後に通知を送信した結果として)、古い登録 ID のままです。正常に機能したため (Google からの応答で正規の登録 ID が送信されました)、害はありませんでした。

編集 (06.06.2013) :

Googleは新しいインターフェースを使用するようにデモ アプリを変更しました。アプリによってローカルに保持されている値に有効期限を設定することで、登録 ID を更新します。アプリが起動すると、ローカルに保存されている登録 ID が読み込まれます。「期限切れ」の場合 (デモでは、GCM から 7 日以上前に受信されたことを意味します)、gcm.register(senderID)再度呼び出します。

これは、長期間起動されていないアプリの登録 ID が Google によって更新されるという架空のシナリオを処理しません。その場合、アプリは変更を認識せず、サード パーティのサーバーも認識しません。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    mDisplay = (TextView) findViewById(R.id.display);

    context = getApplicationContext();
    regid = getRegistrationId(context);

    if (regid.length() == 0) {
        registerBackground();
    }
    gcm = GoogleCloudMessaging.getInstance(this);
}

/**
 * Gets the current registration id for application on GCM service.
 * <p>
 * If result is empty, the registration has failed.
 *
 * @return registration id, or empty string if the registration is not
 *         complete.
 */
private String getRegistrationId(Context context) {
    final SharedPreferences prefs = getGCMPreferences(context);
    String registrationId = prefs.getString(PROPERTY_REG_ID, "");
    if (registrationId.length() == 0) {
        Log.v(TAG, "Registration not found.");
        return "";
    }
    // check if app was updated; if so, it must clear registration id to
    // avoid a race condition if GCM sends a message
    int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
    int currentVersion = getAppVersion(context);
    if (registeredVersion != currentVersion || isRegistrationExpired()) {
        Log.v(TAG, "App version changed or registration expired.");
        return "";
    }
    return registrationId;
}

/**
 * Checks if the registration has expired.
 *
 * <p>To avoid the scenario where the device sends the registration to the
 * server but the server loses it, the app developer may choose to re-register
 * after REGISTRATION_EXPIRY_TIME_MS.
 *
 * @return true if the registration has expired.
 */
private boolean isRegistrationExpired() {
    final SharedPreferences prefs = getGCMPreferences(context);
    // checks if the information is not stale
    long expirationTime =
            prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
    return System.currentTimeMillis() > expirationTime;
}

編集 (08.14.2013) :

Google はデモ アプリを再び変更しました (2 日前)。今回は、登録 ID が 7 日後に期限切れになると見なすロジックを削除しました。現在、アプリの新しいバージョンがインストールされたときにのみ、登録 ID が更新されます。

編集 (04.24.2014) :

完全を期すために、GCM の開発に携わった Google 開発者であるCostin Manolache (ここから引用) の言葉を以下に示します。

「定期的な」更新は行われず、登録の更新は新しい GCM ライブラリには含まれていません。

登録 ID の変更の唯一の既知の原因は、アップグレード中にメッセージを受信すると、アプリが自動的に登録解除されるという古いバグです。このバグが修正されるまで、アプリはアップグレード後に引き続き register() を呼び出す必要があり、これまでのところ登録 ID はこの場合変更される可能性があります。unregister() を明示的に呼び出すと、通常は登録 ID も変更されます。

提案/回避策は、たとえば共有設定として保存された独自のランダム識別子を生成することです。アプリをアップグレードするたびに、識別子と潜在的に新しい登録 ID をアップロードできます。これは、サーバー側でのアップグレードと登録の変更の追跡とデバッグにも役立つ場合があります。

これは、公式の GCM Demo アプリケーションの現在の実装について説明しています。 クラスをcom.google.android.c2dm.intent.REGISTRATION使用して登録する場合は、決して処理しないでください。GoogleCloudMessaging

于 2013-05-30T14:51:24.203 に答える
6

新しい InstanceID API を読んで、トークンがいつ変更される可能性があるかについての詳細を見つけました。

アプリは、必要に応じて getToken() メソッドを使用してインスタンス ID サービスからトークンを要求できます。また、InstanceID と同様に、アプリは独自のサーバーにトークンを保存することもできます。アプリに発行されたすべてのトークンは、アプリの InstanceID に属します。

トークンは一意で安全ですが、セキュリティ上の問題が発生した場合や、デバイスの復元中にユーザーがアプリをアンインストールして再インストールした場合、アプリまたはインスタンス ID サービス でトークンの更新が必要になる場合があります。Instance ID サービスからのトークン更新リクエストに応答するリスナーをアプリに実装する必要があります。

詳細:

インスタンス ID サービスは定期的に (たとえば、6 か月ごとに) コールバックを開始し、アプリがそのトークンを更新するように要求します。また、次の場合にコールバックを開始する場合があります。

  • セキュリティ上の問題があります。たとえば、SSL やプラットフォームの問題などです。
  • デバイス情報が無効になりました。たとえば、バックアップと復元です。
  • それ以外の場合、インスタンス ID サービスは影響を受けます。

ソース:

https://developers.google.com/instance-id/

https://developers.google.com/instance-id/guides/android-implementation

于 2015-09-11T08:33:58.147 に答える