实战|Android后台启动Activity实践之路

本文探讨了在Android后台启动Activity的实践,包括原生Android ROM和定制化ROM的不同策略。在原生系统中,从Android 10开始受限,但可通过全屏Intent权限实现。而在定制化ROM如MIUI上,需处理额外的后台权限检测和Hook方法。总结了不同Android版本和设备的解决方案,以及面对定制化ROM的挑战。
摘要由CSDN通过智能技术生成

概述

前几天产品提了一个需求,想在后台的时候启动我们 APP 的一个 Activity,随着 Android 版本的更新,以及各家 ROM 厂商的无限改造,这种影响用户体验的功能许多都受到了限制,没办法,虽然是比较流氓的功能,但拿人钱财替人消灾,于是开启了哼哧哼哧的调研之路。

原生Android ROM

首先从 Android 的原生 ROM 开始,根据官方的介绍,后台启动 Activity 的限制是从 Android 10(API 29) 才开始的,在此之前原生 ROM 是没有这个限制的,于是我分别启动了一个 Android 9(API 28) 和 10(API 29) 版本的模拟器,发现在 API 28 上可以直接从后台启动 Activity,而在 API 29 上则受到了限制无法直接启动。参照官方 从后台启动 Activity 的限制 的说明,给出了一些不受限制的例外情况,此外官方的推荐是对于后台启动的需求,先向用户展示一个 Notification 而不是直接启动 Activity,然后在用户点击 Notification 后才处理对应的逻辑。还可以在设置 Notification 时通过 setFullScreenIntent 添加一个全屏 Intent 对象,该方法经过测试,可以在 Android 10 的模拟器上从后台启动一个 Activity 界面(需要 android.permission.USE_FULL_SCREEN_INTENT 权限)。代码如下:

object NotificationUtils {
    private const val ID = "channel_1"
    private const val NAME = "notification"

    private var manager: NotificationManager? = null

    private fun getNotificationManagerManager(context: Context): NotificationManager? {
        if (manager == null) {
            manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
        }
        return manager
    }

    fun sendNotificationFullScreen(context: Context, title: String?, content: String?) {
        if (Build.VERSION.SDK_INT >= 26) {
            clearAllNotification(context)
            val channel = NotificationChannel(ID, NAME, NotificationManager.IMPORTANCE_HIGH)
            channel.setSound(null, null)
            getNotificationManagerManager(context)?.createNotificationChannel(channel)
            val notification = getChannelNotificationQ(context, title, content)
            getNotificationManagerManager(context)?.notify(1, notification)
        }
    }

    private fun clearAllNotification(context: Context) {
        getNotificationManagerManager(context)?.cancelAll()
    }

    private fun getChannelNotificationQ(context: Context, title: String?, content: String?): Notification {
        val fullScreenPendingIntent = PendingIntent.getActivity(
            context,
            0,
            DemoActivity.genIntent(context),
            PendingIntent.FLAG_UPDATE_CURRENT
        )
        val notificationBuilder = NotificationCompat.Builder(context, ID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle(title)
            .setContentText(content)
            .setSound(null)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setCategory(Notification.CATEGORY_CALL)
            .setOngoing(true)
            .s
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值