Envío de una notificación desde un servicio en Android


105

Tengo un servicio en ejecución y me gustaría enviar una notificación. Lástima, el objeto de notificación requiere un Context, como un Activity, y no un Service.

¿Conoce alguna forma de evitarlo? Traté de crear una Activitypara cada notificación, pero parece fea y no puedo encontrar la manera de iniciar una Activitysin ninguna View.


14
Umm ... ¡un servicio es un contexto!
Isaac Waller

19
Dios, soy un idiota. Ok, lamento perder el tiempo de todos.
e-satis

28
Está bien, es una buena pregunta de Google.
Isaac Waller

Como su segundo comentario: D: D
Faizan Mubasher

Esta publicación me acaba de salvar el día ...
Muhammad Faizan

Respuestas:


109

Ambos Activityy, de Servicehecho extend Context, puede usarlos simplemente thiscomo su Contextdentro de su 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
Tenga en cuenta que tendrá muchos problemas al realizar las notificaciones de un servicio. Si tiene problemas, eche un vistazo a este groups.google.com/group/android-developers/browse_thread/thread/…
Karussell

1
¿Cómo se puede hacer esto usando Notification.Builder? porque setLatestEventInfo ya está obsoleto.
Kairi San

77

Este tipo de notificación está en desuso como se ve en los documentos:

@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 */ }

Mejor manera
Puede enviar una notificación como esta:

// 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); 

La mejor forma El
código anterior necesita un nivel mínimo de API 11 (Android 3.0).
Si su nivel mínimo de API es inferior a 11, debería usar la clase NotificationCompat de la biblioteca de soporte de esta manera.

Entonces, si su nivel mínimo de API objetivo es 4+ (Android 1.6+), use esto:

    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
esta debería ser la mejor respuesta ya que la aceptada está obsoleta
Marcel Krivek

4
@MarcelKrivek Parece que "olvidó" citar su fuente. vogella.com/tutorials/AndroidNotifications/article.html
StarWind0

¿Qué es "NotificationReceiver"?
user3690202

"NotificationReceiver" es la actividad que se abrirá mediante la notificación. Consulte el enlace proporcionado por @ StarWind0.
George Theodorakis

NotificationCompat.Builder ya está en desuso. Ahora ya no es la mejor respuesta
el sueño del diablo

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 pregunta del tema es de un SERVICIO, no una actividad
Duna

1

Bueno, no estoy seguro de si mi solución es la mejor práctica. El uso de NotificationBuildermi código se ve así:

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

Manifiesto:

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

y aquí el Servicio:

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

No sé si realmente hay un singleTaskat, Servicepero esto funciona correctamente en mi aplicación ...


¿Qué es el constructor en esto?
Viswanath Lekshmanan

-2

Si ninguno de estos funciona, intente getBaseContext(), en lugar de contexto this.


2
No debe utilizar getBaseContext()estos escenarios.
Rahat Zaman
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.