Android Notification用法全解析

关于通知

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

A. 通知使用场景

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

B. 创建通知的详细步骤

1.获取NotificationManager的实例:

NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

通过getSystemService()方法获取到NotificationManager;

方法接收一个字符串参数用于确定获取系统的哪个服务,这里传入NOTIFICATION_SERVICE就表示获取的是通知管理器。

2.使用support-v4包中的NotificationCompat类的Builder构造器来创建Notification对象。

Notification notification = new NotificationCompat.Builder(this)
                        .setContentTitle("This is content title")
                        .setContentText("This is context text")
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                        .build();
                        
1.setContentTitle   用于指定通知的标题内容。
2.setContentText    用于指定通知的正文内容,下拉系统状态栏就可以看到。
3.setWhen   用于指定通知被创建的时间,以毫秒为单位,下拉系统状态栏就会看到。
4.setSmallIcon  用于设置通知的小图标,注意只能使用纯alpha图层的图片进行设置,小图标会显示在系统状态栏上。
5.setLargeIcon  用于设置通知的大图标,下拉系统状态栏即可见。
                        

3.调用NotificationManager的notify方法让通知显示出来。

manager.notify(1, notification);

notify方法接收两个参数:第一个参数是id,保证为每个通知所指定的id都是不同的。第二个参数是Notification对象,这里直接换入刚刚创建好的Notification对象。

4.栗子:

  • 新建项目,修改activity_main.xml中的代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.fkq.inform.MainActivity">

    <Button
        android:id="@+id/send_notice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Notice" />
</LinearLayout>

布局很简单,添加一个Button按钮,用于发送通知。
  • 修改MainActivity中的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.send_notice);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.send_notice:
                NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                Notification notification = new NotificationCompat.Builder(this)
                        .setContentTitle("This is content title")
                        .setContentText("This is context text")
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                        .build();
                manager.notify(1, notification);
                break;
        }
    }
}

C. 实现通知的点击效果-PendingIntent

1.PendingIntent和Intent相同点和不同点:

相同点:都可以去指明某一个“意图”,都可以用于启动活动、启动服务以及发送广播等。

不同点:Intent更倾向于立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。

总之:PendingIntent简单的理解为延迟执行的Intent。

2.PendingIntent用法:

  • PendingIntent提供了几个静态方法用于获取PendingIntent的实例,我们可以根据需求来选择是使用getActivity方法、getBroadcast方法、还是getService方法。

  • 这三个方法所接收的参数是相同的,第一个参数是Context,第二个参数一般用不到,传入0即可,第三个参数是Intent对象,我们可以通过这个对象构建出PendingIntent的“意图”,第四个参数用于确定PendingIntent的行为,有Flag_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT这4种值可选,通常传入0即可。

  • NotificationCompat.Builder构造器还可以再连缀一个setContentIntent方法,接收的参数正是一个PendingIntent对象。因此,这里就可以通过PendingIntent构建出一个延迟执行的“意图”,当用户点击这条通知时就会执行相应的逻辑。

3.添加点击功能:

  • 创建NotificationActivity和notification_layout:
public class NotificationActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notification_layout);
    }
}
<activity android:name=".NotificationActivity"></activity>
  • 修改MainActivity:
Intent intent = new Intent(this, NotificationActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("This is content title")
        .setContentText("This is context text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
        .setContentIntent(pi)
        .build();
manager.notify(1, notification);

1.使用Intent表达出我们想要启动NotificationActivity的“意图”。
2.然后将构建好的Intent对象传入到PendingIntent的getActivity里面,以得到PendingIntent的实例。
3.接着在NotificationCompat.Builder中调用setContentIntent方法,把它作为参数传入即可。

D. 点击通知后取消在系统的状态栏上的通知

1.在NotificationCompat.Builder中连缀一个setAutoCancel方法,传入true即可。

Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("This is content title")
        .setContentText("This is context text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
        .setContentIntent(pi)
        .setAutoCancel(true)
        .build();

2.显式地调用Notification的cancel方法将它取消:

public class NotificationActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notification_layout);
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(1);
    }
}

如果想取消哪条通知,在cancel方法中传入该通知的id就行了

E. 通知的进阶技巧

1.通知到达有声音:
2.通知到达震动:

Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("This is content title")
        .setContentText("This is context text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
        .setContentIntent(pi)
        .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Little_Beat.ogg")))
        .setVibrate(new long[]{0,1000,0,0})
        .build();        
             
1.setSound方法接收一个Uri参数,比如每个手机的/system/media/audio/ringtones目录下都有很多的音频文件,以上是vivo x9i手机的。
2.setVibrate方法接收一个长整型的数组,用于设置手机静止和振动的时长,以毫秒为单位:下标为0的值表示手机静止的时长,下标为1的值表示手机振动的时长,下标为2的值又表示手机静止的时长,以此类推。
3.如果想要通知到来的时候立刻振动1秒,代码如上所示。
4.手机振动实际证明不需要声明权限。

3.控制手机LED灯的显示:
4.使用通知的默认效果:振动方式和铃声跟随系统:

Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("This is content title")
        .setContentText("This is context text")
        .setWhen(System.currentTimeMillis())
        .setSmallIcon(R.mipmap.ic_launcher)
        .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
        .setContentIntent(pi)
        .setDefaults(NotificationCompat.DEFAULT_ALL)
        .setLights(Color.GREEN, 1000, 1000)
        .build();
        
注意:
1.LED灯的闪烁要在锁屏的状态下显示。
2.LED灯的颜色可能受手机的定制原因,不是所有的颜色都起作用。

F. 通知的高级功能

  • setStyle方法接收一个NotificationCompat.Style参数,这个参数就是用来构建具体的富文本信息的,如长文字,图片等。

1.显示长文字:

.setStyle(new NotificationCompat.BigTextStyle().bigText("【美媒称中国奇迹没有结束】“增长表现超出预期”,对于中国国家统计局公布的今年一季度6.9%的国内生产总值(GDP)增长率"))


setStyle方法中创建一个NotificationCompat.BigTextStyle对象,这个对象就是用于封装长文字信息的,我们调用它的bigText方法并将文字内容传入就可以了。

2.显示一张大图片:

.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.fkq)))

setStyle方法中创建一个NotificationCompat.BigPictureStyle对象,这个对象就是用于设置大图片的,然后调用它的bigPicture方法将图片传入。

通过BitmapFactory的decodeResource方法将图片解析成Bitmap对象,再传入bigPicture方法就可以了。
  • setPriority方法用于设置通知的重要程度,一共5个常量值可选:
  1. PRIORITY_DEFAULT 表示默认的重要程序,和不设置效果一样。
  2. PRIORITY_MIN 表示最低的重要程度,系统可能只会在特定的场景才显示这条通知,比如用户下拉状态栏的时候。
  3. PRIORITY_LOW 表示较低的重要程度,系统可能会将这类通知缩小,或改变其显示的顺序,将其排在更重要的通知之后。
  4. PRIORITY_HIGH 表示较高的重要程度,系统可能会将这类通知放大,或改变其显示的顺序,将其排在比较靠前的位置。
  5. PRIORITY_MAX 表示最高的重要程度,这类通知消息必须要让用户立刻看到,甚至需要用户做出响应操作。
.setPriority(NotificationCompat.PRIORITY_MAX)

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

推荐阅读更多精彩内容