当前位置:   article > 正文

Android Service startForeground() 可能不显示Notification问题_android 没有通知的前台service

android 没有通知的前台service

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

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

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

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

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

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

service startForeground()和stopForeground()源码:

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

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

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

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

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

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

  1. if (removeNotification) {
  2. r.cancelNotification();
  3. r.foregroundId = 0;
  4. r.foregroundNoti = null;
  5. }
最后直接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.

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


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/464512
推荐阅读
相关标签
  

闽ICP备14008679号