前一节已经对Android通知栏的初级用法进行了讲解,这篇高级用法主要讲解自定义布局的实现.
对于自定义布局来说,其实和普通的通知的整个流程是一致的,重点不同的是,把内容、标题和点击事件的处理整合在一个自定义布局里面.我们特别需要注意优一下几点.
// 构建通知的实例 NotificationCompat兼容性优
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
final RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.media_notification_layout);
rv.setTextViewText(R.id.title_tv, title);
rv.setTextViewText(R.id.content_tv, msg);
rv.setTextViewText(R.id.time_tv, DateUtil.format(new Date(System.currentTimeMillis()), "HH:mm"));
if (bitmap == null) {
rv.setViewVisibility(R.id.content_iv, View.GONE);
} else {
rv.setViewVisibility(R.id.content_iv, View.VISIBLE);
rv.setImageViewBitmap(R.id.content_iv, bitmap);
}
rv.setOnClickPendingIntent(R.id.btn1, getPendingIntent(context'type1'));
rv.setOnClickPendingIntent(R.id.btn2, getPendingIntent(context, 'type2');
rv.setOnClickPendingIntent(R.id.btn3, getPendingIntent(context,'type3'));
mBuilder.setChannelId('PUSH_CHANNEL_ID')
.setCustomContentView(rv)//自定义布局
.setContentIntent(getPendingIntent(context));
//设置通知自定义扩展布局
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
builder.setCustomBigContentView(rv);
}
//设置通知自定义声音
mBuilder.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/" +'音频文件id');
//设置通知默认声音
mBuilder.setDefaults(Notification.DEFAULT_ALL);
//设置通知icon
if (targetSdkVersion >= 21 && Build.VERSION.SDK_INT >= 21){
mBuilder.setSmallIcon(R.drawable.notification_small_icon);
mBuilder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.notification_large_icon));
} else {
mBuilder.setSmallIcon(R.drawable.statusbar_icon);
}
private static PendingIntent getPendingIntent(final Context context) {
Intent intent = new Intent(context, NotificationBroadcastReceiver.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
//通知extra内容处理
int ownID=1;//放在通知最外层,防止每次进来被初始化
ownID++;
requestCode = ownID;
return PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private static PendingIntent getPendingIntent(final Context context) {
Intent intent = new Intent(context, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
//通知extra内容处理
int ownID=1;//放在通知最外层,防止每次进来被初始化
ownID++;
requestCode = ownID;
return PendingIntent.getAcitivity(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public class NotificationBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//内容处理
//根据类型进行处理
//1、收起状态栏
//2、移除对应通知
}
}
/**
* 收起通知栏
*
* @param context
*/
public static void collapseStatusBar(Context context) {
@SuppressLint("WrongConstant") Object service = context.getSystemService("statusbar");
if (null == service)
return;
try {
@SuppressLint("PrivateApi") Class<?> clazz = Class.forName("android.app.StatusBarManager");
Method collapse;
if (Build.VERSION.SDK_INT <= 16) {
collapse = clazz.getMethod("collapse");
} else {
collapse = clazz.getMethod("collapsePanels");
}
collapse.setAccessible(true);
collapse.invoke(service);
} catch (Exception e) {
e.printStackTrace();
}
}
//创建通知管理器
if (notificationManager == null) {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
//设置通知渠道
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = new NotificationChannel('PUSH_CHANNEL_ID', context.getString(R.string.setting_channel_notification), NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
}
//发送通知
notificationManager.notify(notificationId, mBuilder.build());
//移除通知
if (notificationManager == null) {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
notificationManager.cancel(notificationId);
基本上通知的初级用法就是这些用法,重点注意高版本适配和某些特殊用法.