安卓8.0以上系统的通知栏适配

安卓的通知栏在发展过程中,主要经历了三个阶段,安卓3.0以下——>安卓3.0到安卓8.0以下——>安卓8.0以上。
在3.0之前创建通知栏也很简单

NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      n = new Notification(R.mipmap.app_icon, " 通知栏!", System.currentTimeMillis())
      manager.notify(1, n);

就这三句话就行了,也不需要权限什么的。

在安卓4.4到安卓8.0之间和安卓8.0以上需要在设置页面打开允许应用通知栏通知的选项。
代码如下:

public static void gotoNotificationSetting(Activity activity,int requestCode) {
        ApplicationInfo appInfo = activity.getApplicationInfo();
        String pkg = activity.getApplicationContext().getPackageName();
        int uid = appInfo.uid;
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
                //这种方案适用于 API 26, 即8.0(含8.0)以上可以用
                intent.putExtra(Settings.EXTRA_APP_PACKAGE, pkg);
                intent.putExtra(Settings.EXTRA_CHANNEL_ID, uid);
                //这种方案适用于 API21——25,即 5.0——7.1 之间的版本可以使用
                intent.putExtra("app_package", pkg);
                intent.putExtra("app_uid", uid);
                activity.startActivityForResult(intent, requestCode);
            } else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.setData(Uri.parse("package:" + MyApp.getApp().getPackageName()));
                activity.startActivityForResult(intent, requestCode);
            } else {
                Intent intent = new Intent(Settings.ACTION_SETTINGS);
                activity.startActivityForResult(intent, requestCode);
            }
        } catch (Exception e) {
            Intent intent = new Intent(Settings.ACTION_SETTINGS);
            activity.startActivityForResult(intent, requestCode);
            Log.e(sTAG, e.toString());
        }
    }

一共分为三种情况,每种版本都有不同的页面来设置通知栏通知权限。
在申请完相关的权限之后,就可以创建通知栏消息了。
安卓3.0到安卓8.0一下是采用如下代码进行创建通知栏的:

n = new Notification.Builder(context)
                    .setSmallIcon(R.mipmap.app_icon).setTicker("title")
                    .setContentTitle("收到一条消息")
                    .setContentText("开始监听通知栏!").setSubText("sub text")
                    .setWhen(System.currentTimeMillis()).build();

还有其他相关参数就不列举了。

安卓8.0以上的版本,需要对消息通知进行分类,使用channel对通知进行分组,channel代表着同一个应用内不同种类的通知,比如微信中,订阅号的消息和好友的消息就不是同一类消息,会在两组通知中显示出来。
安卓8.0以上创建通知栏消息代码如下:

//创建channel
 	    @TargetApi(Build.VERSION_CODES.O)
	    public static void createNotificationChannel(Context context,String channelId, String channelName, int importance) {
		        NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
		        NotificationManager notificationManager = (NotificationManager) context.getSystemService(
		                context.NOTIFICATION_SERVICE);
		        notificationManager.createNotificationChannel(channel);
		        PrintLog.log(context,TAG,"createNotificationChannel:"+channelId);
	    }
         
         //创建通知栏消息
         n = new NotificationCompat.Builder(context, "subscribe")
                    .setContentTitle("这是前台服务")
                    .setContentText("负责监听通知栏消息!")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.app_icon)
                    .setAutoCancel(true)
                    .build();

以上就是创建通知栏在不同版本的区别。

接下来介绍下

通知栏监听器

Android在4.3的版本中(即API 18)加入了NotificationListenerService,根据SDK的描述(AndroidDeveloper)可以知道,当系统收到新的通知或者通知被删除时,会触发NotificationListenerService的回调方法。同时在Android 4.4 中新增了Notification.extras 字段,也就是说可以使用NotificationListenerService获取系统通知具体信息,这在以前是需要用反射来实现的。

对于系统通知,三方APP使用NotificationListenerService主要目的是为了获取系统通知相关信息,主要包括:通知的新增和删 除,获取当前通知数量,通知内容相关信息等。这些信息可以通过NotificationListenerService类提供的方法以及 StatusBarNotification类对象来获取。

NotificationListenerService主要方法(成员变量):

cancelAllNotifications() :删除系统中所有可被清除的通知;
cancelNotification(String pkg, String tag, int id) :删除具体某一个通知;
getActiveNotifications() :返回当前系统所有通知到StatusBarNotification[];
onNotificationPosted(StatusBarNotification sbn) :当系统收到新的通知后出发回调;
onNotificationRemoved(StatusBarNotification sbn) :当系统通知被删掉后出发回调;
以上是NotificationListenerService的主要方法,通过这些方法就可以在应用中操作系统通知,在 NotificationListenerService中除了对通知的操作之外,还可以获取到通知的StatusBarNotification对象, 通过该对象可以获取通知更详细的数据。

StatusBarNotification主要方法(成员变量):

getId():返回通知对应的id;
getNotification():返回通知对象;
getPackageName():返回通知对应的包名;
getPostTime():返回通知发起的时间;
getTag():返回通知的Tag,如果没有设置返回null;
getUserId():返回UserId,用于多用户场景;
isClearable():返回该通知是否可被清楚,FLAG_ONGOING_EVENT、FLAG_NO_CLEAR;
isOngoing():检查该通知的flag是否为FLAG_ONGOING_EVENT;

通过以上方法可以做一个拦截手机通知栏的功能,并且可以上传到远程服务器上,

源代码链接如下:
点我试试 运行之后的效果如下:
1.自动拦截消息,并清空通知栏。
2.自动上传消息到服务器。
3.安卓4.4以上都兼容。
注:自己填写服务,我的服务器地址不开放。

android app通知栏权限 安卓通知栏权限_Notification