2

すでに GCM サービスを実装し、十分に機能しているアプリケーションを継承しました。

アプリの起動時にエラーが発生INVALID_SENDERし、残りの半分はエラーが発生しないため、私は十分に言っています。

エラーが発生する時間と発生しない時間に違いはありません (または、違いを見逃している可能性があります)。

時々GCMからメッセージを受け取ります(INVALID_SENDERログイン後にメッセージが届かない場合)

onCreate()これは私の主な活動の登録コードです

private void registerGCM() throws Exception {
    GCMRegistrar.checkDevice(this);
    GCMRegistrar.checkManifest(this);
    registerReceiver(mHandleMessageReceiver, new IntentFilter(
            CommonUtilities.DISPLAY_MESSAGE_ACTION));
    final String regId = GCMRegistrar.getRegistrationId(this);
    if (regId.equals("")) {

        // Automatically registers application on startup.
        GCMRegistrar.register(this, CommonUtilities.SENDER_ID);
    } else {


        // Device is already registered on GCM, check server.
        if (GCMRegistrar.isRegisteredOnServer(this)) {


            ServerUtilities.register(mContext, regId);
        } else {
            // Try to register again, but not in the UI thread.
            // It's also necessary to cancel the thread onDestroy(),
            // hence the use of AsyncTask instead of a raw thread.
            final Context context = this;
            mRegisterTask = new AsyncTask<Void, Void, Void>() {

                @Override
                protected Void doInBackground(Void... params) {
                    boolean registered = ServerUtilities.register(context,                      regId);
                    if (!registered) {
                         GCMRegistrar.unregister(context);
                    }
                    return null;
                }

私のマニフェストファイル

 <receiver
        android:name="com.mixpanel.android.mpmetrics.GCMReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.says.broadcaster" />
        </intent-filter>
    </receiver>
    <receiver
        android:name="com.google.android.gcm.GCMBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>

            <!-- Receives the actual messages. -->
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <!-- Receives the registration id. -->
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

            <category android:name="com.says.broadcaster" />
        </intent-filter>
    </receiver>

私が 2 つのレシーバーを持っている理由は、私が使用している統計追跡 API からもプッシュ通知を受け取り、GCM を使用しているためです。

私のアプリは毎週のように新しいバージョンがあり、アプリの更新後に新しい ID を登録する必要があると読んでいました。これが問題でしょうか?

関連する質問: あるデバイスで INVALID_SENDER を取得し、別の GCM Android で動作している

4

1 に答える 1

7

GCM によって送信されたブロードキャストは順序付けられているようです。つまり、一度に 1 つずつ配信されます。ライブラリのレシーバーがレシーバーの前に呼び出されることがあり、レシーバーが呼び出されない可能性があります (ブロードキャストがキャンセルされた場合)。

それを処理するにはいくつかの方法があります。1 つの方法は、レシーバーにライブラリーのレシーバーよりも高い優先度を与えることです。android:priority両方のレシーバーの に属性を追加してintent-filter、レシーバーの優先順位を高くするだけです。

順序付きブロードキャスト (Context.sendOrderedBroadcast で送信) は、一度に 1 つのレシーバーに配信されます。各レシーバーが順番に実行されると、結果を次のレシーバーに伝達したり、ブロードキャストを完全に中止して他のレシーバーに渡さないようにしたりできます。レシーバーが実行される順序は、一致するインテント フィルターの android:priority 属性で制御できます。同じ優先順位のレシーバーは任意の順序で実行されます。

ブロードキャスト レシーバーが呼び出されたらintent.getExtras ().get("from")、使用している送信者 ID が含まれていることを確認する必要があります。この場合のみ、ブロードキャストを処理する必要があります。送信者 ID が異なる場合は、ライブラリで使用されている送信者 ID である可能性が高いため、ライブラリに処理させる必要があります。

それでも問題が解決しない場合は、マニフェストで受信者のみを宣言し、必要に応じて GCM ブロードキャストを他の受信者に転送することを検討できます。

于 2013-09-12T15:07:59.627 に答える