通知(Notification)

通知(Notification)是Android系统中一个特色功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态中会显示一个通知的图标,下拉状态栏可以看到详细的内容。

通知的基本用法

通知既可以在活动中创建,也可以在广播接收器中创建,也可以在服务中创建。相比于在广播接收器和服务,在活动中创建通知的场景还是比较少的,因为一般只有当程序进入后台的时候我们才需要使用通知;
创建通知的详细步骤:

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.support.v4.app.NotificationCompat;


        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder ;
        int channelId = 1 ;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){    //Android 8.0以上适配
            NotificationChannel channel = new NotificationChannel(String.valueOf(channelId),"channel_name",
                                                              NotificationManager.IMPORTANCE_HIGH);
            manager.createNotificationChannel(channel);
            builder = new NotificationCompat.Builder(this,String.valueOf(channelId));
        }else{
            builder = new NotificationCompat.Builder(this);
        }
        builder.setContentTitle("this is content title")            //指定通知栏的标题内容
                .setContentText("this is content text")             //通知的正文内容
                .setWhen(System.currentTimeMillis())                //通知创建的时间
                .setSmallIcon(R.drawable.ic_launcher_background)    //通知显示的小图标,只能用alpha图层的图片进行设置
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background));

        Notification notification = builder.build() ;
        manager.notify(channelId,notification);

现在将这段代码在Activity中进行运行,看看效果:

package com.sl.demo;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                createNofication();
            }
        },2000);
    }
    private void createNofication(){
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder ;
        int channelId = 1 ;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){        //Android 8.0适配
            NotificationChannel channel = new NotificationChannel(String.valueOf(channelId),
                    "channel_name",
                    NotificationManager.IMPORTANCE_HIGH);
            manager.createNotificationChannel(channel);
            builder = new NotificationCompat.Builder(this,String.valueOf(channelId));
        }else{
            builder = new NotificationCompat.Builder(this);
        }
        builder.setContentTitle("this is content title")            //指定通知栏的标题内容
                .setContentText("this is content text")             //通知的正文内容
                .setWhen(System.currentTimeMillis())                //通知创建的时间
                .setSmallIcon(R.drawable.ic_launcher_background)    //通知显示的小图标,只能用alpha图层的图片进行设置
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher_background));

        Notification notification = builder.build() ;
     //channelId为本条通知的id
        manager.notify(channelId,notification);
    }
}

运行效果为:
运行效果.png

我们在使用Android手机时,当通知栏出现通知时,基本上都可以点击的,而现在如果点击我们创建的这条通知,是没有任何效果的,而要让其有点击效果,我们就需要对代码进行设置,现在就涉及了一个新概念:PendingIntent

PendingIntent和Intent从名字上看有些类似,他们这件确实存在着不少共同点。如,它们都可以去指明某一个“意图”,都可以用于启动活动、启动服务以及发送广播等。不同的是,Intent更加倾向于去立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。所以,也可以把PendingIntent理解为延迟执行的Intent;

PendingIntent的用法,它主要提供了几个静态方法用户获取PendingIntent的实例

  • getActivity(Context context,int requestCode,Intent intent,int flag):跳转到一个Activity组件
  • getBroadcast(Context context,int requestCode,Intent intent,int flag):打开一个广播组件
  • getService(Context context,int requestCode,Intent intent,int flag):打开一个服务组件

这几个方法的参数解释

  • Context就不做解释
  • 第二个参数requestCode一般用不到,通常传入0即可
  • 第三个参数是一个Intent对象,我们可以通过这个对象构建出PendingIntent的“意图”
  • 第四个参数int flag,用于确定PendingIntent的行为,有FLAG_ONE_SHOT,FLAG_NO_CREATE,FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT这4中值可选。

先看看flag的几个主要常量

  • FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个PendingIntent对象,那么先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。(测试发现,多个通知的channelId不同,PendingIntent内容相同时,只有最后发送的通知的PendingIntent有效,即点击事件有效)
  • FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent而是直接返回null。
  • FLAG_ONE_SHOT:该PendingIntent只作用一次(测试发现两个id不同但PendingIntent内容相同的通知,只要点击了其中一个,当再次点击时发现两个通知的点击事件都已经无效)
  • FLAG_UPDATE_CURRENT:①requestCode相同时:如果系统中有一个和你描述的PendingIntent对等的PendingIntent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如Intent中的Extras ; ②requestCode不同时:PendingIntent为设置的内容,不会进行改变

现在在程序中新建一个Actitvity为NotificationActivity,修改刚才的代码,创建PendingIntent并添加点击事件

        Intent intent = new Intent(this,NotificationActivity.class);
        PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
        builder...
                  .setContentIntent(pi);

现在再点击通知栏时,则程序会跳转到NotificationActivity的界面中;但是,发现点击后通知栏还是存在,并没有取消,其实取消通知栏显示有两种方法;
第一种为在NotificationCompat.Builder中再连缀一个方法,setAutoCancel(true),就是当通知栏被点击时取消该条通知,如:

  builder....
            .setAutoCancel(true);    //点击通知后,自动取消

第二种为手动取消通知,我们可以在通知对应的点击后操作的步骤中手动取消通知,如:

public class NotificationActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
//手动调用取消通知,其中cancel(1)中的1表示想取消通知的id
        ((NotificationManager)getSystemService(NOTIFICATION_SERVICE)).cancel(1);
    }
}

通知的进阶技巧

好了,现在已经知道通知的创建、点击事件、取消通知,但是我们平常发现收到同志时会有震动、声音、Led灯闪烁,下面在看看如何进行设置;

  • setSound():设置通知接收到时播放音频,我现在用的模拟器运行,在模拟器中有该文件存在
Notification notification = new Notification.Builder(this)....
                                        .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Lyra.ogg")))
                                        .build();
  • setVibarate():设置震动,其参数为一个长整型数组,用于设置手机静止和震动的时长,以毫秒为单位。赋值规律为:静止时长、振动时长、静止时长、振动时长....,以此类推
Notification notification = new Notification.Builder(this)....
                                        .setVibrate(new long[]{0,1000,1000,1000})
                                        .build();

实现手机振动,还需要声明振动权限:

  <uses-permission android:name="android.permission.VIBRATE"/>
  • setLights():设置LED灯,第一个参数设置LED灯颜色,第二个参数亮灯时长,第三个参数暗灯时长,如
 Notification notification = new Notification.Builder(this)....
                                        .setLights(Color.GREEN,1000,1000)
                                        .build();

其实,如果不想进行这么多复杂的设置,也可以使用通知的默认效果,它会根据当前手机环境来决定播放什么铃声,以及如何振动,写法如下:

Notification notification = new Notification.Builder(this)....
                                        .setDefaults(NotificationCompat.DEFAULT_ALL)   //设置全部默认
                                        .build();


Notification notification = new Notification.Builder(this)...
                                     //设置默认声音和振动
                                 .setDefaults(NotificationCompat.DEFAULT_SOUND|NotificationCompat.DEFAULT_VIBRATE)  
                                        .build();

通知的高级功能

NotificationCompat.Builder类有很多Api是我们没有用过的,现在我们看看setStyle()方法,这个方法允许我们构建出富文本的通知内容,也就是说通知中不管可以有文字和图标,还可以包含更多的东西。

  • 在通知中显示一段长文字
Notification notification = new Notification.Builder(this)....
                                       .setStyle(new NotificationCompat.BigTextStyle().bigText("setStyle()方法,
这个方法允许我们构建出富文本的通知内容"))
                                        .build();

在模拟器测试时是直接显示为完全了,但在我的小米5显示时是没有显示完全的,只有当长按通知时才显示出来;

  • 在通知中显示一张大图片
Notification notification = new Notification.Builder(this)....
                                      .setStyle(new NotificationCompat.BigPictureStyle().bigPicture(
                                        BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)))
                                        .build();

在测试时发现setStyle只能设置一个,如果设置多个,最后一个会覆盖之前的。

  • setPriority()方法,用于设置通知的重要程度,一共有五个值可选
  • PRIORITY_DEFAULT:表示默认的重要程度,和不设置效果是一样的
  • PRIORITY_MIN:表示最低的重要程度,系统只会在特定的场景才会显示这条通知,比如用户下拉状态栏时
  • PRIORITY_LOW:表示较低的重要程度,系统可能将这类通知缩小,或改变其显示顺序,将其排在更重要的通知之后
  • PRIORITY_HIGH:表示较高的重要程度,系统可能将这类通知放大,或改变其显示的顺序,将其排在比计较靠前的位置
  • PRIORITY_MAX:表示最高的重要程度,这类通知消息必须要让用户立即看到,甚至需要用户做出响应操作

具体写法如下:

Notification notification = new Notification.Builder(this)....
                                      .setPriority(NotificationCompat.PRIORITY_MAX)
                                        .build();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,941评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,397评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,345评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,851评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,868评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,688评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,414评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,319评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,775评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,945评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,096评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,789评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,437评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,993评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,107评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,308评论 3 372
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,037评论 2 355

推荐阅读更多精彩内容

  • Notification简介 通知是在常规UI界面之外向用户展示消息的工具,当系统发出通知时,它会以图表的形式显示...
    Cris_Ma阅读 6,904评论 2 10
  • 通知(Notification)这个功能对于我们来说非常的常见。打开手机的时候,各种软件的推送消息蜂拥而至,然后我...
    忆念成风阅读 3,330评论 2 10
  • 通知是您可以在应用的常规 UI 外部向用户显示的消息。当您告知系统发出通知时,它将先以图标的形式显示在通知区域中。...
    鹿小纯0831阅读 863评论 0 3
  • 原文出处: http://www.androidchina.net/6174.html Notification在...
    木木00阅读 12,330评论 3 32
  • 上世纪70年代,人民日报每天有评论员文章,这种文章都是涉及到国际形势和政治思想。舆论工具,意识形态在那个年代非常敏...
    谭良根阅读 706评论 14 7