Pergunta

Eu tenho um serviço em execução, e gostaria de enviar uma notificação. Muito ruim, o objeto de notificação requer um Context, como um Activity, e não um Service.

Você conhece alguma maneira de by pass isso? Tentei criar uma Activity para cada notificação, mas parece feio, e eu não consigo encontrar uma maneira de lançar um Activity sem qualquer View.

Foi útil?

Solução

Ambos Activity e Service realmente extend Context assim você pode simplesmente usar this como seu Context dentro do seu 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);

Outras dicas

Este tipo de notificação é obsoleto como visto de 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 */ }

melhor maneira
Você pode enviar uma notificação 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); 

Melhor maneira
Código acima do nível necessidades mínimo API 11 (Android 3.0).
Se o seu nível mínimo API é inferior a 11, você deve utilizar 's NotificationCompat classe como isso.

Portanto, se seu nível mínimo alvo API é 4+ (Android 1.6+) usar este:

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

Bem, eu não tenho certeza se a minha solução é a melhor prática. Usando o NotificationBuilder meus olhares de código assim:

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

manifesto:

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

e aqui o Serviço:

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

Eu não sei se há realmente uma singleTask em Service mas isso funciona corretamente em minha aplicação ...

Se nenhum desses funcionar, tente getBaseContext(), em vez de context ou this.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top