今天着手解决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); if (manager.areNotificationsEnabled()) { return isNotifyPushChannelEnable(context); } return manager.areNotificationsEnabled(); }
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){
Intent appIntent = context.getPackageManager().getLaunchIntentForPackage("com.iqoo.secure"); if(appIntent != null){ context.startActivity(appIntent); return; }
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) { 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); } }
|