publicclassNotificationChannelsextendsCoreStartable { // ... // 省略代码 publicstaticvoidcreateAll(Context context) { finalNotificationManagernm= context.getSystemService(NotificationManager.class); // 创建通道 finalNotificationChannelbatteryChannel=newNotificationChannel(BATTERY, context.getString(R.string.notification_channel_battery), NotificationManager.IMPORTANCE_MAX); finalStringsoundPath= Settings.Global.getString(context.getContentResolver(), Settings.Global.LOW_BATTERY_SOUND); batteryChannel.setSound(Uri.parse("file://" + soundPath), newAudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT) .build()); batteryChannel.setBlockable(true); // 创建通道 finalNotificationChannelalerts=newNotificationChannel( ALERTS, context.getString(R.string.notification_channel_alerts), NotificationManager.IMPORTANCE_HIGH); // 创建通道 finalNotificationChannelgeneral=newNotificationChannel( GENERAL, context.getString(R.string.notification_channel_general), NotificationManager.IMPORTANCE_MIN); // 创建通道 finalNotificationChannelstorage=newNotificationChannel( STORAGE, context.getString(R.string.notification_channel_storage), isTv(context) ? NotificationManager.IMPORTANCE_DEFAULT : NotificationManager.IMPORTANCE_LOW); // 创建通道 finalNotificationChannelhint=newNotificationChannel( HINTS, context.getString(R.string.notification_channel_hints), NotificationManager.IMPORTANCE_DEFAULT); // No need to bypass DND. // 注册通道 nm.createNotificationChannels(Arrays.asList( alerts, general, storage, createScreenshotChannel( context.getString(R.string.notification_channel_screenshot), nm.getNotificationChannel(SCREENSHOTS_LEGACY)), batteryChannel, hint )); // Delete older SS channel if present. // Screenshots promoted to heads-up in P, this cleans up the lower priority channel from O. // This line can be deleted in Q. nm.deleteNotificationChannel(SCREENSHOTS_LEGACY); if (isTv(context)) { // TV specific notification channel for TV PIP controls. // Importance should be {@link NotificationManager#IMPORTANCE_MAX} to have the highest // priority, so it can be shown in all times. // 注册通道 nm.createNotificationChannel(newNotificationChannel( TVPIP, context.getString(R.string.notification_channel_tv_pip), NotificationManager.IMPORTANCE_MAX)); } } /** * Set up screenshot channel, respecting any previously committed user settings on legacy * channel. * @return */ @VisibleForTestingstatic NotificationChannel createScreenshotChannel( String name, NotificationChannel legacySS) { NotificationChannelscreenshotChannel=newNotificationChannel(SCREENSHOTS_HEADSUP, name, NotificationManager.IMPORTANCE_HIGH); // pop on screen screenshotChannel.setSound(null, // silent newAudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()); screenshotChannel.setBlockable(true); if (legacySS != null) { // Respect any user modified fields from the old channel. intuserlock= legacySS.getUserLockedFields(); if ((userlock & NotificationChannel.USER_LOCKED_IMPORTANCE) != 0) { screenshotChannel.setImportance(legacySS.getImportance()); } if ((userlock & NotificationChannel.USER_LOCKED_SOUND) != 0) { screenshotChannel.setSound(legacySS.getSound(), legacySS.getAudioAttributes()); } if ((userlock & NotificationChannel.USER_LOCKED_VIBRATION) != 0) { screenshotChannel.setVibrationPattern(legacySS.getVibrationPattern()); } if ((userlock & NotificationChannel.USER_LOCKED_LIGHTS) != 0) { screenshotChannel.setLightColor(legacySS.getLightColor()); } // skip show_badge, irrelevant for system channel } return screenshotChannel; } @Override publicvoidstart() { createAll(mContext); } privatestaticbooleanisTv(Context context) { PackageManagerpackageManager= context.getPackageManager(); return packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK); } }
// NotificationEntryManager.java @Override publicvoidonAsyncInflationFinished(NotificationEntry entry) { Trace.beginSection("NotificationEntryManager.onAsyncInflationFinished"); mPendingNotifications.remove(entry.getKey()); // If there was an async task started after the removal, we don't want to add it back to // the list, otherwise we might get leaks. if (!entry.isRowRemoved()) { booleanisNew= getActiveNotificationUnfiltered(entry.getKey()) == null; // 省略部分代码...... if (isNew) { // 省略部分代码...... // 添加一个notification会走到这里、 // 包括一开机就显示出来的那些notification addActiveNotification(entry); // 更新视图 updateNotifications("onAsyncInflationFinished"); // 省略部分代码...... } else { // 省略部分代码...... } } Trace.endSection(); }
@Override publicvoidupdateNotificationViews(final String reason) { if (!mNotifPipelineFlags.checkLegacyPipelineEnabled()) { return; } // The function updateRowStates depends on both of these being non-null, so check them here. // We may be called before they are set from DeviceProvisionedController's callback. if (mScrimController == null) return; // 不要在折叠期间修改通知。. if (isCollapsing()) { mShadeController.addPostCollapseAction(() -> updateNotificationViews(reason)); return; } // 把通知视图添加到通知面版的通知栏中 mViewHierarchyManager.updateNotificationViews(); // 这里不仅仅更新了通知面版的通知视图,也更新了状态栏的通知图标 mNotificationPanel.updateNotificationViews(reason); }