Osheep

时光不回头,当下最重要。

【 Android 】Android 8.0 通知

在 Android 8.0 中,Google 重新设计通知,以便为管理通知行为和设置提供更轻松和更统一的方式。这些变更包括:通知渠道 通知标志 休眠 通知超时 通知设置 通知清除 背景颜色 消息样式

在 Android 8.0 中 用户可以长按应用启动器图标以查看 Android 8.0 中的通知。

《【 Android 】Android 8.0 通知》

notification-long-press.png

相关概念讲解:(摘自 官方文档

  1. 通知渠道
    Android 8.0 引入了通知渠道,其允许您为要显示的每种通知类型创建用户可自定义的渠道。用户界面将通知渠道称之为通知类别。

  2. 通知标志
    Android 8.0 引入了对在应用启动器图标上显示通知标志的支持。通知标志可反映某个应用是否存在与其关联、并且用户尚未予以清除也未对其采取行动的通知。通知标志也称为通知点。

  3. 休眠
    用户可以将通知置于休眠状态,以便稍后重新显示它。重新显示时通知的重要程度与首次显示时相同。应用可以移除或更新已休眠的通知,但更新休眠的通知并不会使其重新显示。

  4. 通知超时
    现在,使用 setTimeoutAfter() 创建通知时您可以设置超时。您可以使用此函数指定一个持续时间,超过该持续时间后,通知应取消。如果需要,您可以在指定的超时持续时间之前取消通知。

  5. 通知设置
    当您使用 Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES Intent 从通知创建指向应用通知设置的链接时,您可以调用 setSettingsText() 来设置要显示的文本。此系统可以提供以下 Extra 数据和 Intent,用于过滤应用必须向用户显示的设置:EXTRA_CHANNEL_IDNOTIFICATION_TAGNOTIFICATION_ID

  6. 通知清除
    系统现在可区分通知是由用户清除,还是由应用移除。要查看清除通知的方式,您应实现 NotificationListenerService 类的新 onNotificationRemoved() 函数。

  7. 背景颜色
    您现在可以设置和启用通知的背景颜色。只能在用户必须一眼就能看到的持续任务的通知中使用此功能。例如,您可以为与驾车路线或正在进行的通话有关的通知设置背景颜色。您还可以使用 Notification.Builder.setColor() 设置所需的背景颜色。这样做将允许您使用 Notification.Builder.setColorized() 启用通知的背景颜色设置。

  8. 消息样式
    现在,使用 MessagingStyle 类的通知可在其折叠形式中显示更多内容。对于与消息有关的通知,您应使用 MessagingStyle 类。您还可以使用新的 addHistoricMessage() 函数,通过向与消息相关的通知添加历史消息为会话提供上下文。

代码实战:(参考 Google 提供的 Sample

示例 GIF:

《【 Android 】Android 8.0 通知》

Android 8.0 通知.gif

首先创建一个 Helper 类,用来管理通知渠道,并创建通知。

public class NotificationHelper extends ContextWrapper {

    public static final String PRIMARY_CHANNEL = "default";
    public static final String SECONDARY_CHANNEL = "second";

    private NotificationManager mManager;

    /**
     * 注册通知通道,它可以稍后被单独的通知使用。
     */
    public NotificationHelper(Context ctx) {
        super(ctx);

        NotificationChannel chan1 = new NotificationChannel(PRIMARY_CHANNEL,
                getString(R.string.main_primary_title), NotificationManager.IMPORTANCE_DEFAULT);
        chan1.setLightColor(Color.GREEN);
        chan1.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
        getManager().createNotificationChannel(chan1);

        NotificationChannel chan2 = new NotificationChannel(SECONDARY_CHANNEL,
                getString(R.string.main_secondary_title), NotificationManager.IMPORTANCE_HIGH);
        chan2.setLightColor(Color.BLUE);
        chan2.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        getManager().createNotificationChannel(chan2);
    }

    /**
     * 建立一级通道的通知
     */
    public Notification.Builder getNotification1(String title, String body) {
        return new Notification.Builder(getApplicationContext(), PRIMARY_CHANNEL)
                .setContentTitle(title)
                .setContentText(body)
                .setSmallIcon(getSmallIcon())
                .setAutoCancel(true);
    }

    /**
     * 建立二级通道的通知
     */
    public Notification.Builder getNotification2(String title, String body) {
        return new Notification.Builder(getApplicationContext(), SECONDARY_CHANNEL)
                .setContentTitle(title)
                .setContentText(body)
                .setSmallIcon(getSmallIcon())
                .setAutoCancel(true);
    }

    /**
     * 发送通知
     */
    public void notify(int id, Notification.Builder notification) {
        getManager().notify(id, notification.build());
    }

    /**
     * 获取这个应用程序的小图标
     */
    private int getSmallIcon() {
        return android.R.drawable.stat_notify_chat;
    }

    /**
     * 通知管理
     */
    private NotificationManager getManager() {
        if (mManager == null) {
            mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mManager;
    }
}

接下来,我们就要发送通知。如 GIF 图所示,界面上总共有 7 个按钮,就对应 7 个点击事件。(示例 Sample 使用 Data-Binding 代替 findViewById)

private void initViews() {
    mBinding.mainPrimarySend1.setOnClickListener(this);
    mBinding.mainPrimarySend2.setOnClickListener(this);
    mBinding.mainPrimaryConfig.setOnClickListener(this);

    mBinding.mainSecondarySend1.setOnClickListener(this);
    mBinding.mainSecondarySend2.setOnClickListener(this);
    mBinding.mainSecondaryConfig.setOnClickListener(this);

    mBinding.btnSetting.setOnClickListener(this);
}

自定义发送通知的方法(sendNotification):

private static final int NOTIFY_PRIMARY1 = 1100;
private static final int NOTIFY_PRIMARY2 = 1101;
private static final int NOTIFY_SECONDARY1 = 1200;
private static final int NOTIFY_SECONDARY2 = 1201;

NotificationHelper mHelper = new NotificationHelper(this);

public void sendNotification(int id, String title) {
    Notification.Builder builder = null;
    switch (id) {
        case NOTIFY_PRIMARY1:
            builder = mHelper.getNotification1(title, getString(R.string.primary1_body));
            break;
        case NOTIFY_PRIMARY2:
            builder = mHelper.getNotification1(title, getString(R.string.primary2_body));
            break;
        case NOTIFY_SECONDARY1:
            builder = mHelper.getNotification2(title, getString(R.string.secondary1_body));
            break;
        case NOTIFY_SECONDARY2:
            builder = mHelper.getNotification2(title, getString(R.string.secondary2_body));
            break;
    }

    if (mHelper != null) {
        mHelper.notify(id, builder);
    }
}

自定义 App 通知设置的方法(goToNotificationSettings):

public void goToNotificationSettings() {
    Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
    startActivity(intent);
}

public void goToNotificationSettings(String channel) {
    Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
    intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel);
    startActivity(intent);
}

自定义获取一级标题文字的方法(getTitlePrimaryText):

private String getTitlePrimaryText() {
    if (mBinding.mainPrimaryTitle != null) {
        return mBinding.mainPrimaryTitle.getText().toString();
    }
    return "";
}

自定义获取二级标题文字的方法(getTitleSecondaryText):

private String getTitleSecondaryText() {
    if (mBinding.mainPrimaryTitle != null) {
        return mBinding.mainSecondaryTitle.getText().toString();
    }
    return "";
}

对按钮做点击事件,执行 ① 发送一级通知 ② 发送二级通知 ③ App 通知设置:

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.main_primary_send1:
            sendNotification(NOTIFY_PRIMARY1, getTitlePrimaryText());
            break;
        case R.id.main_primary_send2:
            sendNotification(NOTIFY_PRIMARY2, getTitlePrimaryText());
            break;
        case R.id.main_primary_config:
            goToNotificationSettings(NotificationHelper.PRIMARY_CHANNEL);
            break;
        case R.id.main_secondary_send1:
            sendNotification(NOTIFY_SECONDARY1, getTitleSecondaryText());
            break;
        case R.id.main_secondary_send2:
            sendNotification(NOTIFY_SECONDARY2, getTitleSecondaryText());
            break;
        case R.id.main_secondary_config:
            goToNotificationSettings(NotificationHelper.SECONDARY_CHANNEL);
            break;
        case R.id.btn_setting:
            goToNotificationSettings();
            break;
        default:
            Log.d(TAG, "onClick: Unknown click event.");
            break;
    }
}

示例代码已上传至 GitHub,如果对你有帮助,请 Star,谢谢。

点赞