Отправка уведомления из службы на Android

У меня есть служба, и я хочу отправить уведомление. Слишком плохо, для объекта уведомления требуется контекст, например Activity, а не служба.

Знаете ли вы какой-либо способ пройти мимо? Я попытался создать Activity для каждого уведомления, это кажется уродливым, и я не могу найти способ запуска Activity без какого-либо представления.

Ответ 1

Оба Activity и Service на самом деле extend Context, поэтому вы можете просто использовать this в качестве Context в пределах 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);

Ответ 2

Этот тип уведомления устарел, как видно из документов:

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

Лучший способ
Вы можете отправить уведомление следующим образом:

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

Лучший способ
Для кода выше требуется минимальный уровень API 11 (Android 3.0).
Если ваш минимальный уровень API ниже 11, вы должны использовать поддержку библиотеки класса NotificationCompat, как это.

Итак, если ваш минимальный целевой уровень API 4+ (Android 1.6+), используйте это:

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

Ответ 3

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

Ответ 4

Ну, я не уверен, что мое решение - лучшая практика. С помощью NotificationBuilder мой код выглядит следующим образом:

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

Манифест:

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

и здесь Служба:

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

Я не знаю, действительно ли есть singleTask at Service, но это нормально работает в моем приложении...

Ответ 5

Если ни одна из них не работает, попробуйте getBaseContext() вместо context или this.