java Android 多个通知和多个意图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12968280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Multiple Notifications and with multiple intents
提问by EGHDK
I have a fairly simple app that takes the input from a user and then sets it as a notification. The user can create as many notifications as he/she likes. I want the user to click the notification and get taken to a new activity called ResultActivity
. ResultActivity
in turn reads in the putExtras
from the notifications intent and shows it to the user. The code below allows me to do almost everything I wanted, except anytime a notification is pressed, I receive the putExtra
of the last created notification.
我有一个相当简单的应用程序,它接受用户的输入,然后将其设置为通知。用户可以根据需要创建任意数量的通知。我希望用户单击通知并转到名为ResultActivity
. ResultActivity
依次putExtras
从通知意图中读取并将其显示给用户。下面的代码允许我做几乎所有我想做的事情,除非任何时候按下通知,我都会收到putExtra
上次创建的通知。
Intent notificationIntent = new Intent(ctx, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, i,notificationIntent,PendingIntent.FLAG_CANCEL_CURRENT);
NotificationManager nm = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
Resources res = ctx.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
builder.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res,R.drawable.ic_launcher))
.setTicker("Remember to " + text.getText())
.setWhen(System.currentTimeMillis()).setAutoCancel(true)
.setContentTitle(text.getText());
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);
String pass = text.getText().toString();
resultIntent.putExtra("title", pass);
resultIntent.putExtra("uid", i);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
new Uri.Builder().scheme("data").appendQueryParameter("text", "my text").build();
builder.setContentIntent(resultPendingIntent);
Notification n = builder.build();
n.flags = Notification.FLAG_NO_CLEAR;
nm.notify(i++, n);
text.setText(null);
Open the application
Type in "One"
Hit ok
Notification is sent
Open the application
Type in "Two"
Hit ok
Notification is sent
打开应用程序
输入“一”
点击确定
通知已发送
打开应用程序
输入“二”
点击确定
通知已发送
Now you have two notifications. One that says "One" and one that says "Two". If you click on the notification "Two" it takes you to a screen that says "Two". Perfect!
现在你有两个通知。一说“一”,一说“二”。如果您单击通知“两个”,它会将您带到一个显示“两个”的屏幕。完美的!
If you click on the notification "One" it takes you to a screen that says "Two". BROKEN!
如果您单击通知“一”,它会将您带到显示“二”的屏幕。破碎的!
ResultActivity.java
结果活动.java
public class ResultActivity extends Activity {
String title = null;
TextView text;
int i=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
text = (TextView) findViewById(R.id.textView1);
title = getIntent().getStringExtra("title");
i = getIntent().getIntExtra("uid", 0);
text.setText(title);
}
采纳答案by Tobias Ritzau
You create multiple intents that are mixed. I cleaned up the code (but did not test it)
您创建了多个混合的意图。我清理了代码(但没有测试)
NotificationManager nm = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
Resources res = ctx.getResources();
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);
String pass = text.getText().toString();
resultIntent.setData(new Uri.Builder().scheme("data")
.appendQueryParameter("text", "my text").build());
resultIntent.putExtra("title", pass);
resultIntent.putExtra("uid", i);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
builder.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(
BitmapFactory.decodeResource(res,
R.drawable.ic_launcher))
.setTicker("Remember to " + text.getText())
.setWhen(System.currentTimeMillis()).setAutoCancel(true)
.setContentTitle(text.getText())
.setContentIntent(resultPendingIntent);
Notification n = builder.build();
n.flags = Notification.FLAG_NO_CLEAR;
nm.notify(i++, n);
text.setText(null);
回答by Γι?ργο? Χα?λαζ?πουλο?
I know this was a lot time ago but i feel that the answers have not said anything about the problem in your code.
So the problem is pretty much here
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
我知道这是很久以前的事了,但我觉得答案并没有说明您代码中的问题。所以问题就在这里
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
So you create a pendingIntent from the stackbuilder whith the flag of update_current. If you look at FLAG_UPDATE_CURRENT it says
因此,您从带有 update_current 标志的堆栈构建器中创建了一个 pendingIntent。如果你看看 FLAG_UPDATE_CURRENT 它说
/**
* Flag indicating that if the described PendingIntent already exists,
* then keep it but replace its extra data with what is in this new
* Intent. For use with {@link #getActivity}, {@link #getBroadcast}, and
* {@link #getService}. <p>This can be used if you are creating intents where only the
* extras change, and don't care that any entities that received your
* previous PendingIntent will be able to launch it with your new
* extras even if they are not explicitly given to it.
*/
public static final int FLAG_UPDATE_CURRENT = 1<<27;
So what happens in your use case is that you create two identical pendingintents from the stackbuilder and the second intent overrides the first one . Actually you never create a second you just update the extras of the first one.
因此,在您的用例中发生的情况是,您从 stackbuilder 创建了两个相同的待定意图,并且第二个意图覆盖了第一个意图。实际上,您永远不会创建第二个,您只需更新第一个的附加内容。
So unfortunately there is no available flag for your use case , but there is a good hack around it. What you can do is use the setAction of your resultIntent and place a random string or a string that makes sense to your app.
所以不幸的是,您的用例没有可用的标志,但是有一个很好的技巧可以解决它。您可以做的是使用 resultIntent 的 setAction 并放置一个随机字符串或对您的应用程序有意义的字符串。
eg. resultIntent.setAction("dummy_action_" + notification.id);
例如。 resultIntent.setAction("dummy_action_" + notification.id);
This will make your resultIntent unique enough , so that the pendingIntent will create it rather than updating a previous one.
这将使您的 resultIntent 足够独特,以便 pendingIntent 将创建它而不是更新前一个。
回答by Denis Rybnikov
Set different requestCode
helps me create and update current intent.
设置不同requestCode
有助于我创建和更新当前意图。
val pendingIntent = PendingIntent.getActivity(
this,
notificationID,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
回答by aamitarya
Use some random requestCode to seperate two notifications
使用一些随机的 requestCode 来分隔两个通知
PendingIntent pendingIntent = PendingIntent.getActivity(context, CommonTools.getRandomNumber(1, 100),
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
public int getRandomNumber(int min, int max) {
// min (inclusive) and max (exclusive)
Random r = new Random();
return r.nextInt(max - min) + min;
}