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.

e-satis
la source
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);
Josef Pfleger
la source
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 " + "[email protected]")
        .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());
trante
la source
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 source
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 ...

Martin Pfeffer
la source
quel est le constructeur là-dedans?
Viswanath Lekshmanan
-2

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

kurdist android
la source
2
Vous ne devez pas utiliser getBaseContext()ces scénarios.
Rahat Zaman