Отправка уведомления от сервиса в Android - PullRequest
98 голосов
/ 30 июля 2009

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

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

Ответы [ 5 ]

105 голосов
/ 30 июля 2009

И 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);
74 голосов
/ 28 октября 2013

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

@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 " + "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); 

Лучший способ
Код выше требует минимального уровня API 11 (Android 3.0).
Если ваш минимальный уровень API ниже 11, вам следует использовать support library Класс 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());
7 голосов
/ 28 сентября 2015
@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);
}
1 голос
/ 02 октября 2014

Ну, я не уверен, что мое решение - лучшая практика. Используя 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 в Service, но это правильно работает в моем приложении ...

0 голосов
/ 17 апреля 2016

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...