Android P Notification(3) 之 Fullscreen intent被拦截

源码网站:http://androidxref.com/9.0.0_r3

可以参照: Android O 8.0 Notification 源码分析(一)

                Android O 8.0 Notification 源码分析(二)

 

1.来电话时发现全屏通知被拦截

拦截原因

1): No Fullscreen intent: suppressed by DND(do not disturb) 被勿扰模式拦截

2).No Fullscreen intent: not important enough 通知优先级不够

 

2.Fullscreen intent app处理

incallUI发送通知的代码如下

@/packages/apps/Dialer/java/com/android/incallui/StatusBarNotifier.java
private void buildAndSendNotification(
  LogUtil.i("StatusBarNotifier.buildAndSendNotification", "notificationType=" + notificationType);  //2 log会打印2,表示incallUI发送通知开始
  switch (notificationType) {
    case NOTIFICATION_INCOMING_CALL: //2
      if (BuildCompat.isAtLeastO()) {
        builder.setChannelId(NotificationChannelId.INCOMING_CALL);  //channel id : INCOMING_CALL
      }
      // Set the intent as a full screen intent as well if a call is incoming
      configureFullScreenIntent(builder, createLaunchPendingIntent(true /* isFullScreen */));  //发送全屏通知
      // Set the notification category and bump the priority for incoming calls
      builder.setCategory(Notification.CATEGORY_CALL);
      // This will be ignored on O+ and handled by the channel
      builder.setPriority(Notification.PRIORITY_MAX);  //优先级 PRIORITY_MAX
      if (currentNotification != NOTIFICATION_INCOMING_CALL) {
        LogUtil.i(
            "StatusBarNotifier.buildAndSendNotification",
            "Canceling old notification so this one can be noisy");
        // Moving from a non-interuptive notification (or none) to a noisy one. Cancel the old
        // notification (if there is one) so the fullScreenIntent or HUN will show
        TelecomAdapter.getInstance().stopForegroundNotification();
      }
      break;
   
  LogUtil.i(
      "StatusBarNotifier.buildAndSendNotification",
      "displaying notification for " + notificationType);

  // If a notification exists, this will only update it.
  TelecomAdapter.getInstance().startForegroundNotification(NOTIFICATION_ID, notification);  //notify通知
}

需要设置setFullScreenIntent为true

http://androidxref.com/9.0.0_r3
packages/apps/Dialer/java/com/android/incallui/StatusBarNotifier.java
983  private void configureFullScreenIntent(Notification.Builder builder, PendingIntent intent) {
984    // Ok, we actually want to launch the incoming call
985    // UI at this point (in addition to simply posting a notification
986    // to the status bar).  Setting fullScreenIntent will cause
987    // the InCallScreen to be launched immediately *unless* the
988    // current foreground activity is marked as "immersive".
989    LogUtil.d("StatusBarNotifier.configureFullScreenIntent", "setting fullScreenIntent: " + intent);
990    builder.setFullScreenIntent(intent, true);
991  }

3.Framework层收到通知拦截fullScreen Intent

在addNotificationInternal回去拦截,看了几个Android 版本位置都有点差异,不过代码逻辑都是一样的

@/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
743    protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn)
744            throws InflationException {
745        if (DEBUG) {
746            Log.d(TAG, "createNotificationViews(notification=" + sbn);
747        }
748        NotificationData.Entry entry = new NotificationData.Entry(sbn);
749        Dependency.get(LeakDetector.class).trackInstance(entry);
750        entry.createIcons(mContext, sbn);
751        // Construct the expanded view.
752        inflateViews(entry, mListContainer.getViewParentForNotification(entry));
753        return entry;
754    }
755
756    private void addNotificationInternal(StatusBarNotification notification,
757            NotificationListenerService.RankingMap ranking) throws InflationException {
758        String key = notification.getKey();
759        if (DEBUG) Log.d(TAG, "addNotification key=" + key);
760
761        mNotificationData.updateRanking(ranking);
762        NotificationData.Entry shadeEntry = createNotificationViews(notification);
763        boolean isHeadsUped = shouldPeek(shadeEntry);
764        if (!isHeadsUped && notification.getNotification().fullScreenIntent != null) {
765            if (shouldSuppressFullScreenIntent(shadeEntry)) {
766                if (DEBUG) {
767                    Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + key);
768                }
769            } else if (mNotificationData.getImportance(key)
770                    < NotificationManager.IMPORTANCE_HIGH) {
771                if (DEBUG) {
772                    Log.d(TAG, "No Fullscreen intent: not important enough: "
773                            + key);
774                }
775            } else {
776                // Stop screensaver if the notification has a fullscreen intent.
777                // (like an incoming phone call)
778                SystemServicesProxy.getInstance(mContext).awakenDreamsAsync();
779
780                // not immersive & a fullscreen alert should be shown
781                if (DEBUG)
782                    Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
783                try {
784                    EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
785                            key);
786                    notification.getNotification().fullScreenIntent.send();
787                    shadeEntry.notifyFullScreenIntentLaunched();
788                    mMetricsLogger.count("note_fullscreen", 1);
789                } catch (PendingIntent.CanceledException e) {
790                }
791            }
792        }
793        abortExistingInflation(key);
794
795        mForegroundServiceController.addNotification(notification,
796                mNotificationData.getImportance(key));
797
798        mPendingNotifications.put(key, shadeEntry);
799        mGroupManager.onPendingEntryAdded(shadeEntry);
800    }

 

 

 

 

 

 

 

 

 

 

 

上一篇:Android 使用 DownloadManager 管理系统下载任务的方法


下一篇:Android中的通知功能Notification具体实现过程