通知クリックからアクティビティにパラメータを送信するにはどうすればよいですか?
-
20-09-2019 - |
質問
通知からアクティビティにパラメータを送信する方法を見つけることができます。
通知を作成するサービスがあります。ユーザーが通知をクリックすると、いくつかの特別なパラメーターを使用してメイン アクティビティを開きたいと考えています。たとえば、アクティビティが特別なアイテム詳細ビューをロードして表示できるようにするためのアイテム ID。より具体的には、ファイルをダウンロードしていて、ファイルがダウンロードされたときに、クリックすると特別なモードでアクティビティが開くというインテントを通知に含めたいと考えています。使ってみました putExtra
私の意図に従っていますが、それを抽出できないように見えるので、間違っていると思います。
通知を作成するサービスのコード:
// construct the Notification object.
final Notification notif = new Notification(R.drawable.icon, tickerText, System.currentTimeMillis());
final RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);
contentView.setImageViewResource(R.id.image, R.drawable.icon);
contentView.setTextViewText(R.id.text, tickerText);
contentView.setProgressBar(R.id.progress,100,0, false);
notif.contentView = contentView;
Intent notificationIntent = new Intent(context, Main.class);
notificationIntent.putExtra("item_id", "1001"); // <-- HERE I PUT THE EXTRA VALUE
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notif.contentIntent = contentIntent;
nm.notify(id, notif);
通知から追加のパラメーターを取得しようとするアクティビティのコード:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bundle extras = getIntent().getExtras();
if(extras != null){
Log.i( "dd","Extra:" + extras.getString("item_id") );
}
エクストラは常に null であり、ログには何も記録されません。
ところで...の onCreate
はアクティビティが開始されたときにのみ実行されます。アクティビティがすでに開始されている場合は、エクストラを収集し、受け取った item_id に従ってアクティビティを提示したいと考えています。
何か案は?
解決
このガイドをご覧ください (通知を作成する)およびサンプル ApiDemos「StatusBarNotifications」および「NotificationDisplay」に追加します。
アクティビティがすでに実行されているかどうかを管理するには、次の 2 つの方法があります。
追加 FLAG_ACTIVITY_SINGLE_TOP アクティビティの起動時にインテントにフラグを設定し、アクティビティ クラスに実装します。 onNewIntent(インテントの意図) イベント ハンドラーを使用すると、アクティビティに対して呼び出された新しいインテントにアクセスできます (これは単に getIntent() を呼び出すのとは異なります。これにより、アクティビティを起動した最初のインテントが常に返されます。
1 番目と同じですが、インテントにフラグを追加する代わりに、 「シングルトップ」 アクティビティ AndroidManifest.xml 内。
インテント エクストラを使用する場合は、必ず呼び出してください PendingIntent.getActivity()
旗を持って PendingIntent.FLAG_UPDATE_CURRENT
, そうでない場合は、すべての通知に対して同じエクストラが再利用されます。
他のヒント
私は自分のアプリケーションがメッセージ通知を表示する同様の問題がありました。 複数の通知各通知をクリックがある場合には、ビュー・メッセージ・アクティビティにその通知の詳細を表示します。私は、同じ追加のパラメータの問題は、メッセージの表示の意図に受信されている解決
ここでは、この固定コードです。 通知テントを作成するためのコードます。
Intent notificationIntent = new Intent(getApplicationContext(), viewmessage.class);
notificationIntent.putExtra("NotificationMessage", notificationMessage);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(getApplicationContext(),notificationIndex,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(getApplicationContext(), notificationTitle, notificationMessage, pendingNotificationIntent);
メッセージの表示の活動のためのコードます。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onNewIntent(getIntent());
}
@Override
public void onNewIntent(Intent intent){
Bundle extras = intent.getExtras();
if(extras != null){
if(extras.containsKey("NotificationMessage"))
{
setContentView(R.layout.viewmain);
// extract the extra-data in the Notification
String msg = extras.getString("NotificationMessage");
txtView = (TextView) findViewById(R.id.txtMessage);
txtView.setText(msg);
}
}
}
たぶん、少し遅れて、しかし: これに代えます:
public void onNewIntent(Intent intent){
Bundle extras = intent.getExtras();
Log.i( "dbg","onNewIntent");
if(extras != null){
Log.i( "dbg", "Extra6 bool: "+ extras.containsKey("net.dbg.android.fjol"));
Log.i( "dbg", "Extra6 val : "+ extras.getString("net.dbg.android.fjol"));
}
mTabsController.setActiveTab(TabsController.TAB_DOWNLOADS);
}
これを使用します:
Bundle extras = getIntent().getExtras();
if(extras !=null) {
String value = extras.getString("keyName");
}
ここで同じ問題が発生します。 私は別の要求コードを使用して、それを解決するため、PendingIntentを作成中に、通知と同じIDを使用します。これが実行されなければならない理由が、まだわかりません。
PendingIntent contentIntent = PendingIntent.getActivity(context, **id**, notificationIntent, 0);
notif.contentIntent = contentIntent;
nm.notify(**id**, notif);
一部の電子メール・リストや他のフォーラムを読んだ後、私はトリックが意図にソム独自のデータを追加しているようだことがわかっています。
このような
Intent notificationIntent = new Intent(Main.this, Main.class);
notificationIntent.putExtra("sport_id", "sport"+id);
notificationIntent.putExtra("game_url", "gameURL"+id);
notificationIntent.setData((Uri.parse("foobar://"+SystemClock.elapsedRealtime())));
私は、これは、それが意図とは何か、そのエキストラによってのみ識別されるカントを持って実行する必要がある理由を理解しない...
私はすべてを試みたが、何も働いた。
は、最終的には、次の解決策を考え出したています。
活動のマニフェストの追加で1- アンドロイド:launchMode = "singleTop"
2-ペンディングインテントを製造後、使用バンドルを行う代わりに、直接intent.putString()またはintent.putIntを使用している間()
Intent notificationIntent = new Intent(getApplicationContext(), CourseActivity.class);
Bundle bundle = new Bundle();
bundle.putString(Constants.EXAM_ID,String.valueOf(lectureDownloadStatus.getExamId()));
bundle.putInt(Constants.COURSE_ID,(int)lectureDownloadStatus.getCourseId());
bundle.putString(Constants.IMAGE_URL,lectureDownloadStatus.getImageUrl());
notificationIntent.putExtras(bundle);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
new Random().nextInt(), notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
AndroidManifest.xml
launchMode="singleTop" を含める
<activity android:name=".MessagesDetailsActivity"
android:launchMode="singleTop"
android:excludeFromRecents="true"
/>
SMSReceiver.java
Intent と PendingIntent のフラグを設定します。
Intent intent = new Intent(context, MessagesDetailsActivity.class);
intent.putExtra("smsMsg", smsObject.getMsg());
intent.putExtra("smsAddress", smsObject.getAddress());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(context, notification_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
MessageDetailsActivity.java
onResume() - 毎回呼び出され、エクストラをロードします。
Intent intent = getIntent();
String extraAddress = intent.getStringExtra("smsAddress");
String extraBody = intent.getStringExtra("smsMsg");
それが役立つことを願っています、これはstackoverflowの他の回答に基づいていましたが、これは私にとってうまくいった最も更新されたものです。
簡単です。これがオブジェクトを使用した私の解決策です。
私のポジョ
public class Person implements Serializable{
private String name;
private int age;
//get & set
}
メソッド通知
Person person = new Person();
person.setName("david hackro");
person.setAge(10);
Intent notificationIntent = new Intent(this, Person.class);
notificationIntent.putExtra("person",person);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.notification_icon)
.setAutoCancel(true)
.setColor(getResources().getColor(R.color.ColorTipografiaAdeudos))
.setPriority(2)
.setLargeIcon(bm)
.setTicker(fotomulta.getTitle())
.setContentText(fotomulta.getMessage())
.setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT))
.setWhen(System.currentTimeMillis())
.setContentTitle(fotomulta.getTicketText())
.setDefaults(Notification.DEFAULT_ALL);
新しいアクティビティ
private Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification_push);
person = (Person) getIntent().getSerializableExtra("person");
}
幸運を!!
私は、Androidデベロッパーガイドからのソリューションを持って、いくつかの検索を行った後、
PendingIntent contentIntent ;
Intent intent = new Intent(this,TestActivity.class);
intent.putExtra("extra","Test");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(ArticleDetailedActivity.class);
contentIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
テストActivityクラスで意図余分な値を取得するには、次のコード記述する必要があります:
Intent intent = getIntent();
String extra = intent.getStringExtra("extra") ;
あなたが使用している場合は、
android:taskAffinity="myApp.widget.notify.activity"
android:excludeFromRecents="true"
起動するための活動のためのあなたのAndroidManifest.xmlファイルに、あなたはあなたの意図に次のように使用する必要があります:
Intent notificationClick = new Intent(context, NotifyActivity.class);
Bundle bdl = new Bundle();
bdl.putSerializable(NotifyActivity.Bundle_myItem, myItem);
notificationClick.putExtras(bdl);
notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));
notificationClick.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); // schließt tasks der app und startet einen seperaten neuen
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(NotifyActivity.class);
stackBuilder.addNextIntent(notificationClick);
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(notificationPendingIntent);
例えば固有のデータを設定することが重要です。以下のような固有のIDを使用します:
notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));
サービスの利用PendingIntent.FLAG_UPDATE_CURRENT
のための
私は仕事のために。
それが解決されるよりも、通知を表示しながら、PendingIntentとして使用してください。
PendingIntent意図= PendingIntent.getActivity(本、0、 notificationIntent、PendingIntent.FLAG_UPDATE_CURRENT);
最後のフィールドとしてPendingIntent.FLAG_UPDATE_CURRENTを追加します。
通知の実装では、次のようなコードを使用します。
NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
...
Intent intent = new Intent(this, ExampleActivity.class);
intent.putExtra("EXTRA_KEY", "value");
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
nBuilder.setContentIntent(pendingIntent);
...
ExampleActivity でインテントの追加値を取得するには、次のコードを使用します。
...
Intent intent = getIntent();
if(intent!=null) {
String extraKey = intent.getStringExtra("EXTRA_KEY");
}
...
非常に重要な注意: の インテント::putExtra() メソッドはオーバーロードされたメソッドです。追加のキーを取得するには、次を使用する必要があります インテント::get[タイプ]Extra() 方法。
注記: 通知_ID そして NOTIFICATION_CHANNEL_ID ExampleActivity で宣言された定数です
やあ、 私も、私はこれらの記事で言及したすべてのものを試してみましたが、他の場所からさらにいくつかのことを言うことができます。 私のための#1の問題は、新しいテントが常にnullバンドルを持っていたということでした。 私の問題は、「私は.thisまたは.thatが含まれている」の詳細にあまり注目していました。 私のソリューションは、詳細から戻って一歩を踏み出し、通知の全体的な構造を見ていました。私は私が正しい順序でコードのキーパーツを配置するために管理することをしなかったとき。 あなたが持っているのであれば、同様の問題がためにチェックします:
1. Intent notificationIntent = new Intent(MainActivity.this, NotificationActivity.class);
2a. Bundle bundle = new Bundle();
//私はデータを指定したいとずっと良いと入力します。例えばbundle.putInt
2b. notificationIntent.putExtras(bundle);
3. PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this, WIZARD_NOTIFICATION_ID, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
4. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
5. NotificationCompat.Builder nBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notify)
.setContentTitle(title)
.setContentText(content)
.setContentIntent(contentIntent)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setAutoCancel(false)//false is standard. true == automatically removes the notification when the user taps it.
.setColor(getResources().getColor(R.color.colorPrimary))
.setCategory(Notification.CATEGORY_REMINDER)
.setPriority(Notification.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
notificationManager.notify(WIZARD_NOTIFICATION_ID, nBuilder.build());
これにより、のシーケンスの私は、有効なバンドルを取得します。