IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 10 后台启动Activity(app切换到前台) -> 正文阅读

[移动开发]Android 10 后台启动Activity(app切换到前台)

目录

过程分析

解决方案

在AndroidManifest.xml上添加权限

检查是否开启悬浮窗权限

打开悬浮窗权限设置页


????????最近需要开发一个某些时候需要把app唤醒并置于前台的功能。刚开发时,在模拟器正常,后来上真机出问题了。进行排查发现模拟器api是28的,真机是api29(Android 10),查资料发现,api29版本禁止后台启动activity,而造成的。

过程分析

具体资料如下:

从后台启动 Activity 的限制

Android10(Api 29)新特性适配小结

从官方文档得知,在一些情况下,可以允许从后台启动Activity,具体如下:

在 Android?10 或更高版本上运行的应用只有在满足以下一项或多项条件时,才能启动 Activity:

  • 应用具有可见窗口,例如前台 Activity。
  • 应用在前台任务的返回栈中拥有 Activity。
  • 应用在?Recents?屏幕上现有任务的返回栈中拥有 Activity。

    注意:当此类应用尝试启动新的 Activity 时,系统会将该 Activity 放置到应用现有任务的顶部,但不会离开当前可见的任务。当用户稍后返回应用任务时,系统会启动新的 Activity,而不是之前放置在应用任务顶部的 Activity。

  • 应用的某个 Activity 刚在不久前启动。

  • 应用最近为某个 Activity 调用了?finish()。这仅适用于在调用?finish()?时,应用在前台或前台任务的返回栈中拥有 Activity 的情况。

  • 应用具有受系统约束的服务。此情况仅适用于以下服务,这些服务可能需要启动界面:AccessibilityServiceAutofillServiceCallRedirectionServiceHostApduServiceInCallServiceTileServiceVoiceInteractionService?和?VrListenerService

  • 应用中的某个服务受另一个可见应用约束。请注意,绑定到服务的应用必须保持可见,以便后台应用成功启动 Activity。

  • 应用收到系统的?PendingIntent?通知。对于服务和广播接收器的挂起 Intent,应用可在该挂起 Intent 发送几秒钟后启动 Activity。

  • 应用收到另一个可见应用发送的?PendingIntent

  • 应用收到它应该在其中启动界面的系统广播。示例包括?ACTION_NEW_OUTGOING_CALL?和?SECRET_CODE_ACTION。应用可在广播发送几秒钟后启动 Activity。

  • 应用通过?CompanionDeviceManager?API 与配套硬件设备相关联。此 API 支持应用启动 API,以响应用户在配对设备上执行的操作。

  • 应用是在设备所有者模式下运行的设备政策控制器。示例用例包括完全托管的企业设备,以及数字标识牌和自助服务终端等专用设备

  • 用户已向应用授予?SYSTEM_ALERT_WINDOW?权限。

解决方案

? ? ? ? 通过让用户授权SYSTEM_ALERT_WINDOW?权限,既悬浮窗权限即可。

  • 在AndroidManifest.xml上添加权限

 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

  • 检查是否开启悬浮窗权限

代码摘自

Android悬浮窗权限“android.permission.SYSTEM_ALERT_WINDOW”判断是否开启问题

public static boolean checkFloatPermission(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)//4.4-5.1
            return true;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {//6.0
            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) {//8
                AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
                if (appOpsMgr == null)
                    return false;
                int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window", android.os.Process.myUid(), context
                        .getPackageName());
                return Settings.canDrawOverlays(context) || mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_IGNORED;
            } else {
                return Settings.canDrawOverlays(context);
            }
        }
    }

  • 打开悬浮窗权限设置页

if(!(checkFloatPermission(this))){
            Toast.makeText(getApplicationContext(),"请给软件设置悬浮窗权限,否则无法正常使用!",Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
            startActivity(intent);
        }

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-26 12:12:28  更:2021-07-26 12:12:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/22 23:43:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码