Notification的一些新特性
普通的Notification写法
首先需要初始化一个NotificationManager:
NotificationManager notificationManager = (
NotificationManager)getSystemService(
NOTIFICATION_SERVICE)
1. 基本的Notification:
private void sendBasicNotification(){
NotificationCompat.
Builder builder =
new NotificationCompat.Builder(this);
Intent
intent =
new
Intent(
Intent.
ACTION_VIEW,
Uri.parse("https://wwww.baidu.com"));
PendingIntent
pendingIntent =
PendingIntent.
getActivity(this,
0, intent,
0);
Notification
notification =
builder
.
setContentIntent(pendingIntent)
.
setSmallIcon(
R.mipmap.ic_launcher_round)
.
setLargeIcon(
BitmapFactory.decodeResource(getResources(),
R.
mipmap.
ic_launcher))
.
setAutoCancel(true)
.
setContentTitle("一个普通的通知~")
.
setContentText("这是
Content啊!").
build();
notificationManager.
notify(
0, notification);
}
由于android系统的手机厂商太多,相同代码下Notification的表现也可能不一样,所以有些差异只能慢慢去琢磨。
2. 展示更多内容
Notification的高度都有一个通用标准,据说是64dp。如果想要展示更多的内容比如文字,可以用下面的办法:
...
...
NotificationCompat.BigTextStyle bigTextStyle =
new NotificationCompat.BigTextStyle(builder);
bigTextStyle.bigText(
"长到没边的文字就问你拍不怕!长到没边的文字就问你拍不怕长到没边的文字就问你拍不怕!长到没边的文字就问你拍不怕!长到没边的文字就问你拍不怕!长到没边的文字就问你拍不怕!长到没边的文字就问你拍不怕!长到没边的文字就问你拍不怕!长到没边的文字就");
builder.setStyle(bigTextStyle)
...
...
除了BigTextStyle,NotificationCompat类还有BigPictureStyle等其它Style,支持更多的扩展内容。
3. 悬浮通知, 让通知直接展示在屏幕上。
哇,这个我根本不太敢写,因为不同手机品牌的差异太大了! 就小米4手机来说,目前通知管理的选择项有:
- 是否允许通知
- 是否悬浮通知
- 是否允许锁屏通知
- 是否允许通知铃声
- 是否允许振动
- 是否允许呼吸灯闪烁
- 等等…
也就是说,如果不在手机设置里打开这些选项,即使在代码里写了这些东西也没用。目前我只在三台手机上有测试:
- vivo X7 android 5.1.1 : 只要给builder.setTicker(“”),通知就能变成悬浮通知
- 小米4 android 6.0.1 : 设什么都没用,但只要在手机设置里把允许悬浮通知打开,无论如何都会是悬浮通知
- google pixel 模拟器 android N : 需要设置通知的优先权为最大,同时设置通知声音才有效
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
builder.setSound(alarmSound)
builder.setPriority(NotificationCompat.PRIORITY_MAX)
真是一个坑,不是吗?
完全自定义样式的Notification
public final
static
int NOTIFICATION_ID =
11;
private void sendCustomNotification(){
NotificationCompat.Builder builder =
new NotificationCompat.Builder(
this);
Intent intent =
new Intent(Intent.ACTION_VIEW, Uri.parse(
"https://www.baidu.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0, intent,
0);
RemoteViews remoteViews =
new RemoteViews(getPackageName(), R.layout.view_notification);
Intent clickIntent =
new Intent(
this, NotificationReceiver.
class);
clickIntent.putExtra(
"id", NOTIFICATION_ID);
PendingIntent buttonPendingIntent = PendingIntent.getBroadcast(
this,
0, clickIntent,
0);
remoteViews.setOnClickPendingIntent(R.id.button_noti, buttonPendingIntent);
Notification notification = builder.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setAutoCancel(
true)
.setContent(remoteViews)
.setTicker(
"")
.build();
notificationManager.notify(NOTIFICATION_ID, notification);
}
1. 通过RemoteViews可以给Notification添加一个自定义布局
RemoteViews有自带的方法可以对布局中的控件设置各种属性,比如给Button添加点击事件、给TextView添加文字、给ImageView设置图片资源、给ProgressBar设置进度等等,RemoteViews这个类值得好好去探究一番。
2. 通知布局的高度
自定义布局并不意味着Notification的高度不受限制,Notification的高度受到系统的制约, 使用自定义布局时必须考虑到这一点。上面代码有setContent()和setCustomBigContentView()两个方法,如果只要正常高度的通知,使用第一个方法就好,如果需要展示更高的通知布局,则使用第二个方法。使用第二个方法时,在某些手机上,可能需要手动下拉通知,通知的布局才会全部展示出来。
3. 布局里控件的点击事件
这里我给布局中的按钮设置了一个点击事件。但是点击按钮之后,Notification并不会消失,为了让它能消失我使用了一个广播接收器,接收按钮的点击,然后在接收器里处理按钮的点击事件, 并消除掉Notification。这似乎不是最佳解决办法,但目前只想到这一点。(真实情况下,要求点击一个控件就使Notification消失的案例可能不常见,如果只是单纯的需要点击跳转,直接把点击事件设给Notification就好了) Receiver代码如下:
public
class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(
Context context,
Intent intent) {
if(intent.getIntExtra(
"id",
0) ==
MainActivity.
NOTIFICATION_ID){
Intent intent1 =
new
Intent(context,
SecondActivity.
class);
intent1.addFlags(
Intent.
FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
NotificationManager notiManager = (
NotificationManager) context.getSystemService(
Context.
NOTIFICATION_SERVICE);
notiManager.cancel(
MainActivity.
NOTIFICATION_ID);
}
}
}
最后
有些手机可能会把app的通知默认设为关闭,所以有些应用可能永远都发不了通知。这需要用户主动去 手机设置 的 通知管理里面允许app使用通知。而在代码里,我们唯一能做的就是检测app是否能够发送通知 并且 引导用户去设置里面打开通知。
1. 检测app通知是否被禁止:
boolean isNotiEnable = NotificationManagerCompat.
from(
this).areNotificationsEnabled();
这个方法可以告诉我们当前app是否能够发通知。
引导用户打开通知:
Intent
intent = new
Intent(ACTION_APP_NOTIFICATION_SETTINGS);
startActivity(
intent);
以上代码可以直接跳转到设置的通知管理界面。但是啊,ACTION_APP_NOTIFICATION_SETTINGS 是API 26,也就是Andorid 8.0才支持的,所以如果是8.0以下的手机,可以跳转到app设置详情界面:
Intent
intent = new
Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts(
"package", getPackageName(), null);
intent.setData(uri);
startActivity(
intent);
总结
这篇文章只是对我自己掌握的Notification知识做一个总结,当然不是一篇全面的Notification总结文章。还有很多不到之处,望能与大家一起探讨进步。