Android APP息屏状态下收到通知解决方案

您所在的位置:网站首页 小米k40息屏接收不到信息 Android APP息屏状态下收到通知解决方案

Android APP息屏状态下收到通知解决方案

2024-07-14 21:54| 来源: 网络整理| 查看: 265

1.问题

       最近负责的Android APP,用户反馈无法收到通知,尤其是息屏状态下无法收到通知。

       这些APP,笔者以前都测试过,可以收到推送的。但测试以后,发现在新的Android上,确实收不到通知和推送。

       根本原因在于:在最新的Android系统里,基于省电考虑,如果相关应用没有在系统白名单里,则会在锁屏之后,会被优化掉而不再运行;这样,APP将不再收到通知和推送。

       用户还抱怨:微信能收到消息,为啥你们不能?笔者查阅资料后得知:在几乎所有Android系统里,微信、QQ、企业微信都被默认在系统白名单里,可以开机运行,锁屏后后台运行。

2.解决方案整体思路

       但问题还得解决,解决思路为:

      1)允许APP收到通知;

      2)允许APP自启动;

      3)打开APP的悬浮窗;

      4)在电量管理里,允许APP在耗电状态下长期运行。

      值得注意的是:这一系列操作,只能让使用者自己来完成;这样的APP才能才能被认为是合规的。

      对于用户来说,可以做的,其实是提供引导程序,让用户来操作。

3.引导程序

       提供的引导程序如下:

开启通知工具类:

/** * Created by Administrator * 开启通知 */ public class NotificationUtil { /** * 跳转到app的设置界面--开启通知 * @param context */ public static void goToNotificationSetting(Context context) { Intent intent = new Intent(); if (Build.VERSION.SDK_INT >= 26) { // android 8.0引导 intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName()); } else if (Build.VERSION.SDK_INT >= 21) { // android 5.0-7.0 intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); intent.putExtra("app_package", context.getPackageName()); intent.putExtra("app_uid", context.getApplicationInfo().uid); } else { // 其他 intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.setData(Uri.fromParts("package", context.getPackageName(), null)); } intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } /** * 判断是否需要打开通知 * @param context */ public static boolean isNotificationEnabled(Context context) { boolean isOpened = false; try { isOpened = NotificationManagerCompat.from(context).areNotificationsEnabled(); } catch (Exception e) { e.printStackTrace(); isOpened = false; } return isOpened; } }

权限检查工具类:

/** * Created by Administrator * 权限检查 */ public class PermissionCheckUtil { //判断是否开启悬浮窗权限 context可以用你的Activity.或者tiis public static boolean checkFloatPermission(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { return true; } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { try { Class cls = Class.forName("android.content.Context"); Field declaredField = cls.getDeclaredField("APP_OPS_SERVICE"); declaredField.setAccessible(true); Object obj = declaredField.get(cls); if (!(obj instanceof String)) { return false; } String str2 = (String) obj; obj = cls.getMethod("getSystemService", String.class).invoke(context, str2); cls = Class.forName("android.app.AppOpsManager"); Field declaredField2 = cls.getDeclaredField("MODE_ALLOWED"); declaredField2.setAccessible(true); Method checkOp = cls.getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class); int result = (Integer) checkOp.invoke(obj, 24, Binder.getCallingUid(), context.getPackageName()); return result == declaredField2.getInt(cls); } catch (Exception e) { return false; } } else { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); if (null == appOpsMgr) { return false; } int mode = appOpsMgr.checkOpNoThrow( "android:system_alert_window", android.os.Process.myUid(), context .getPackageName() ); return mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_IGNORED; } else { return Settings.canDrawOverlays(context); } } } //权限打开 public static void requestSettingCanDrawOverlays(Context context) { int sdkInt = Build.VERSION.SDK_INT; if (sdkInt >= Build.VERSION_CODES.O) { //8.0以上 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); // startActivityForResult(intent, REQUEST_DIALOG_PERMISSION); context.startActivity(intent); } else if (sdkInt >= Build.VERSION_CODES.M) { //6.0-8.0 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.parse("package:" + context.getPackageName())); // startActivityForResult(intent, REQUEST_DIALOG_PERMISSION); context.startActivity(intent); } else { //4.4-6.0以下 //无需处理了 } } }

自启动工具类

/** * Created by Administrator * 自启动设置 */ public class AutoStartUtil { /** * 获取自启动管理页面的Intent * @param context context * @return 返回自启动管理页面的Intent * */ public static void getAutostartSettingIntent(Context context) { ComponentName componentName = null; String brand = Build.MANUFACTURER; Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { switch (brand.toLowerCase()) { case "samsung"://三星 componentName = new ComponentName("com.samsung.android.sm", "com.samsung.android.sm.app.dashboard.SmartManagerDashBoardActivity"); break; case "huawei"://华为 //荣耀V8,EMUI 8.0.0,Android 8.0上,以下两者效果一样 componentName = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity"); // componentName = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");//目前看是通用的 break; case "xiaomi"://小米 componentName = new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"); break; case "vivo"://VIVO // componentName = new ComponentName("com.iqoo.secure", "com.iqoo.secure.safaguard.PurviewTabActivity"); componentName = new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity"); break; case "oppo"://OPPO // componentName = new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity"); componentName = new ComponentName("com.coloros.oppoguardelf", "com.coloros.powermanager.fuelgaue.PowerUsageModelActivity"); break; case "yulong": case "360"://360 componentName = new ComponentName("com.yulong.android.coolsafe", "com.yulong.android.coolsafe.ui.activity.autorun.AutoRunListActivity"); break; case "meizu"://魅族 componentName = new ComponentName("com.meizu.safe", "com.meizu.safe.permission.SmartBGActivity"); break; case "oneplus"://一加 componentName = new ComponentName("com.oneplus.security", "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity"); break; case "letv"://乐视 intent.setAction("com.letv.android.permissionautoboot"); default://其他 intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.setData(Uri.fromParts("package", context.getPackageName(), null)); break; } intent.setComponent(componentName); context.startActivity(intent); } catch (Exception e){ Log.e("HLQ_Struggle", e.getLocalizedMessage()); AlertDialog.Builder builder = new AlertDialog.Builder(context); //设置标题 builder.setTitle("请用户设置自启动"); //设置对话框内容 builder.setMessage("请用户别忘记设置自启动!!!"); //设置图标 builder.setIcon(android.R.drawable.ic_dialog_alert); //设置是否可以点击屏幕其他地方或者返回键取消显示 builder.setCancelable(false); //确定按钮 builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //该按钮的点击事件,这里设置按钮返回 dialog.dismiss(); } }); //很多朋友都会忘了show builder.show(); intent = new Intent(Settings.ACTION_SETTINGS); context.startActivity(intent); } } }

电池优化工具类:

/** * Created by Administrator * 对电池进行管理,使APP避免被电池优化 */ public class BatteryManagementUtil { /** * 忽略电池优化 */ public static void ignoreBatteryOptimization(Context context) { PowerManager powerManager = (PowerManager) context.getSystemService(POWER_SERVICE); boolean hasIgnored = false; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { hasIgnored = powerManager.isIgnoringBatteryOptimizations(context.getPackageName()); // 判断当前APP是否有加入电池优化的白名单,如果没有,弹出加入电池优化的白名单的设置对话框。 if (!hasIgnored) { try {//先调用系统显示 电池优化权限 Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + context.getPackageName())); context.startActivity(intent); } catch (Exception e) {//如果失败了则引导用户到电池优化界面 try { Intent intent = new Intent(Intent.ACTION_MAIN); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addCategory(Intent.CATEGORY_LAUNCHER); ComponentName cn = ComponentName.unflattenFromString("com.android.settings/.Settings$HighPowerApplicationsActivity"); intent.setComponent(cn); context.startActivity(intent); }catch (Exception ex){//如果全部失败则说明没有电池优化功能 ex.printStackTrace(); Intent intent = new Intent(Settings.ACTION_SETTINGS); context.startActivity(intent); } } } } } }

整个程序放在MainActivity的OnCreate()函数里:

NotificationUtil.goToNotificationSetting(MainActivity.this); //打开悬浮窗 PermissionCheckUtil.requestSettingCanDrawOverlays(MainActivity.this); //打开自启动窗口 AutoStartUtil.getAutostartSettingIntent(MainActivity.this); //打开电池优化 BatteryManagementUtil.ignoreBatteryOptimization(MainActivity.this);

4.目前结果

         引导之后,部分机型可以直接设置。当然,部分机型还有如下问题:

         1)小米需要更改通知过滤规则,避免消息被过滤掉;

         2)华为需要手动在电池管理里进行操作,才能进行自启动和后台运行。

        没办法,提供操作说明和解决方案吧。提供解决方案以后,目前还正常。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3