web-dev-qa-db-ja.com

アプリの起動時に受信した奇妙なプッシュメッセージ

プッシュサービスでキャプチャされた奇妙なプッシュメッセージが表示されます。

Bundle[{CMD=RST_FULL, from=google.com/iid, Android.support.content.wakelockid=1}]

昨日起こり始めたばかりで、どのコード変更がこれのせいであるかを本当に見つけることはできません。このメッセージを見たことがありますか?

55
vkislicins

バックアップからデータが復元されたため、アプリにこのメッセージが表示されています。バックアップには登録トークンが含まれている可能性があるため、このブロードキャストは、バックアップされたトークンが機能しないため、新しいトークンを取得するようアプリに伝えるために送信されます。

これは、新しい GCM API を対象としています。これにより、InstanceIdListenerService実装のonTokenRefresh()メソッドが呼び出され、アプリがすべてのトークンを再度取得する必要があります。

残念ながら、独自のBroadcastReceiverを作成している場合、これらのメッセージは予期せず、アプリがクラッシュする可能性があります。正しいことは、「差出人」フィールドでフィルタリングし、これらのメッセージのいずれかが表示された場合、トークンが無効である可能性があるためGCMに再登録することです。

アプリのデータが復元される新規インストールの状況以外でこれらのメッセージを受け取っている場合は、 Android-gcm メーリングリストに投稿してください。

20
morepork

@moreporkが示唆するように、更新された GCM APIドキュメント を参照してください。

WakefulBroadcastReceiverを拡張する既存のアプリの場合、GCMReceiverとGcmListenerServiceに移行することをお勧めします。移行するには:

アプリマニフェストで、GcmBroadcastReceiverを「com.google.Android.gms.gcm.GcmReceiver」に置き換え、IntentServiceを新しいGcmListenerServiceに拡張する現在のサービス宣言を置き換えます

クライアントコードからBroadcastReceiverの実装を削除する

GcmListenerServiceを使用するように、現在のIntentServiceサービス実装をリファクタリングします

詳細については、このページのサンプルマニフェストとコードサンプルを参照してください。

サンプルコード から、簡単に理解できます。

AndroidManifest.xml

<receiver
    Android:exported="true"
    Android:name="com.google.Android.gms.gcm.GcmReceiver"
    Android:permission="com.google.Android.c2dm.permission.SEND">
    <intent-filter>
        <action Android:name="com.google.Android.c2dm.intent.RECEIVE"/>
        <category Android:name="com.example.client"/>
    </intent-filter>
</receiver>

<service
    Android:name=".MyGcmListenerService"
    Android:exported="false">
    <intent-filter>
        <action Android:name="com.google.Android.c2dm.intent.RECEIVE"/>
    </intent-filter>
</service>

<service
    Android:name=".MyInstanceIdListenerService"
    Android:exported="false">
    <intent-filter>
        <action Android:name="com.google.Android.gms.iid.InstanceID"/>
    </intent-filter>
</service>

<service
    Android:name=".MyGcmRegistrationService"
    Android:exported="false">
</service>

MyGcmListenerService.Java

public class MyGcmListenerService extends GcmListenerService {
    @Override
    public void onMessageReceived(String from, Bundle data) {
        final String message = data.getString("message");
        makeNotification(message);
    }
}

MyGcmRegistrationService.Java

public class MyGcmRegistrationService extends IntentService {
    private static final String TAG = "MyRegistrationService";
    private static final String GCM_SENDER_ID = "XXXXXXXXXXXX";
    private static final String[] TOPICS = {"global"};

    public MyGcmRegistrationService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            synchronized (TAG) {
                InstanceID instanceID = InstanceID.getInstance(this);
                String token = instanceID.getToken(GCM_SENDER_ID,
                        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                sendTokenToServer(token);
                subscribeTopics(token);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void subscribeTopics(String token) throws IOException {
        for (String topic : TOPICS) {
            GcmPubSub pubSub = GcmPubSub.getInstance(this);
            pubSub.subscribe(token, "/topics/" + topic, null);
        }
    }
}

MyInstanceIdListenerService.Java

public class MyInstanceIdListenerService extends InstanceIDListenerService {
    public void onTokenRefresh() {
        Intent intent = new Intent(this, MyGcmRegistrationService.class);
        startService(intent);
    }
}

その後、古い登録コードを単に

Intent intent = new Intent(this, MyGcmRegistrationService.class);
startService(intent);
13
mpkuth

今日も同じ問題に気付きました。まず、このメッセージはgoogle自体(from = google.com/iid)から送信される必要があります。そうでない場合、from属性はgoogle開発者コンソール(つまり475832179747)のプロジェクトのIDになります。しかし、確かに、アプリケーションサーバーをシャットダウンしても、メッセージは引き続き受信されます。

Google Cloud Messagingサーバーに新規登録すると、常に受信します。インテントアクションによってメッセージをフィルター処理できるため、これは大きな問題ではありませんが、その目的を本当に知りたいです。

7
rickul

次からwakelockid要素のみを受信して​​GCM-> FCMを移行中にこの問題が発生しました。

  • firebaseコンソール
  • 次のようなリクエストで郵便配達員によるリクエストを再現しました:

{ "to": "<your token from FirebaseInstanceId.getInstance().getToken()>", "notification": { "body": "Hello", "title": "This is test message." } }

また、Googleからすべてのコードをコピーしました quickstart firebase messaging 。すべてがうまくいくはずです。しかし、すべてのテストの後、私は自分のgradle libsのバージョンを再確認することにしました。そこで、それらを最新の数に増やしました。それ以来、メッセージを正しく受信し始めました。

GitHubからプロジェクトをダウンロードし、これがあなたのために機能するかどうか試してみることをお勧めします。次のステップでは、このコードをプロジェクトにコピーします。 1つのプロジェクトですべてが正常に機能している場合、開始点として少なくとも1つのスタンディング/ワーキングポイントがあります。

Androidスタジオがこの問題を引き起こしているという噂があります-しかし、それは真実ではありません。私はそれをチェックしました。

同じ古いトークン(gcmから)を使用してメッセージを受信しないこともありますが、私のようなmigratingの場合と同じ場合は、トークンを新しいトークンに更新し、処理する必要がありますそれ..

0
deadfish

少なくともAsusタブレットで同じことが起こっています

より多くのデバイスで可能性が高いが、私は見てみる機会がなかった

私はIntent.getExtras()で特定の文字列を探しているので、修正は簡単でした。それらが存在しない場合はすべてを無視します。

googleの誰かが現れて何が起こっているのかを説明する可能性はありますか?

0
user1126515