生成int唯一id作为android通知id

问题描述 投票:0回答:8

当我发送多个推送通知时,我需要将它们全部显示在通知栏中,并按发送时间顺序排列。我知道我应该使用唯一的通知 - 我尝试生成随机数,但这并没有解决我的问题,因为我需要订购它们。我尝试使用

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.");
  }
}

我需要最好、最简单的方法来生成一个增量的 int id,将其分配为通知 id。

java android push-notification
8个回答
114
投票

您对所有通知使用相同的通知 ID(值始终为 1)。您可能应该将通知 ID 分离到一个单独的单例类中:

public class NotificationID {
    private final static AtomicInteger c = new AtomicInteger(0);
    public static int getID() {
        return c.incrementAndGet();
    }
}

然后在代码中使用

NotificationID.getID()
而不是
NOTIFICATION_ID

编辑:正如 @racs 在评论中指出的那样,如果您的应用程序进程恰好被终止,上述方法不足以确保正确的行为。至少,

AtomicInteger
的初始值应从某些活动的保存状态进行初始化,而不是从 0 开始。如果通知 ID 在应用程序重新启动时需要唯一(同样,应用程序进程可能会被终止) ),那么最新值应该在每次增量后保存在某个地方(可能是共享首选项),并在应用程序启动时恢复。


37
投票

对于仍在四处张望的人。我生成了一个时间戳并将其用作 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;
}

像这样使用它

int id = createID();
mNotifyManager.notify(id, mBuilder.build());

22
投票

也许不是最好的,但绝对是最简单的是使用当前时间。

int oneTimeID = (int) SystemClock.uptimeMillis();
mNotificationManager.notify(oneTimeID, mBuilder.build());

优点:这是增加 ids 的最简单方法。

缺点:时间是

long
,我们将其截断为一半。这意味着计数器将每 2'147'483'647 /1000(ms->s)/60(s->m)/60(m->h)/24(h->d) =~ 25天。

SystemClock.uptimeMillis()
currentTimeMillis
有2个优点:

  1. 减少深度睡眠所花费的所有毫秒,从而减少环绕次数。
  2. 手机重启时从0开始。

18
投票
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;
}

5
投票

您可以使用计数器并将其存储在 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
}

它将获取 id 并存储下一个 id(加 1),如果 id 达到整数的最大值,它将被重置为 0。

你可以这样使用它:

val notificationId = getNextNotificationId(applicationContext)
notificationManager.notify(notificationId, yourNotification)

5
投票

您需要设置一个唯一的标签(字符串)/ id(整数)

在官方文档中查看此方法

我建议在通知时使用任何时间戳(SystemClock.uptimeMillis() / System.currentTimeMillis())作为标签。

 notificationManager.notify(String.valueOf(System.currentTimeMillis()), 0, notification);

1
投票

如果有人读到这篇文章,有一个方法这里。最好同时指定

tag
名称和
id
,这样如果您将部件捆绑为模块以与开发人员共享,这将会有所帮助。

注意:分配一些随机整数 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());

0
投票

我这里用的是简单的方法。

只需使用 NotificationManager 中的方法 notify 和参数 tag。您将使用 tag 仅对带有您创建的标签的通知进行计数。使用您选择的标签。基本方法如下。

public void notify(String tag, int id, Notification notification) {
    notifyAsUser(tag, id, notification, mContext.getUser()); 
}

我们将使用带有 tag 的版本,因为如果您发送 1 个或多个通知,Android 可以生成带有标签 ranker_group 的其他通知,如果您使用不带 tag 参数的通知,您将计数它。

要获取下一个notificationId,请使用以下方法:

private fun getNextNotificationId(): Int {
    val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    val activeNotifications =
        notificationManager.activeNotifications
            .filter { it.tag == packageName }
    return if (activeNotifications.isEmpty()) {
        0
    } else {
        Collections.max(activeNotifications.map { it.id }) + 1
    }
}
  • 在上面的代码中,您将浏览带有您选择的标签的所有活动通知。这里我使用 packageName,返回应用程序包的上下文变量。
  • 如果您没有任何通知,它将从索引 0 开始。
  • 如果您有 1 个或多个通知,请使用所有通知 ID 的映射中的 Collections.max 获取最大通知 ID。当您拥有最大的现有 id 时,请增加 1 以获取要在通知中使用的下一个通知 id。

准备好!

© www.soinside.com 2019 - 2024. All rights reserved.