web-dev-qa-db-ja.com

Android通知アクションは実行されません(PendingIntent)

音楽プレーヤーであるアプリに通知アクションアイテムを追加しようとしています。ストリームが開始されると、通知がトリガーされ、ストリームの停止ボタンが通知に表示されます。これまでのところ通知は正常に機能していますが、ストップアクションアイテムに問題があります。ストリームを開始するサービスで宣言される方法は次のとおりです。

Intent stopIntent = new Intent(this, MusicPlayerNew.class);
stopIntent.putExtra("STOP", "STOP");
PendingIntent stopPendingIntent = PendingIntent.getActivity(this, 0,
                stopIntent, PendingIntent.FLAG_UPDATE_CURRENT, null);
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent);

今、私のアクティビティのonResume()メソッドで、getIntent()。getStringExtra()で「STOP」エクストラをチェックしていますが、getIntent()を介して取得したインテントにはエクストラが設定されていません:(

また、ブロードキャストの送信を確認しようとしました(サービスからアクティビティへの通信を行うブロードキャストレシーバーがあります)

Intent stopIntent2 = new Intent(MusicPlayerNew.STOP_MEDIAPLAYER);
PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0,
                stopIntent2, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.addAction(R.drawable.ic_stat_stop, "Stop", stopPendingIntent2); 

これで、アクティビティが現在フォアグラウンドにある場合に機能します。アクティビティがバックグラウンドにある場合、停止ボタンは何もしません:(

編集:プライベートクラスとしてアクティビティにBroadcastReceiverがあります

private class DataUpdateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
..
}}

OnResume()で、このレシーバーにアプリを登録します。

intentFilter = new IntentFilter(STOP_MEDIAPLAYER);
registerReceiver(dataUpdateReceiver, intentFilter);

onPause()

unregisterReceiver(dataUpdateReceiver);

OnPause()メソッドから登録解除を削除すると、アプリ/アクティビティがフォアグラウンドにない場合でもブロードキャストが受信されます。しかし、これはそれを行う正しい方法ですか?私はこの登録/登録解除をウェブ上のチュートリアルから入手したと思います。

18
MrHill

私はグーグルコードのこのスレッドで解決策を見つけます https://code.google.com/p/Android/issues/detail?id=6185

これを修正するには、PendingIntentPendingIntent.FLAG_CANCEL_CURRENTフラグを追加する必要があります。

PendingIntent stopPendingIntent2 = PendingIntent.getBroadcast(this, 0,
            stopIntent2, PendingIntent.FLAG_CANCEL_CURRENT);
10
Nik

これは非常に遅い答えですが、誰かを助けるかもしれません:

実行するインテントに基づいて、適切な種類の保留中のインテントを選択する必要があります。ここではいくつかの例を示します:

アクティビティの場合、以下を使用します。

Intent i = new Intent(this, YourActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);

サービスの場合、以下を使用します。

Intent i = new Intent(this, YourService.class);
PendingIntent pi = PendingIntent.getService(this, 0, i, 0);

ブロードキャストレシーバー以下を使用します。

Intent i = new Intent(this, YourReciver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);

必要に応じて、リクエストコードとフラグを変更する必要がある場合があります

10
Ayman Al-Absi

私は今日この問題に遭遇しました。私の場合、pendingIntentコンストラクターのすべてのパラメーターが同じであったため、インテントの前のインスタンスからキャッシュされたインテントエクストラを使用していました。私はこれに対する2つの解決策を見つけました...

  1. Nik で言及されているようにFLAG_CANCEL_CURRENTを使用します。
  2. 次のように、一意のrequestCodependingIntentに渡します

    PendingIntent pi = PendingIntent.getService(this, UNIQUE_ID, pi, 0);
    

私の場合、以前の通知を存続させる必要があるため、2番目の方法で問題が解決しました。これは、同様の問題を抱えている人を助けるかもしれません。

6
Atekihcan

今日この問題が発生しましたが、アクティビティが登録されていないか、AndroidManifest.xmlに追加されていないことが原因でした。そこにあると思ったのですが、そうではありませんでした。また、その意図でアクションを呼び出そうとしても、エラーはログに記録されていませんでした。

インテントを作成し、通知を使用せずにstartAcitivty(intent)を呼び出すことで、これを理解しました。次に、アクティビティがマニフェストから欠落している可能性があることを示すエラーが発生しました。

他の答えのどれもあなたの問題を解決しないなら、うまくいけばこれは解決するでしょう。通常、トリッキーな問題は、単純でばかげた何かの結果です。

5
Daniel Eagle

ブロードキャストレシーバーを使用するよりも、サービスを使用して、次のようにサービスで新しいアクションを宣言する必要があります。

public final String ACTION_STOP = "yourpackagename.ACTION_STOP";

そして、次のようにインテントを作成します。

Intent stopIntent = new Intent(this, YourService.class).setAction(YourService.ACTION_STOP);
PendingIntent stopPendingIntent = PendingIntent.getService(this, 0, stopIntent, 0);

もちろん、インテントのアクションがACTION_STOPに等しい場合は、サービスの関数startCommandで再生を停止します。

これでうまくいくはずです;)

1

ここには複数の質問があります:

パート1:「STOP」エクストラを受け取らないのはなぜですか?提供したコードには表示されていませんが、確認したかったのは通知インテントにフラグFLAG_ACTIVITY_SINGLE_TOPを使用していますか?その場合、アクティビティで受け取るインテントはアクティビティを開始したインテントであるため、「STOP」エクストラは使用できません。この場合、onNewIntent()を拡張する必要があります(新しいインテントが送信される場合)。 詳細はこちら
FLAG_ACTIVITY_SINGLE_TOPを使用していない場合は、通知がタップされたときに新しいアクティビティが作成されることを意味します。この場合、インテントには「STOP」パラメーターが必要です。関連するすべてのコードを提供していただければ、より良いお手伝いをさせていただきます。

パート2:ブロードキャストレシーバーの使用すでに発見したように、これは簡単ではありません。 onDestroyの登録を解除する必要があります。ユーザーがアクティビティを閉じると、onDestroyが呼び出され、ユーザーが通知をタップしたときにブロードキャストレシーバーがアクティブにならない場合があります。登録をまったく解除しないと、機能しているように見える場合がありますが、これはメモリリークであり、GCはいつでもクリーンアップして、プログラムのクラッシュにつながる可能性があります。つまり、登録を解除する必要があります。放送受信機のアプローチを採用する必要がある場合は、これを行うためのサービスが必要であり、サービスには独自の落とし穴があります->システムによる再起動、バッテリーの消耗など。最初のアプローチを採用することを強くお勧めします。

0
Sudhee

私は非常によく似た問題を抱えていましたが、解決策は非常に異なっていました。マニフェスト.xmlファイルで<service Android:enabled="false"></service>を宣言した場合も、保留中のインテントは発生しません。

Android:enabled="false"からAndroid:enabled="true"に置き換えます

これは問題の直接の問題ではない可能性があります。ただし、デフォルトのテンプレートを使用してAndroid studioでサービスを作成すると、これらのプロパティがサービスに自動的に追加されます。

0
bilal_hanif

OnPauseで登録を解除しているため、バックグラウンドでブロードキャストを受信しません。 unregisterReceiverコードをonDestroy関数に移動します。これは、アクティビティが破棄された場合にのみ呼び出されます。または、予期されたイベントが発生したら登録を解除できます。

0
prijupaul

私にとっての解決策は、インテントのフラグを設定することでした。

resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                Intent.FLAG_ACTIVITY_CLEAR_TASK);
0
Julien D