通知

作者: 进攻的蚂蚁 | 来源:发表于2018-03-09 01:22 被阅读0次

    创建一个基本的通知

    以最基本和紧凑形式(也称为折叠形式)的通知显示图标,标题和少量内容文本。在本节中,您将学习如何创建用户可以点击的通知来在应用中启动活动。

    图1. 带有标题和文本的通知
    有关通知各部分的更多详细信息,请阅读有关 通知解剖的内容

    设置通知内容

    要开始使用,您需要使用[NotificationCompat.Builder]对象设置通知的内容和频道 。以下示例显示如何使用以下命令创建通知:

    • 一个小图标,[setSmallIcon()]。这是唯一需要的用户可见内容。
    • 标题,[setContentTitle()]
    • 正文,[setContentText()]
    • 通知优先级,由...设定[setPriority()]。优先级决定了Android 7.1及更低版本的通知应具有多大的侵入性。(对于Android 8.0及更高版本,您必须设置频道重要性 - 如下一节所示。)
    NotificationCompat.Builder mBuilder =  new  NotificationCompat.Builder(this, CHANNEL_ID)  .setSmallIcon(R.drawable.notification_icon)  
    .setContentTitle(textTitle)  
    .setContentText(textContent) 
    .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    

    注意[NotificationCompat.Builder]构造函数要求你提供一个通道ID。这是与Android 8.0(API级别26)及更高版本兼容所必需的,但旧版本会忽略它。

    默认情况下,通知的文本内容被截断以适合一行。如果您希望通知时间更长,可以通过添加样式模板来启用可扩展通知[setStyle()]。例如,下面的代码创建一个更大的文本区域:

    NotificationCompat.Builder mBuilder = new  NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Much longer text that cannot fit one line...")
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText("Much longer text that cannot fit one line..."))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    

    有关其他大型通知样式的更多信息,包括如何添加图像和媒体播放控件,请参阅使用展开式详细信息创建通知

    创建一个频道并设置重要性

    在Android 8.0及更高版本上发布通知之前,您必须向系统注册您的应用程序的 [通知渠道],方法是[NotificationChannel]向其 传递实例[createNotificationChannel()]。因此,以下代码被[SDK_INT]版本中的条件阻止 :

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        CharSequence name = getString(R.string.channel_name);
        String description = getString(R.string.channel_description);
        int importance = NotificationManagerCompat.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
        channel.setDescription(description);
        // Register the channel with the system
        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
        notificationManager.createNotificationChannel(channel);
    }
    

    注意[NotificationChannel]构造函数需要importance使用类中的一个常量[NotificationManagerCompat]。此参数确定如何中断用户对属于此的任何通知信道,虽然必须同时设置的优先级[setPriority()]支持Android 7.1和下(如上所示)。

    尽管您必须如此处所示设置通知重要性/优先级,但系统并不保证您会收到警报行为。在某些情况下,系统可能会根据其他因素改变重要性级别,用户可以随时重新定义给定频道的重要性级别。

    有关不同级别的含义的更多信息,请阅读有关通知重要性级别

    设置通知的点按操作

    每个通知都应该对点击进行响应,通常会在您的应用中打开与通知相对应的活动。为此,您必须指定一个用[PendingIntent]对象定义的内容意图并将其传递给[setContentIntent()]

    以下片段显示了如何在用户点击通知时创建打开活动的基本意图:

    // Create an explicit intent for an Activity in your app
    Intent intent = new Intent(this, AlertDetails.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            .setAutoCancel(true);
    

    注意这个代码调用[setAutoCancel()], 当用户点击它时[会]自动[删除通知]。

    [setFlags()]上面显示的方法有助于在通过通知打开您的应用程序后保留用户的预期导航体验。但是,您是否想要使用这取决于您开始的活动类型,可能是以下某种活动:

    · 专门用于响应通知的活动。在正常的应用程序使用过程中,用户无需导航到此活动,因此该活动将启动一项新任务,而不是添加到您的应用程序的现有 [任务和后退堆栈中]。这是上面示例中创建的意图类型。

    · 存在于您应用的常规应用流中的活动。在这种情况下,启动该活动应创建一个后退堆栈,以便保留用户对Back和Up按钮的期望。

    有关配置通知意图的不同方法的更多信息,请参阅从通知开始活动

    显示通知

    要显示通知,请调用[NotificationManagerCompat.notify()]并为其传递一个唯一的通知ID和结果[NotificationCompat.Builder.build()]。例如:

    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    
    // notificationId is a unique int for each notification that you must define
    notificationManager.notify(notificationId, mBuilder.build());
    

    请记住保存您传递给的通知ID,[NotificationManagerCompat.notify()]因为如果您想[更新]或[删除通知],以后需要它 。

    注意:从Android 8.1(API级别27)开始,应用程序无法每秒发出一次以上的通知声音。如果您的应用在一秒内发布多个通知,它们全都按预期显示,但每秒只有第一个通知发出声音。

    添加操作按钮

    通知最多可以提供三个操作按钮,以便用户快速响应,例如暂停提醒或甚至回复短信。但是这些操作按钮不应复制用户[点击通知]时执行的操作 。

    图2. 带有一个动作按钮的的通知

    添加动作按钮,传递[PendingIntent][addAction()]方法。这就像设置通知的默认点按操作一样,除了启动活动之外,您还可以执行其他各种操作,例如启动[BroadcastReceiver]在后台执行作业的操作,以便操作不会中断已打开的应用程序。

    例如,以下代码显示如何将广播发送到特定接收者:

     Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
    snoozeIntent.setAction(ACTION_SNOOZE);
    snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
    PendingIntent snoozePendingIntent =
            PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);
    
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setContentIntent(pendingIntent)
            .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                    snoozePendingIntent);
    

    有关构建[BroadcastReceiver](https://developer.android.com/reference/android/content/BroadcastReceiver.html) 要运行后台工作的更多信息,请参阅 广播指南

    如果您尝试使用媒体播放按钮(例如暂停和跳过曲目)来构建通知,请参阅如何使用媒体控件创建通知

    添加直接回复操作

    Android 7.0(API级别24)中引入的直接回复操作允许用户直接在通知中输入文本,通知会在不打开任何活动的情况下发送到您的应用。例如,您可以使用直接回复操作来让用户回复通知中的短信或更新任务列表。


    图3.点击“Reply”按钮打开文本输入

    直接回复操作在打开文本输入的通知中显示为附加按钮。当用户完成输入时,系统将文本响应附加到您为通知操作指定的意图,并将意图发送到您的应用程序。

    添加回复按钮

    创建支持直接回复的通知操作:

    1. 创建一个[RemoteInput.Builder] 可以添加到通知操作的实例。此类的构造函数接受系统用作文本输入的关键字的字符串。稍后,掌上电脑应用程序会使用该键来检索输入的文本。
    // Key for the string that's delivered in the action's intent.
    private static final String KEY_TEXT_REPLY = "key_text_reply";
    
    String replyLabel = getResources().getString(R.string.reply_label);
    RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
            .setLabel(replyLabel)
            .build();
    

    2. 创建一个[PendingIntent]回复操作。

    // Build a PendingIntent for the reply action to trigger.
    PendingIntent replyPendingIntent =
            PendingIntent.getBroadcast(getApplicationContext(),
                    conversation.getConversationId(),
                    getMessageReplyIntent(conversation.getConversationId()),
                    PendingIntent.FLAG_UPDATE_CURRENT);
    

    警告:如果您重新使用[PendingIntent],用户可能会回复与他们认为不同的对话。您必须为每个对话提供一个不同的请求代码,或者提供一个true在您调用[equals()] 任何其他对话的回复意图时不会返回的意图。对话ID经常作为意图的额外套餐的一部分传递,但在您致电时会被忽略[equals()]

    3 将该RemoteInput 对象附加到使用的操作 [addRemoteInput()]// Create the reply action and add the remote input.

    NotificationCompat.Action action =
            new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon,
                    getString(R.string.label), replyPendingIntent)
                    .addRemoteInput(remoteInput)
                    .build();
    

    4. 将操作应用于通知并发出通知。

    // Build the notification and add the action.
    Notification newMessageNotification = new Notification.Builder(mContext, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_message)
            .setContentTitle(getString(R.string.title))
            .setContentText(getString(R.string.content))
            .addAction(action)
            .build();
    
    // Issue the notification.
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    notificationManager.notify(notificationId, newMessageNotification);
    

    系统提示用户在触发通知操作时输入响应,如图3所示。

    从回复中检索用户输入

    从通知的答复UI,呼叫接收用户输入 [RemoteInput.getResultsFromIntent()],它传递[Intent]您收到的[BroadcastReceiver]

    private CharSequence getMessageText(Intent intent) {
        Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
        if (remoteInput != null) {
            return remoteInput.getCharSequence(KEY_TEXT_REPLY);
        }
        return null;
     }
    

    处理完文本后,您必须[NotificationManagerCompat.notify()](https://developer.android.com/reference/java/lang/Object.html#notify())使用相同的ID和标签(如果使用)更新通知 。这对于隐藏直接回复UI并向用户确认他们的回复已被正确接收和处理是必要的。

    // Build a new notification, which informs the user that the system
    // handled their interaction with the previous notification.
    Notification repliedNotification = new Notification.Builder(context, CHANNEL_ID)
           .setSmallIcon(R.drawable.ic_message)
           .setContentText(getString(R.string.replied))
           .build();
    
    // Issue the new notification.
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    notificationManager.notify(notificationId, repliedNotification);
    

    使用这个新通知时,请使用传递给接收方[onReceive()]方法的上下文。

    您还应该通过呼叫将答复追加到通知底部 [setRemoteInputHistory()]。但是,如果您正在构建消息传递应用程序,则应该创建[消息传递式通知] 并将新消息附加到对话中。

    有关消息应用程序通知的更多建议,请参阅消息传递应用程序的[最佳实践]

    添加一个进度条

    通知可以包含一个动画进度指示器,向用户显示正在进行的操作的状态


    图4.操作期间和之后的进度条

    如果您可以随时估计完成的操作有多少,请使用指示器的“确定”形式(如图4所示) [setProgress(max, progress, false)]。第一个参数是“完整”值(例如100); 第二个是当前完成的数量,最后一个表示这是确定的进度条。

    随着您的操作进行,持续呼叫[setProgress(max, progress, false)]更新后的值 progress并重新发出通知。

    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
    mBuilder.setContentTitle("Picture Download")
            .setContentText("Download in progress")
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_LOW);
    
    // Issue the initial notification with zero progress
    int PROGRESS_MAX = 100;
    int PROGRESS_CURRENT = 0;
    mBuilder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    notificationManager.notify(notificationId, mBuilder.build());
    
    // Do the job here that tracks the progress.
    // Usually, this should be in a worker thread
    // To show progress, update PROGRESS_CURRENT and update the notification with:
    // mBuilder.setProgress(PROGRESS_MAX, PROGRESS_CURRENT, false);
    // notificationManager.notify(notificationId, mBuilder.build());
    
    // When done, update the notification one more time to remove the progress bar
    mBuilder.setContentText("Download complete")
            .setProgress(0,0,false);
    notificationManager.notify(notificationId, mBuilder.build());   
    

    在手术结束时,progress应该相等 max。您可以让进度条显示操作完成时间,或将其删除。无论哪种情况,请记住更新通知文本以显示操作已完成。要删除进度条,请致电[setProgress(0, 0, false)]

    注意:由于进度条要求您的应用程序不断更新通知,因此此代码通常应在后台服务中运行。

    要显示不确定的进度条(不指示完成百分比的栏),请调用 [setProgress(0, 0, true)]。结果是一个与上面的进度条具有相同样式的指示符,除了进度条是一个不表示完成的连续动画。进度动画会一直运行,直到您致电 [setProgress(0, 0, false)] ,然后更新通知以删除活动指示符。

    请记住更改通知文本以表明操作已完成。

    注意:如果您确实需要下载文件,您应该考虑使用 [DownloadManager],它提供了自己的通知来跟踪您的下载进度。

    设置一个系统范围的类别

    Android使用某些预定义的系统范围类别来确定当用户启用["请勿打扰”模式]时是否使用给定通知[打扰]用户 。

    如果您的通知属于中定义的预先定义的通知类别之一[NotificationCompat]-如[CATEGORY_ALARM][CATEGORY_REMINDER][CATEGORY_EVENT],或[CATEGORY_CALL]-你应该通过合适的类别声明它是这样[setCategory()]

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("My notification")
            .setContentText("Hello World!")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setCategory(NotificationCompat.CATEGORY_MESSAGE);
    

    当设备处于免打扰模式时,系统将使用有关您的通知类别的这些信息来做出关于显示通知的决定。

    但是,您无需设置系统范围的类别,只有在您的通知与由in定义的某个类别匹配时才应该这样做 [NotificationCompat](https://developer.android.com/reference/android/support/v4/app/NotificationCompat.html)

    设置锁定屏幕可见性


    要通过锁定屏幕控制通知中可见的详细程度,请调用[setVisibility()]并指定以下值之一:

    · [VISIBILITY_PUBLIC] 显示通知的完整内容。

    · [VISIBILITY_SECRET] 在锁定屏幕上不显示此通知的任何部分。

    · [VISIBILITY_PRIVATE] 显示基本信息,例如通知图标和内容标题,但隐藏通知的完整内容。

    何时[VISIBILITY_PRIVATE]设置,您还可以提供隐藏某些详细信息的通知内容的备用版本。例如,短信应用可能会显示一条通知,显示您有3条新短信,但隐藏了短信内容和发件人。要提供此替代通知,请首先[NotificationCompat.Builder]像往常一样创建替代通知。然后用另外的通知附加替代通知[setPublicVersion()]

    但是,用户始终可以最终控制他们的通知是否在锁定屏幕上可见,甚至可以根据您的应用程序的通知渠道来控制这些通知。

    更新通知


    要在发布通知后更新此通知,请[NotificationManagerCompat.notify()]再次拨打电话,并将与您先前使用的ID相同的通知传递给它。如果先前的通知已被解除,则会创建新的通知。

    您可以选择打电话, [setOnlyAlertOnce()]以便只在通知出现时通知才会中断用户(包括声音,振动或视觉线索),而不是在以后进行更新。

    警告:Android在更新通知时应用速率限制。如果您过于频繁地发布更新(通常少于一秒),系统可能会放弃一些更新。

    删除通知


    通知保持可见,直到发生以下情况之一:

    · 用户关闭通知。

    · 用户单击通知,并[setAutoCancel()]在创建通知时调用 。

    · 你需要[cancel()]一个特定的通知ID。此方法还会删除正在进行的通知。

    · 你打电话[cancelAll()],这将删除您先前发出的所有通知。

    · 如果您在创建通知时设置超时 [setTimeoutAfter()],系统会在指定的持续时间过后取消通知。如果需要,您可以在超过指定的超时时间之前取消通知。

    消息传递应用的最佳实践


    使用此处列出的最佳做法作为创建消息传递和聊天应用通知时要记住的内容的快速参考。

    使用MessagingStyle

    从Android 7.0(API级别24)开始,Android为消息内容专门提供通知样式模板。使用该 [NotificationCompat.MessagingStyle] 课程,您可以更改通知中显示的多个标签,包括会话标题,其他消息和通知的内容视图。

    以下代码片段演示了如何使用MessagingStyle该类自定义通知的样式。

    Notification notification = new Notification.Builder(this, CHANNEL_ID)
            .setStyle(new NotificationCompat.MessagingStyle("Me")
            .setConversationTitle("Team lunch")
            .addMessage("Hi", timestamp1, null) // Pass in null for user.
            .addMessage("What's up?", timestamp2, "Coworker")
            .addMessage("Not much", timestamp3, null)
            .addMessage("How about lunch?", timestamp4, "Coworker"))
            .build();
    

    从Android 8.0(API级别26)开始,使用[NotificationCompat.MessagingStyle]该类的通知 将以折叠形式显示更多内容。您还可以使用该[addHistoricMessage()]方法通过向与消息传递相关的通知添加历史消息来为对话提供上下文。

    使用时[NotificationCompat.MessagingStyle]

    · 呼叫[MessagingStyle.setConversationTitle()]为两人以上的群组聊天设置标题。一个好的对话标题可能是群组聊天的名称,或者如果它没有特定的名称,则可能是对话中的参与者列表。如果没有这个,该消息可能被误认为属于与对话中最近消息的发送者的一对一对话。

    · 使用该[MessagingStyle.setData()] 方法来包含媒体消息,如图像。目前支持模式图像/ *的MIME类型。

    使用直接回复

    直接回复允许用户回复内部消息。

    · 用户回复内嵌回复操作后,用于 [MessagingStyle.addMessage()]更新 MessagingStyle通知,并且不收回或取消通知。不取消通知允许用户从通知中发送多个回复。

    · 要使内联回复操作与Android Wear兼容,请致电。[ Action.WearableExtender.setHintDisplayInlineAction(true)]

    · 通过向通知添加历史消息,使用该方法为直接回复对话提供上下文。[ addHistoricMessage()]

    启用智能回复

    · 要启用智能回复,请调用回复操作。这会使通知桥接到Android Wear设备时,用户可以使用智能回复响应。智能回复响应由完全在机器学习模型生成,使用 通知提供的上下文,并且没有数据上传到互联网以生成响应。[ setAllowGeneratedResponses(true)][NotificationCompat.MessagingStyle]

    添加通知元数据

    · 当设备处于免打扰模式时,分配通知元数据以告知系统如何处理您的应用通知。例如,使用 or 方法覆盖免打扰模式。 addPerson() setCategory(Notification.CATEGORY_MESSAGE)

    本文源自 * 发展* 指南* 用户界面和导航* 通知

    2018/3/9

    相关文章

      网友评论

          本文标题:通知

          本文链接:https://www.haomeiwen.com/subject/dkmufftx.html