在Android中从服务发送通知

113

我有一个正在运行的服务,想要发送通知。不幸的是,通知对象需要一个像 Activity 而不是 ServiceContext
你知道有什么方法可以绕过这个问题吗?我尝试为每个通知创建一个 Activity,但是这看起来很丑陋,并且我找不到一种不带任何 View 启动 Activity 的方法。

15
嗯,一个服务就是一个上下文! - Isaac Waller
20
神啊,我真是个傻瓜。好的,抱歉浪费大家的时间。 - Bite code
32
好的 - 这是一个很好的谷歌问题。 - Isaac Waller
5个回答

113

ActivityService都实际上扩展了Context,因此您可以在Service中使用this作为Context

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
请记住,从服务中进行通知可能会遇到许多问题。如果您遇到问题,请查看此链接:http://groups.google.com/group/android-developers/browse_thread/thread/e95740e776982f89 - Karussell
1
你如何使用Notification.Builder来完成这个任务?因为setLatestEventInfo已经被弃用了。 - Kairi San

80

这种类型的通知已经被废弃,如文档所示:

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

最佳方法
以上代码需要Android 3.0以上的最低API级别11。
如果您的最低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());

4
这应该是最佳答案,因为已接受的答案已经过时。 - Marcel Krivek
4
@MarcelKrivek似乎“忘记”引用他们的来源。 http://www.vogella.com/tutorials/AndroidNotifications/article.html - StarWind0
什么是“NotificationReceiver”? - user3690202
“NotificationReceiver” 是将由通知打开的活动。请查看 @StarWind0 提供的链接。 - George Theodorakis
NotificationCompat.Builder已经被弃用。现在不再是最佳答案。 - 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);
}

该主题问题来自于一个服务而不是活动。 - Duna

1

我不确定我的解决方案是否是最佳实践。使用 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>

我不确定在Service中是否真的有singleTask,但是这在我的应用程序中可以正常工作...


这里的Builder是什么? - Viswanath Lekshmanan

-3
如果以上方法都不起作用,可以尝试使用getBaseContext()代替contextthis

2
在这些情况下,您不应该使用getBaseContext() - Rahat Zaman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接