在安卓系统中实现startForeground方法

15

我希望在 Service 类中实现 startForeground() 方法,以防止服务自我关闭。

有人能否向我发送实现此方法的代码?

4个回答

28
Jovan,这里有一种方法可以使2.0+和1.6-之间的代码兼容(代码展示了如何检测哪个版本是兼容的)。 http://android-developers.blogspot.com/2010/02/service-api-changes-starting-with.html 对于2.0+,我编写了一些示例代码(使用startForeground)。请注意,某些代码现在已经过时,但是Notification.Builder使用API级别11(3.x),这意味着在大多数手机使用兼容的Android版本之前,我不会使用它。由于绝大多数手机现在都运行着某个版本的2.x,因此跳过兼容性检查应该是足够安全的。
final static int myID = 1234;

//The intent to launch when the user clicks the expanded notification
Intent intent = new Intent(this, SomeActivityToLaunch.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);

//This constructor is deprecated. Use Notification.Builder instead
Notification notice = new Notification(R.drawable.icon_image, "Ticker text", System.currentTimeMillis());

//This method is deprecated. Use Notification.Builder instead.
notice.setLatestEventInfo(this, "Title text", "Content text", pendIntent);

notice.flags |= Notification.FLAG_NO_CLEAR;
startForeground(myID, notice);

将这段代码放在您的service的onStartCommand()中即可。但是,您可以将此部分代码放在service的任何位置。

附言:要停止服务处于前台状态,只需在您的service中的任何位置使用stopForeground(true);


为什么在前台运行的服务中需要设置FLAG_NO_CLEAR标志?有没有一种方法可以“清除”前台服务的通知?我知道AUTO_CANCEL不起作用。 - Eduardo
1
为什么不使用支持库中提供的通知构建器兼容性来获得新API的优势,保持兼容性,而不编写已弃用的代码呢? - Abandoned Cart
@TwistedUmbrella:Android仍在不断发展……在撰写本文时,Android支持库尚未提供此功能。 - Someone Somewhere
2
@SomeoneSomewhere 在不更新答案的情况下留下这样的评论是不好的做法。我已经进行了必要的更改,并为那些偶然遇到此主题的人提交了新的答案。 - Abandoned Cart
嘿,ID是做什么用的? - Ruchir Baronia
Ruchir Baronia- 通知需要一个非零ID。 - Saik Caskey

7

这段代码将通过将Android支持库添加到您的项目中,使用最佳可用选项来调用任何API。在Eclipse中,您可以右键单击项目,转到Android工具,然后单击“添加支持库…”选项来下载并添加它。

final static int myID = 1234;

//The intent to launch when the user clicks the expanded notification
Intent intent = new Intent(this, SomeActivityToLaunch.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);

if (Integer.parseInt(Build.VERSION.SDK) >= Build.VERSION_CODES.DONUT) {
// Build.VERSION.SDK_INT requires API 4 and would cause issues below API 4

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setTicker("TICKER").setContentTitle("TITLE").setContentText("CONTENT")
            .setWhen(System.currentTimeMillis()).setAutoCancel(false)
            .setOngoing(true).setPriority(Notification.PRIORITY_HIGH)
            .setContentIntent(pendIntent);
    Notification notification = builder.build();

} else {

    Notification notice = new Notification(R.drawable.icon_image, "Ticker text", System.currentTimeMillis());
    notice.setLatestEventInfo(this, "Title text", "Content text", pendIntent);

}
notification.flags |= Notification.FLAG_NO_CLEAR;
startForeground(myID, notification);

将代码放在你用于服务的start方法中,当你想要停止前台进程时,在你的服务中的任何位置调用stopForeground(true);


4
你漏掉了 builder.setSmallIcon(int)。没有这个自定义构建器将被默认通知忽略。 - Konstantin Konopko
这个问题不是关于如何实现自定义通知的,而是关于如何使用startForeground()方法。除此之外,你可以根据个人喜好进行其他操作。 - Abandoned Cart

1

我正在寻找在Android 2.0上实现startForeground的方法,这个示例是用于API级别5之前的实现。谢谢。 - Jovan
ID是做什么用的? - Ruchir Baronia

0

我不确定这是否是您要寻找的内容,但您只需创建一个通知对象(如下所示的mOngoingNote),并使用通知ID以及实际通知调用startForeground即可。

    startForeground(NOTEMAN_ID, mOngoingNote);

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