簡體   English   中英

生成int唯一ID作為android通知ID

[英]Generate int unique id as android notification id

當我發送多個推送通知時,我需要將它們全部顯示在按發送時間排序的通知欄中。 我知道我應該使用唯一通知 - 我試圖生成隨機數,但這並沒有解決我的問題,因為我需要訂購它們。 我嘗試使用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。

您對所有通知使用相同的通知 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的初始值應該從某個 Activity 的保存狀態初始化,而不是從 0 開始。如果通知 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;
}

像這樣使用它

int id = createID();
mNotifyManager.notify(id, mBuilder.build());
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;
}

也許不是最好的,但絕對最簡單的是使用當前時間。

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

好處:這是獲得增加 id 的最簡單方法。

壞處:時間很long ,我們將其縮短到一半。 這意味着計數器將每 2'147'483'647 /1000(ms->s)/60(s->m)/60(m->h)/24(h->d) =~ 25 天。

SystemClock.uptimeMillis()currentTimeMillis有兩個優點:

  1. 打折在深度睡眠中花費的所有毫秒數,這會減少環繞的數量。
  2. 手機重啟時從0開始。

您可以使用計數器並將其存儲在 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)

您需要設置一個唯一的標簽(字符串)/ id(整數)

在官方文檔中查看此方法

我建議在通知時使用任何時間戳 (SystemClock.uptimeMillis() / System.currentTimeMillis()) 作為標記。

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

如果有人讀這篇文章,有一種方法在這里 最好也指定一個帶有idtag名稱,這樣如果您將部件捆綁為一個模塊與開發人員共享,這將有所幫助。

注意:分配一些隨機整數 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());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM