Envoi d'une notification depuis un service sous Android


105

J'ai un service en cours d'exécution et je souhaite envoyer une notification. Dommage, l'objet de notification nécessite un Context, comme un Activity, et non un Service.

Connaissez-vous un moyen de contourner cela? J'ai essayé de créer un Activitypour chaque notification mais cela semble moche, et je ne trouve pas de moyen de lancer un Activitysans aucun View.


14
Euh ... un service est un contexte!
Isaac Waller

19
Dieu, je suis un idiot. Ok, désolé de perdre le temps de tout le monde.
e-satis

28
C'est bien - c'est une bonne question à Google.
Isaac Waller

Comme votre deuxième commentaire: D: D
Faizan Mubasher

Ce message vient de sauver ma journée ...
Muhammad Faizan

Réponses:


109

Les deux Activityet en Servicefait extend Context, vous pouvez simplement l'utiliser thiscomme votre Contextdans votre Service.

NotificationManager notificationManager =
    (NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
Notification notification = new Notification(/* your notification */);
PendingIntent pendingIntent = /* your intent */;
notification.setLatestEventInfo(this, /* your content */, pendingIntent);
notificationManager.notify(/* id */, notification);

4
Gardez à l'esprit que vous rencontrerez de nombreux problèmes lors de la notification d'un service. Si vous rencontrez des problèmes, jetez un œil à ce groups.google.com/group/android-developers/browse_thread/thread/…
Karussell

1
comment pouvez-vous faire cela en utilisant Notification.Builder? car setLatestEventInfo est déjà obsolète.
Kairi San

77

Ce type de notification est obsolète comme on le voit dans les documents:

@java.lang.Deprecated
public Notification(int icon, java.lang.CharSequence tickerText, long when) { /* compiled code */ }

public Notification(android.os.Parcel parcel) { /* compiled code */ }

@java.lang.Deprecated
public void setLatestEventInfo(android.content.Context context, java.lang.CharSequence contentTitle, java.lang.CharSequence contentText, android.app.PendingIntent contentIntent) { /* compiled code */ }

Meilleure façon
Vous pouvez envoyer une notification comme celle-ci:

// prepare intent which is triggered if the
// notification is selected

Intent intent = new Intent(this, NotificationReceiver.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);

// build notification
// the addAction re-use the same intent to keep the example short
Notification n  = new Notification.Builder(this)
        .setContentTitle("New mail from " + "test@gmail.com")
        .setContentText("Subject")
        .setSmallIcon(R.drawable.icon)
        .setContentIntent(pIntent)
        .setAutoCancel(true)
        .addAction(R.drawable.icon, "Call", pIntent)
        .addAction(R.drawable.icon, "More", pIntent)
        .addAction(R.drawable.icon, "And more", pIntent).build();


NotificationManager notificationManager = 
  (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

notificationManager.notify(0, n); 

Meilleur moyen Le
code ci-dessus nécessite un niveau d'API minimum 11 (Android 3.0).
Si votre niveau d'API minimum est inférieur à 11, vous devez utiliser la classe NotificationCompat de la bibliothèque de support comme ceci.

Donc, si votre niveau d'API cible minimum est 4+ (Android 1.6+), utilisez ceci:

    import android.support.v4.app.NotificationCompat;
    -------------
    NotificationCompat.Builder builder =
            new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.mylogo)
                    .setContentTitle("My Notification Title")
                    .setContentText("Something interesting happened");
    int NOTIFICATION_ID = 12345;

    Intent targetIntent = new Intent(this, MyFavoriteActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(contentIntent);
    NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    nManager.notify(NOTIFICATION_ID, builder.build());

4
cela devrait être la meilleure réponse puisque celle acceptée est obsolète
Marcel Krivek

4
@MarcelKrivek Semble qu'il ou elle a "oublié" de citer leur source. vogella.com/tutorials/AndroidNotifications/article.html
StarWind0

Qu'est-ce que "NotificationReceiver"?
user3690202

"NotificationReceiver" est l'activité qui sera ouverte par la notification. Vérifiez le lien fourni par @ StarWind0.
George Theodorakis

NotificationCompat.Builder est déjà obsolète. Ce n'est plus la meilleure réponse
Devil's Dream

7
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void PushNotification()
{
    NotificationManager nm = (NotificationManager)context.getSystemService(NOTIFICATION_SERVICE);
    Notification.Builder builder = new Notification.Builder(context);
    Intent notificationIntent = new Intent(context, MainActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(context,0,notificationIntent,0);

    //set
    builder.setContentIntent(contentIntent);
    builder.setSmallIcon(R.drawable.cal_icon);
    builder.setContentText("Contents");
    builder.setContentTitle("title");
    builder.setAutoCancel(true);
    builder.setDefaults(Notification.DEFAULT_ALL);

    Notification notification = builder.build();
    nm.notify((int)System.currentTimeMillis(),notification);
}

La question du sujet provient d'un SERVICE et non d'une activité
Duna

1

Eh bien, je ne suis pas sûr que ma solution soit la meilleure pratique. Utiliser NotificationBuildermon code ressemble à ça:

private void showNotification() {
    Intent notificationIntent = new Intent(this, MainActivity.class);

    PendingIntent contentIntent = PendingIntent.getActivity(
                this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(contentIntent);
    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.notify(NOTIFICATION_ID, builder.build());
    }

Manifeste:

    <activity
        android:name=".MainActivity"
        android:launchMode="singleInstance"
    </activity>

et ici le Service:

    <service
        android:name=".services.ProtectionService"
        android:launchMode="singleTask">
    </service>

Je ne sais pas s'il y a vraiment un singleTaskat Servicemais cela fonctionne correctement dans mon application ...


quel est le constructeur là-dedans?
Viswanath Lekshmanan

-2

Si aucun de ces éléments ne fonctionne, essayez getBaseContext()plutôt que contextou this.


2
Vous ne devez pas utiliser getBaseContext()ces scénarios.
Rahat Zaman
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.