生成int unique id作为android通知id

时间:2022-11-25 11:26:16

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.

当我发送多个推送通知时,我需要它们全部显示在发送时间desc的通知栏中。我知道我应该使用独特的通知 - 我试图生成随机数,但这并没有解决我的问题,因为我需要它们被订购。我试图使用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。

5 个解决方案

#1


58  

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在应用程序重新启动时需要是唯一的(同样,应用程序进程可能会被终止),然后在每次增量后将最新值保存在某处(可能是共享的prefs),并在应用程序启动时恢复。

#2


16  

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());

#3


7  

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;
}

#4


0  

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.

如果有人读这个,这里有一个方法。最好同时使用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());

#5


0  

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)

#1


58  

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在应用程序重新启动时需要是唯一的(同样,应用程序进程可能会被终止),然后在每次增量后将最新值保存在某处(可能是共享的prefs),并在应用程序启动时恢复。

#2


16  

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());

#3


7  

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;
}

#4


0  

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.

如果有人读这个,这里有一个方法。最好同时使用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());

#5


0  

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)