Android前台service和Notification

8.0版本Notifacation适配/Notification开关判断与设置跳转

Posted by JamesPxy on 2019-11-15

今天着手解决Android8.0以上前台服务的问题,还是有些许收获的,下面来简单总结一下:

  • 然后再了解一下通知概览

  • 从 Android 8.0(API 级别 26)开始,所有通知都必须分到一个渠道,否则通知将不会显示。 通过将通知分类到渠道,用户可以停用应用的特定通知渠道(而不是停用所有通知),还可以控制每个渠道的视觉和听觉选项,所有这些操作都在 Android 系统设置中完成(如图 11 所示)。用户还可以长按通知以更改关联渠道的行为。

  • 我实践了一下,我们可以不注册前台服务的通知渠道,然后startService()时照常在onCreate()中调用startForeground(),实际效果是service依然正常运行,历久弥新,并没有被系统干掉。具体可能需要灰度看在更多的机器上的表现。当然钻系统的这种漏洞是不好,但是通知栏一直干扰用户带来的体验更差,只能有所倾向和选择了。此外还需要留意是否会出现BadNotifacation异常。目前我测试的机器上是没有遇到过这个异常的。

  • 另外再推荐一篇关于通知栏适配的文章
    网易考拉 Android 通知栏适配全方案
    失效点击这里

通知栏开关状态判断,包括高版本通知渠道判断,以及跳转去设置引导打开开关工具类。

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class NotificationPageHelper {

public static boolean isNotificationOpen(Context context) {
NotificationManagerCompat manager = NotificationManagerCompat.from(context);
// areNotificationsEnabled方法的有效性官方只最低支持到API 19,
// 低于19的仍可调用此方法不过只会返回true,即默认为用户已经开启了通知。
if (manager.areNotificationsEnabled()) {
return isNotifyPushChannelEnable(context);
}
return manager.areNotificationsEnabled();
}

/**
* 通知渠道的开关
* 8.0以上增加对通知渠道开关的判断
* 主要是为了解决vivo、oppo等手机对应渠道通知大概率会被关闭问题
*/
public static boolean isNotifyPushChannelEnable(Context context) {
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = ((NotificationManager) context.getSystemService(NOTIFICATION_SERVICE))
.getNotificationChannel(NotificationUtils.CHANNEL_ID);
return channel.getImportance() > NotificationManager.IMPORTANCE_NONE;
}
return true;
}


/**
* 跳转到权限设置界面
*/
public static void openNotification(Context context){

// vivo 点击设置图标>加速白名单>我的app
// 点击软件管理>软件管理权限>软件>我的app>信任该软件
Intent appIntent = context.getPackageManager().getLaunchIntentForPackage("com.iqoo.secure");
if(appIntent != null){
context.startActivity(appIntent);
return;
}

// oppo 点击设置图标>应用权限管理>按应用程序管理>我的app>我信任该应用
// 点击权限隐私>自启动管理>我的app
appIntent = context.getPackageManager().getLaunchIntentForPackage("com.oppo.safe");
if(appIntent != null){
context.startActivity(appIntent);
return;
}

Intent intent = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 8.0以上跳转引导
NotificationManager manager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
NotificationChannel channel = manager.getNotificationChannel(NotificationUtils.CHANNEL_ID);
if (channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {
intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel.getId());
} else {
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra("app_package", context.getPackageName());
intent.putExtra("app_uid", context.getApplicationInfo().uid);
} else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD){
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
} else {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
intent.setClassName("com.android.settings","com.android.settings.InstalledAppDetails");
intent.putExtra("com.android.settings.ApplicationPkgName", context.getPackageName());
}
context.startActivity(intent);
}
}


支付宝打赏 微信打赏

赞赏一下