Java 生成int唯一ID作为android通知ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25713157/
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
Generate int unique id as android notification id
提问by Zenogrammer
When I send multiple push notifications, I need them to be all shown in the notification bar ordered by the time sent desc. I know I should use unique notification - I tried to generate random number but that did not solve my problem since I need them to be ordered. I tried to use AtomicInt
and still don't have the desired result.
当我发送多个推送通知时,我需要将它们全部显示在按发送时间排序的通知栏中。我知道我应该使用唯一通知 - 我试图生成随机数,但这并没有解决我的问题,因为我需要订购它们。我尝试使用AtomicInt
,但仍然没有想要的结果。
package com.mypackage.lebadagency;
import java.util.concurrent.atomic.AtomicInteger;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.RemoteViews;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GCMNotificationIntentService extends IntentService {
private AtomicInteger c = new AtomicInteger(0);
public int NOTIFICATION_ID = c.incrementAndGet();
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMNotificationIntentService() {
super("GcmIntentService");
}
public static final String TAG = "GCMNotificationIntentService";
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
.equals(messageType)) {
sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ extras.toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
for (int i = 0; i < 3; i++) {
Log.i(TAG,
"Working... " + (i + 1) + "/5 @ "
+ SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
sendNotification(""
+ extras.get(Config.MESSAGE_KEY));
Log.i(TAG, "Received: " + extras.toString());
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
//here start
Intent gcmintent = new Intent(this, AppGcmStation.class);
gcmintent.putExtra("ntitle", msg);
gcmintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
int requestID = (int) System.currentTimeMillis();
//here end
PendingIntent contentIntent = PendingIntent.getActivity(this, requestID,
gcmintent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("my title")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setAutoCancel(true);
mBuilder.setTicker(msg);
mBuilder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
mBuilder.setLights(Color.RED, 3000, 3000);
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Log.d(TAG, "Notification sent successfully.");
}
}
I need the BEST and simplest way to generate an int id which is incremental to assign it as the notification id.
我需要最好和最简单的方法来生成一个 int id,它是递增的以将其分配为通知 id。
采纳答案by Ted Hopp
You are using the same notification ID (the value is always 1) for all your notifications. You probably should separate out the notification ID into a separate singleton class:
您对所有通知使用相同的通知 ID(值始终为 1)。您可能应该将通知 ID 分离到一个单独的单例类中:
public class NotificationID {
private final static AtomicInteger c = new AtomicInteger(0);
public static int getID() {
return c.incrementAndGet();
}
}
Then use NotificationID.getID()
instead of NOTIFICATION_ID
in your code.
然后在您的代码中使用NotificationID.getID()
而不是NOTIFICATION_ID
。
EDIT: As @racs points out in a comment, the above approach is not enough to ensure proper behavior if your app process happens to be killed. At a minimum, the initial value of the AtomicInteger
should be initialized from some activity's saved state rather than starting at 0. If the notification IDs need to be unique across restarts of the app (again, where the app process may be killed off), then the latest value should be saved somewhere (probably to shared prefs) after every increment and restored when the app starts.
编辑:正如@racs 在评论中指出的那样,如果您的应用程序进程碰巧被终止,上述方法不足以确保正确的行为。至少, 的初始值AtomicInteger
应该从某个活动的保存状态初始化,而不是从 0 开始。如果通知 ID 需要在应用程序重新启动时是唯一的(同样,应用程序进程可能会被终止),那么每次增量后应将最新值保存在某处(可能保存到共享首选项)并在应用程序启动时恢复。
回答by Adetunji Mohammed
For anyone still looking around. I generated a timestamp and used it as the id.
对于仍在环顾四周的任何人。我生成了一个时间戳并将其用作 id。
import java.util.Date;
import java.util.Locale;
public int createID(){
Date now = new Date();
int id = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.US).format(now));
return id;
}
Use it like so
像这样使用它
int id = createID();
mNotifyManager.notify(id, mBuilder.build());
回答by Raphael C
private static final String PREFERENCE_LAST_NOTIF_ID = "PREFERENCE_LAST_NOTIF_ID";
private static int getNextNotifId(Context context) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
int id = sharedPreferences.getInt(PREFERENCE_LAST_NOTIF_ID, 0) + 1;
if (id == Integer.MAX_VALUE) { id = 0; } // isn't this over kill ??? hahaha!! ^_^
sharedPreferences.edit().putInt(PREFERENCE_LAST_NOTIF_ID, id).apply();
return id;
}
回答by Renjith Thankachan
If someone reading this, there is a method here. it is better to specify a tag
name also with id
, so that it will help if you are bundling the part as a module to share with developers.
如果有人读这篇文章,有一种方法在这里。最好tag
也用指定一个名称id
,这样如果您将部件捆绑为一个模块与开发人员共享,这将有所帮助。
NOTE: The problem with assigning some random integer id is that, if any module or library uses the same id, your notification will be replaced by new notification data.
注意:分配一些随机整数 id 的问题是,如果任何模块或库使用相同的 id,您的通知将被新的通知数据替换。
// here createID method means any generic method of creating an integer id
int id = createID();
// it will uniqly identify your module with uniq tag name & update if present.
mNotifyManager.notify("com.packagename.app", id, mBuilder.build());
回答by Chuy47
You can use a counter and store it in the SharedPreferences. This is an example in kotlin:
您可以使用计数器并将其存储在 SharedPreferences 中。这是 kotlin 中的一个例子:
fun getNextNotificationId(context: Context) : Int {
val sp = context.getSharedPreferences("your_shared_preferences_key", MODE_PRIVATE)
val id = sp.getInt("notification_id_key", 0)
sp.edit().putInt("notification_id_key", (id + 1) % Int.MAX_VALUE).apply()
return id
}
it will get the id and it will store the next id (increased by 1), also if the id reaches the max value for an integer it will be reset to 0.
它将获取 id 并存储下一个 id(增加 1),如果 id 达到整数的最大值,它将被重置为 0。
You can use it like this:
你可以这样使用它:
val notificationId = getNextNotificationId(applicationContext)
notificationManager.notify(notificationId, yourNotification)
回答by Agent_L
Maybe not the best, but definitely the simplestis to use current time.
也许不是最好的,但绝对最简单的是使用当前时间。
int oneTimeID = (int) SystemClock.uptimeMillis();
mNotificationManager.notify(oneTimeID, mBuilder.build());
The good: this is the easiest way to get increasing ids.
好处:这是获得增加 id 的最简单方法。
The bad: time is a long
and we're truncating it to half of that. This means that the counter will wrap around every 2'147'483'647 /1000(ms->s)/60(s->m)/60(m->h)/24(h->d) =~25 days.
坏处:时间是一个long
,我们将它截断到一半。这意味着计数器将每 2'147'483'647 /1000(ms->s)/60(s->m)/60(m->h)/24(h->d) =~ 25 天。
SystemClock.uptimeMillis()
has 2 advantages over currentTimeMillis
:
SystemClock.uptimeMillis()
有 2 个优点currentTimeMillis
:
- discounts all the milliseconds spent at deep sleep, what decreases amount of wraparounds.
- starts at 0 when the phone is restarted.
- 打折在深度睡眠中花费的所有毫秒数,这减少了环绕的数量。
- 手机重启时从0开始。
回答by ImBatman
You need to set either a unique tag (String) / id (integer)
您需要设置一个唯一的标签(字符串)/ id(整数)
Checkout this method in official documentaation
I suggest using any timestamp (SystemClock.uptimeMillis() / System.currentTimeMillis()) as a tag while notifying.
我建议在通知时使用任何时间戳 (SystemClock.uptimeMillis() / System.currentTimeMillis()) 作为标记。
notificationManager.notify(String.valueOf(System.currentTimeMillis()), 0, notification);