Android(安卓)通知(Notification)高级用法和注意事项
16lz
2021-12-04
前言
前一节已经对Android通知栏的初级用法进行了讲解,这篇高级用法主要讲解自定义布局的实现.
- 上一节 Android 通知(Notification)初级用法和注意事项
https://blog.csdn.net/GL_MINE_CSDN/article/details/83894357
Notofication 自定义布局说明
对于自定义布局来说,其实和普通的通知的整个流程是一致的,重点不同的是,把内容、标题和点击事件的处理整合在一个自定义布局里面.我们特别需要注意优一下几点.
- 大小
- 默认布局高度为64
- 最大扩展高度为256
- 颜色
- 尽量使用系统默认颜色,不同手机系统背景颜色不一致,导致显示效果有差异
- 点击事件
- 重点处理
- 如果使用PendingIntent.getBroadcast,需要手动处理,状态栏的收起,通知的移除
- 如果使用PendingIntent.getAcitivity,需要手动处理状态栏的收起
Notofication 构建实例
// 构建通知的实例 NotificationCompat兼容性优 NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
Notofication 搭建自定义布局
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'));
- 重点说明
- 当自定布局中出现需要获取网络图片的时候,应该先请求网络资源成功之后,在创建和发送通知 整个流程,因为通知的执行属性导致网络图片无法正常显示
Notification 设置属性
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); }
- 重点说明
- setSmallIcon,必须设置属性,因为是手机状态栏上面的提示图标
- 当targetSdkVersion >= 21 && Build.VERSION.SDK_INT >= 21 必须设置setLargeIcon,并且setSmallIcon设置为透明的图标,否则不显示
- 当 Build.VERSION.SDK_INT>=21 必须设置setCustomBigContentView
- setSmallIcon,必须设置属性,因为是手机状态栏上面的提示图标
Notification 点击事件
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); }
Notification 点击事件处理
public class NotificationBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //内容处理 //根据类型进行处理 //1、收起状态栏 //2、移除对应通知 } }
- 重点说明
- 点击事件分为两类
- PendingIntent.getBroadcast 通知处理
- PendingIntent.getActivity 直接处理
- 自定义布局处理点击事件时,需要手动收起状态栏和移除对应通知
- 点击事件分为两类
Notification 收起状态栏
/** * 收起通知栏 * * @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(); } }
Notification 创建通知管理器
//创建通知管理器 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); }
- 重点说明
- Build.VERSION.SDK_INT >= 26,需要设置createNotificationChannel,并且设置setChannelId
Notification 发送通知
//发送通知 notificationManager.notify(notificationId, mBuilder.build());
- 重点说明
- notificationId 用来发送和移除对应的通知
Notification 移除通知
//移除通知 if (notificationManager == null) { notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); } notificationManager.cancel(notificationId);
Notification 结束语
基本上通知的初级用法就是这些用法,重点注意高版本适配和某些特殊用法.
Notification 参考文献
- Android通知栏介绍与适配总结
- https://iluhcm.com/2017/03/12/experience-of-adapting-to-android-notifications/
更多相关文章
- Android(安卓)图像处理(一) : Shader
- Android(安卓)应用程序权限
- Android(安卓)打开本地pdf文件,android 加载pdf文件
- [Android]为Spinner填充数据后设置默认值的问题
- android:configChanges属性
- Android教程-Android(安卓)五大布局讲解与应用
- 探究Android异步消息的处理之Handler详解
- Android(安卓)Touch事件原理加实例分析
- ScrollView常用属性汇总