Android15适配Edge

Android15适配

Gradle插件版本升级

项目下的build.gradle未升级前:

复制代码
dependencies {
    classpath 'com.android.tools.build:gradle:8.4.2'
    classpath 'com.google.gms:google-services:4.3.8'
    classpath 'com.huawei.agconnect:agcp:1.9.1.301'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    // Google Services plugin
    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

项目的build.gradle升级后:

复制代码
   dependencies {
        classpath 'com.android.tools.build:gradle:8.10.0'
        classpath 'com.google.gms:google-services:4.3.8'
        classpath 'com.huawei.agconnect:agcp:1.9.1.301'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

    }

gradle插件升级前:

复制代码
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip

gradle插件升级后:

kotlin版本升级

未升级前:

复制代码
buildscript {
    ext {
        kotlin_version = '1.9.23'
    }
    repositories {
        google()
        mavenCentral()
        // hms
        maven { url 'https://developer.huawei.com/repo/'}
        // fcm
        maven { url "https://maven.google.com" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.10.0'
        classpath 'com.google.gms:google-services:4.3.8'
        classpath 'com.huawei.agconnect:agcp:1.9.1.301'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // Google Services plugin
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

升级后:

复制代码
buildscript {
    ext {
        kotlin_version = '2.1.0'
    }
    repositories {
        google()
        mavenCentral()
        // hms
        maven { url 'https://developer.huawei.com/repo/'}
        // fcm
        maven { url "https://maven.google.com" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.10.0'
        classpath 'com.google.gms:google-services:4.3.8'
        classpath 'com.huawei.agconnect:agcp:1.9.1.301'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // Google Services plugin
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

3.EdgeToEdge适配:

3.1 dialog适配:

显示白色背景和导航栏

复制代码
<style name="TransparentNavDialogTheme" parent="Theme.AppCompat.Light.Dialog.Alert">
    <!-- 禁用默认导航栏颜色 -->
    <item name="android:navigationBarColor">@android:color/transparent</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <!-- 禁用背景变暗 -->
    <item name="android:backgroundDimEnabled">false</item>
    <!-- 允许窗口延伸到系统栏 -->
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:windowTranslucentNavigation">false</item>
    <item name="android:windowTranslucentStatus">false</item>
</style>

3.2 Dialog背景透明隐藏导航栏和状态栏:

复制代码
fun setUpEdgToEdg(dialog: android.app.AlertDialog?, rootView:View){
    dialog?.let {
            val window: Window = it.window!!
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
            window.statusBarColor = Color.TRANSPARENT
            window.navigationBarColor = Color.TRANSPARENT
            WindowCompat.setDecorFitsSystemWindows(window, false)

            ViewCompat.setOnApplyWindowInsetsListener(
                rootView
            ) { v: View, insets: WindowInsetsCompat ->
                val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
                val ime = insets.getInsets(WindowInsetsCompat.Type.ime())
                val bottomPadding = max(systemBars.bottom, ime.bottom)
                v.setPadding(systemBars.left, systemBars.top, systemBars.right, bottomPadding)
                insets
            }
            val controllerCompat = WindowCompat.getInsetsController(
                window, window.decorView
            )
            controllerCompat.isAppearanceLightStatusBars = false
            controllerCompat.isAppearanceLightNavigationBars = false
            controllerCompat.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
            controllerCompat.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }
}

3.3 Dialog透明背景且导航栏显示浅色:

复制代码
fun setUpEdgToEdgToDiaLog(dialog: android.app.AlertDialog?, rootView:View){
        dialog?.let {
                val window: Window = it.window!!
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                WindowCompat.setDecorFitsSystemWindows(window, false)
                ViewCompat.setOnApplyWindowInsetsListener(
                    rootView
                ) { v: View, insets: WindowInsetsCompat ->
                    val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
                    val ime = insets.getInsets(WindowInsetsCompat.Type.ime())
                    val bottomPadding = max(systemBars.bottom, ime.bottom)
                    v.setPadding(systemBars.left, systemBars.top, systemBars.right, bottomPadding)
                    insets
                }
                val controllerCompat = WindowCompat.getInsetsController(
                    window, window.decorView
                )
                //浅色状态栏
                controllerCompat.isAppearanceLightStatusBars = false
                //深色导航栏
                controllerCompat.isAppearanceLightNavigationBars = true
                //隐藏导航栏和状态栏
                //controllerCompat.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
                controllerCompat.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        }
    }



<style name="ActionBottomDialogStyle" parent="Theme.Design.BottomSheetDialog">

    <!-- 背景透明 -->
    <item name="android:windowBackground">@android:color/transparent</item>
   <!-- <item name="android:windowContentOverlay">@null</item>-->
    <!-- 浮于Activity之上 -->
    <item name="android:windowIsFloating">false</item>
    <!-- 边框 -->
    <item name="android:windowFrame">@null</item>
    <!-- Dialog以外的区域模糊效果 -->
   <!-- <item name="android:backgroundDimEnabled">true</item>
    <item name="android:backgroundDimAmount">0.5</item>-->
    <!-- 无标题 -->
    <item name="android:windowNoTitle">true</item>
    <!-- 半透明 -->
   <!-- <item name="android:windowIsTranslucent">true</item>-->
    <item name="android:navigationBarColor">@color/white</item>

    <item name="android:windowFullscreen">true</item>
    <!-- Dialog进入及退出动画 -->
    <item name="android:windowAnimationStyle">@style/ActionSheetDialogAnimation</item>
    <!-- ActionSheet进出动画 -->
</style>

4.App违规收集应用信息:

4.1 问题截图

4.2 问题排查思路:

  • 检查动态注册的广播(代码中隐藏) 可能在代码中通过 registerReceiver 动态注册了广播,但未显式使用 ACTION_PACKAGE_ADDED 等常量(如使用字符串字面量),导致搜索不到。 排查方法: 全局搜索项目中所有 registerReceiver 调用,检查传入的 IntentFilter 是否包含以下字符串: "android.intent.action.PACKAGE_ADDED" "android.intent.action.PACKAGE_REMOVED" "android.intent.action.PACKAGE_REPLACED" 检查是否有通过反射、动态字符串拼接注册广播的情况(较少见,但需排查)。 整改方法: 若发现动态注册的相关广播,删除对应的 registerReceiver 调用和接收器逻辑。
  • 检查应用是否申请了相关敏感权限 即使未注册广播,若申请了某些与应用列表相关的权限(如 QUERY_ALL_PACKAGES),可能被误认为在收集安装 / 卸载信息(尽管权限本身不直接关联广播,但可能被关联检测)。 排查方法: 检查清单文件中是否有 android.permission.QUERY_ALL_PACKAGES 权限(Android 11+ 用于查询所有应用)。 检查是否有 android.permission.GET_PACKAGE_SIZE 等与应用信息相关的权限。 整改方法: 若未使用这些权限,在清单文件中删除。 若必须使用(如应用市场功能),按 Google 要求在 Play Console 中说明权限用途,并确保仅用于必要场景。
  • 检查 "应用使用情况" 权限相关逻辑 若应用申请了 android.permission.PACKAGE_USAGE_STATS(通过 Settings.ACTION_USAGE_ACCESS_SETTINGS 授权),可能被误认为在跟踪应用安装 / 卸载(尽管该权限主要用于获取应用使用时长)。 排查方法: 搜索项目中是否有请求 "应用使用情况访问权限" 的代码(如跳转到权限设置页面)。 整改方法: 若未使用该功能,删除相关权限申请和跳转逻辑。

4.3 排查第三方sdk:

4.4 排查自己的app:

去掉权限PACKAGE_USAGE_STATS

复制代码
<uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    android:protectionLevel="signature|privileged"
    tools:ignore="ProtectedPermissions" />

4.5 排查是否为此权限:

4.6 验证上面的问题思路:

在使用情况权限查看App有没有申请此权限:

去掉后权限运行App:

相关推荐
yBmZlQzJ14 小时前
财运到内网穿透域名解析技术机制与中立评估
运维·经验分享·docker·容器·1024程序员节
yBmZlQzJ16 小时前
内网穿透工具通过端口转发实现内外网通信
运维·经验分享·docker·容器·1024程序员节
数据皮皮侠AI1 天前
数字经济政策工具变量数据(2008-2023)
大数据·数据库·人工智能·笔记·1024程序员节
网安_秋刀鱼2 天前
【java安全】shiro反序列化1(shiro550)
java·开发语言·安全·web安全·网络安全·1024程序员节
unable code4 天前
攻防世界-Misc-Wire1
网络安全·ctf·misc·1024程序员节
开开心心就好4 天前
版本转换工具,支持Win双系统零售批量版
linux·运维·服务器·pdf·散列表·零售·1024程序员节
开开心心就好5 天前
免费卸载工具,可清理残留批量管理启动项
linux·运维·服务器·windows·随机森林·pdf·1024程序员节
unable code5 天前
攻防世界-Misc-4-1
网络安全·ctf·misc·1024程序员节
yBmZlQzJ7 天前
免费内网穿透-端口转发配置介绍
运维·经验分享·docker·容器·1024程序员节
金融小师妹8 天前
AI算法视角下非农夜冲击波来袭,黄金高位区间震荡态势的深度神经网络解析
大数据·深度学习·1024程序员节