web-dev-qa-db-fra.com

Générer un identifiant unique int en tant qu'identifiant de notification Android

Lorsque j'envoie plusieurs notifications Push, j'ai besoin qu'elles soient toutes affichées dans la barre de notification, en ordre chronologique. Je sais que je devrais utiliser une notification unique - j'ai essayé de générer un nombre aléatoire, mais cela n'a pas résolu mon problème car j'ai besoin qu'ils soient commandés. J'ai essayé d'utiliser AtomicInt et je n'ai toujours pas le résultat souhaité.

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

J'ai besoin de la meilleure façon et la plus simple de générer un identifiant int qui est incrémental pour l'attribuer comme identifiant de notification.

37
Zenogrammer

Vous utilisez le même ID de notification (la valeur est toujours 1) pour toutes vos notifications. Vous devriez probablement séparer l'ID de notification dans une classe singleton distincte:

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

Utilisez ensuite NotificationID.getID() au lieu de NOTIFICATION_ID dans votre code.

EDIT: Comme le souligne @racs dans un commentaire, l’approche ci-dessus n’est pas suffisante pour garantir un comportement correct si le processus de votre application est tué. Au minimum, la valeur initiale de AtomicInteger doit être initialisée à partir de l'état de sauvegarde de certaines activités plutôt que de commencer à 0. Si les ID de notification doivent être uniques pour tous les redémarrages de l'application (là encore, le processus de l'application peut être interrompu), alors la dernière valeur devrait être sauvegardée quelque part (probablement dans les préférences partagées) après chaque incrément et restaurée au démarrage de l'application.

71
Ted Hopp

Pour tous ceux qui cherchent encore. J'ai généré un horodatage et je l'ai utilisé comme identifiant.

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

Utilisez-le comme ça

int id = createID();
mNotifyManager.notify(id, mBuilder.build());
19
Adetunji Mohammed
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;
}
11
Raphael C

Vous pouvez utiliser un compteur et le stocker dans les SharedPreferences . Voici un exemple dans 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
}

il obtiendra l'id et stockera l'id suivant (augmenté de 1). Si l'id atteint la valeur maximale pour un entier, il sera remis à 0.

Vous pouvez l'utiliser comme ceci:

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

Peut-être pas le meilleur, mais certainement le plus simple est d'utiliser l'heure actuelle. 

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

Les points positifs: c’est le moyen le plus simple d’obtenir des identifiants croissants.

Le mauvais: le temps est une long et nous le tronquons à la moitié. Cela signifie que le compteur sera bouclé tous les 2'147'483'647/1000 (ms-> s)/60 (s-> m)/60 (m-> h)/24 (h-> d) = ~ 25 jours.

SystemClock.uptimeMillis() a 2 avantages sur currentTimeMillis:

  1. réduit toutes les millisecondes passées en sommeil profond, ce qui diminue le nombre d'enveloppements.
  2. commence à 0 lorsque le téléphone est redémarré.
1
Agent_L

Si quelqu'un lit ceci, il existe une méthode ici . il est préférable de spécifier également un nom tag avec id, de manière à vous aider si vous regroupez la pièce dans un module à partager avec les développeurs.

REMARQUE: Le problème avec l'attribution d'un identifiant entier aléatoire est que, si un module ou une bibliothèque utilise le même identifiant, votre notification sera remplacée par de nouvelles données de notification.

// 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
I Am Batman