我是靠谱客的博主 狂野咖啡,这篇文章主要介绍Android Service startForeground() 可能不显示Notification问题,现在分享给大家,希望可以做个参考。

Android中的Service分前台服务和后台服务两类:

前台服务会在通知栏有一条不能被手动清除的Notification,当此前台服务由于内存不足而被系统kill掉的时候,此Notification也会同时消失,用户由此得知此服务已经停止了,起到一个通知用户服务是否还在工作;

后台服务则没有类似的Notification,即使被系统kill掉,用户也不会得到什么通知。

Service通过调用方法 startForeground (int id, Notification notification)方法设置是否为前台任务,如:

复制代码
1
2
3
4
5
6
7
8
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), System.currentTimeMillis()); Intent notificationIntent = new Intent(this, ViewServerActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(this, getText(R.string.notification_title, getText(R.string.notification_message), pendingIntent); startForeground(ONGOING_NOTIFICATION, notification);

由此代码引发了一个需要特别注意的事情,代码片段中的NOGOING_NOTIFICATION的值,不能是0,否则就不会显示出Notification,究其原因只能看源码了:

service startForeground()和stopForeground()源码:

复制代码
1
2
3
4
5
6
7
8
9
public final void startForeground(int id, Notification notification) { try { mActivityManager.setServiceForeground( new ComponentName(this, mClassName), mToken, id, notification, true); } catch (RemoteException ex) { } }

复制代码
1
2
3
4
5
6
7
8
9
public final void stopForeground(boolean removeNotification) { try { mActivityManager.setServiceForeground( new ComponentName(this, mClassName), mToken, 0, null, removeNotification); } catch (RemoteException ex) { } }

可见是有mActivityManager.setServiceForeground()里面做了封装,mActivityManager是一个IActivityManager接口的实现类,此接口实现类的关系具体参考此博文:

http://blog.csdn.net/stonecao/article/details/6579710

其实最终运行到的是ActiveServices类中的setServiceForegroundLocked方法:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public void setServiceForegroundLocked(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification) { final int userId = UserHandle.getCallingUserId(); final long origId = Binder.clearCallingIdentity(); try { ServiceRecord r = findServiceLocked(className, token, userId); if (r != null) { if (id != 0) { if (notification == null) { throw new IllegalArgumentException("null notification"); } if (r.foregroundId != id) { r.cancelNotification(); r.foregroundId = id; } notification.flags |= Notification.FLAG_FOREGROUND_SERVICE; r.foregroundNoti = notification; r.isForeground = true; r.postNotification(); if (r.app != null) { updateServiceForegroundLocked(r.app, true); } getServiceMap(r.userId).ensureNotStartingBackground(r); } else { if (r.isForeground) { r.isForeground = false; if (r.app != null) { mAm.updateLruProcessLocked(r.app, false, false); updateServiceForegroundLocked(r.app, true); } } if (removeNotification) { r.cancelNotification(); r.foregroundId = 0; r.foregroundNoti = null; } } } } finally { Binder.restoreCallingIdentity(origId); } }
至此,我们应该很清楚了,如果传进来的id=0,则直接执行以下代码了:

复制代码
1
2
3
4
5
if (removeNotification) { r.cancelNotification(); r.foregroundId = 0; r.foregroundNoti = null; }
最后直接cancleNotification(),所以传id=0,就相当于取消notification显示!

从google上的文档看到以下参数说明:

Parameters
id The identifier for this notification as per NotificationManager.notify(int, Notification); must not be 0.
notification The Notification to be displayed.
See Also
  • stopForeground(boolean)

但是在我的eclipse中的javadoc却是看不到“must not be 0”的说明的!


最后

以上就是狂野咖啡最近收集整理的关于Android Service startForeground() 可能不显示Notification问题的全部内容,更多相关Android内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(99)

评论列表共有 0 条评论

立即
投稿
返回
顶部