8

通知

当应用想向用户发出一些提示信息,而应用不在前台运行时,通知可完成此事项。

通知的基本用法

通知既可以在活动里创建,也可以在广播接收器里创建。

创建通知的详细步骤

1.调用Context的getSystemService()方法获取NotificationManager管理通知。

getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务,传入Context.NOTIFICATION。

获取NotificationManager的实例:

1
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

2.使用Builder构造器创建Notification对象。

为了解决兼容问题,使用support-v4库提供的NofitificationCompat类的构造器创建Notification对象。

1
Notification notification = new NotificationCompat.Builder(context).build();

如下,在最终的build()方法之前连缀任意多的设置方法创建Notification对象。

1
2
3
4
5
6
7
Notification notification=new NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.build();

setContentTitle(),指定通知的标题内容。
setContentText(),指定通知的正文内容。
setWhen(),指定通知被创建的时间,以毫秒为单位。
setSmallIcon(),设置通知的小图标。只能使用纯alpha图层的图片进行设置,小图标会显示在系统状态栏上。
setLargeIcon(),设置通知的大图标。

完成以上准备工作,调用NotificationManager的notify()方法就可以显示通知。

notify()方法接收两个参数,第一个参数是id,第二个参数是Notification对象。

如下,显示通知:

1
manager.notify(1,notification);

实例体验通知

1.新建NotificationTest项目。

2.修改activity_main.xml。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

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

</LinearLayout>

3.修改MainActivity。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class  extends AppCompatActivity implements View.OnClickListener{


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button sendNotice = (Button)findViewById(R.id.send_notice);
sendNotice.setOnClickListener(this);
}


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 content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.build();
manager.notify(1,notification);
break;
default:
break;
}
}
}

这时候的通知,点击后没有任何效果。

PendlingIntent

PendlingIntent与Intent类似,但是不同的是:前者倾向于在某个合适的时机去执行某个动作,而后者倾向于立即执行某个动作。

PendlingIntent提供以下几个静态方法用于获取PendlingIntent实例:getActivity()、getBroadcast()、getService()。它们接收相同的参数:

  • 第一个参数是Context。
  • 第二个参数一般传入0。
  • 第三个参数是一个Intent对象,构建PendlingIntent的“意图”。
  • 第四个参数确定PendlingIntent的行为,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT。

NotificationCompat.Builder可以连缀一个setContentIntent()方法,接收PendlingIntent对象。

PendlingIntent构建出一个“意图”,当用户点击通知时就执行相应的逻辑。

给通知加上点击功能

1.新建活动NotificationActivity,布局notification_layout。

2.编辑notification_layout。

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="24sp"
android:text="This is notification layout"/>

</LinearLayout>

3.修改MainActivity,给通知加入点击功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class  extends AppCompatActivity implements View.OnClickListener{


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button sendNotice = (Button)findViewById(R.id.send_notice);
sendNotice.setOnClickListener(this);
}


public void onClick(View view) {
switch (view.getId()){
case R.id.send_notice:
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 content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pi)
.build();
manager.notify(1,notification);
break;
default:
break;
}
}
}

取消通知图标

如果没有在代码中对通知进行取消,通知会一直显示在系统的状态栏上。

取消通知图标的方法有以下两种。

第一种,在NotificationCompat.Builder中连缀一个setAutoCancel()方法。写法如下:

1
2
3
4
5
6
7
8
9
NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pi)
.setAutoCancle(true)
.build();

第二种,显式调用NotificationManager的cancle()方法取消。写法如下:

1
2
3
4
5
6
7
8
9
10
11
public class NotificationActivity extends AppCompatActivity {


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notification_layout);

NotificationManager manager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
manager.cancel(1);
}
}

cancel(1),1是要取消的通知的id。

通知的进阶技巧

setSound(),可以在通知发出的时候播放一段音频。

setSound()方法接收一个Uri参数:

1
2
3
4
5
6
7
8
9
10
NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pi)
.setAutoCancle(true)
.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg"))
.build();

setVibrate(),可以在通知到时,让手机震动。

长整型的数组,设置手机静止和振动的时长,以毫秒为单位。下标为0的值表示手机静止的时长,下标为1的值表示手机振动的时长,下标为2的值表示手机静止的时长。

1
setVibrate(new long[]{0,1000,1000,1000})

控制手机振动的权限:

1
<uses-permission android:name="android.permission.VIBRATE"/>

如何在通知到来时控制手机LED灯的显示?
setLights()接收3个参数:

  1. 参数一,指定LED灯的颜色。
  2. 参数二,指定亮的时长,以毫秒为单位。
  3. 参数三,指定暗的时长,以毫秒为单位。
1
setLights(Color.GREEN,1000,1000)

通知的默认效果:

1
setDefaults(NotificationCompat.DEFAULT_ALL)

通知的高级功能

setSytle()方法允许构建富文本内容。

一般通知显示过长的文字,后面会用省略号代替。setSytle()可实现在通知中显示一段长文字。

1
setSytle(new NofitificationCompat.BigTextSytle().bigText("此处填充长文本内容"))

通知里显示大图片:

1
setSytle(new NotificationCompat.BigPictureSytle().bigPicture(BitmapFactory.decodeResource(getResource(),R.drawable.big_image)))

setPrority()方法可设置方法的重要程度。setPrority()接收一个整型参数设置通知的重要程度:

  1. PRIORITY_DEFAULT,默认的重要程度,和不设置的效果一样。
  2. PRIORITY_MIN,最低的重要程度,系统可能在特定的场景才显示通知。
  3. PRIORITY_LOW,较低的重要程度,系统可能会将这类通知缩小,或改变其显示的顺序。
  4. PRIORITY_HIGH,较高的重要程度,系统可能将这类通知放大,或改变其显示的顺序。
  5. PRIORITY_MAX,最高的重要程度,立即让用户看到,甚至需要用户做出相应操作。
1
setPriority(NotificationCompat.PRIORITY_MAX)