从广播接收器启动活动意图会显示错误的活动

十字架

我正在制作一个可用于将中断和输入检测合并到任何应用程序中的库

有一个设置为房屋警报的arduino,可在触发时将SMS发送到特定电话

在我的sdk中,我注册了一个短信接收器,接收到带有特定文本的短信后,该短信接收器应显示全屏活动(也在锁屏顶部),这将提醒用户

我创建了一个应用程序来测试此行为

该应用程序的软件包是:com.example.demo

库的软件包是:com.example.sdk

短信接收器看起来像这样:

class SMSReceiver : BroadcastReceiver() {
    companion object {
        const val TAG = "SMSReceiver"
    }

    private val logger by lazy { Injections.logger }

    override fun onReceive(context: Context?, intent: Intent?) {
        logger.log(TAG) { "Got sms" }
        val ctx = context ?: return
        val bundle = intent?.extras ?: return
        val format = bundle.getString("format") ?: return
        val pdus = (bundle["pdus"] as? Array<*>) ?: return
        for (idx in pdus.indices) {
            val pdu = pdus[idx] as? ByteArray ?: continue
            val msg = SmsMessage.createFromPdu(pdu, format)
            if (msg.messageBody.startsWith("theft event", true)) {
                logger.log(TAG) { "Got theft event" }
                abortBroadcast()
                showTheftActivity(ctx, msg.messageBody)
                break
            }
        }
    }

    private fun showTheftActivity(context: Context, messageBody: String) {
        val intent = Intent(context, TheftActivity::class.java)
        intent.addFlags(Intent.FLAG_FROM_BACKGROUND)
            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
//            .addCategory(Intent.CATEGORY_LAUNCHER)

        val location = messageBody.split(" ").getOrNull(2)
        if (location != null) {
            val coords = location.split(",")
            if (coords.size == 2) {
                val x = coords[0].toBigDecimalOrNull()
                val y = coords[1].toBigDecimalOrNull()
                if (x != null && y != null) {
                    intent.putExtra(TheftActivity.X, x.toString())
                    intent.putExtra(TheftActivity.Y, y.toString())
                }
            }
        }
        context.startActivity(intent)
    }
}

应该显示在所有内容之上的活动是这样的:

class TheftActivity : Activity() {
    companion object {
        const val X = "locationX"
        const val Y = "locationY"
    }

    private val x: String? by lazy { intent.getStringExtra(X) }
    private val y: String? by lazy { intent.getStringExtra(Y) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_theft)
        val location = findViewById<Button>(R.id.locate)
        if (x != null && y != null) {
            location.setOnClickListener { Toast.makeText(applicationContext, "Going to $x , $y", Toast.LENGTH_SHORT).show() }
            location.isEnabled = true
            finish()
        } else {
            location.isEnabled = false
        }
        findViewById<Button>(R.id.cancel).setOnClickListener {
            finish()
        }
        turnScreenOnAndKeyguardOff()
    }

    private fun turnScreenOnAndKeyguardOff() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
        } else {
            window.addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
            )
        }

        with(getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                requestDismissKeyguard(this@TheftActivity, null)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        turnScreenOffAndKeyguardOn()
    }

    private fun turnScreenOffAndKeyguardOn() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(false)
            setTurnScreenOn(false)
        } else {
            window.clearFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
            )
        }
    }
}

并且sdk的android清单包含以下内容:

   <application>
        <activity
            android:name=".ui.TheftActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:excludeFromRecents="true"
            android:label="@string/title_activity_theft"
            android:showOnLockScreen="true"
            android:theme="@style/Theme.Sdk.Fullscreen" />

        <receiver
            android:name=".receivers.SMSReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
    </application>

在模拟器上测试时,我发送短信以触发盗窃事件

如果测试活动(com.example.demo包中的活动)未关闭,则将其置于最前面,但如果关闭,则什么也不会发生(尽管我确实看到了接收方的日志消息)

如何使我的短信接收器打开TheftActivity而不是从主程序包打开主活动?

编辑:如果有帮助,盗窃活动似乎开始,然后立即被销毁

埃伦·图菲切

由于Android Q中实施的限制,系统似乎无法将活动置于前台

使用Android Q,如果您的应用未包含以下链接中列出的那些例外,则无法从后台自动启动活动。

https://developer.android.com/guide/components/activities/background-starts

对于可能的解决方案:

https://stackoverflow.com/a/59421118/11982611

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

通知广播接收器的片段或活动

来自分类Dev

尝试从广播接收器开始活动

来自分类Dev

活动中的意图过滤器和广播接收器之间有什么区别?

来自分类Dev

启动应用程序而没有任何活动,我的广播接收器不起作用

来自分类Dev

通过从广播接收器的onReceive的主要活动启动Dismiss ProgressDialog

来自分类Dev

在显示活动之前,如何在android中使用来自广播接收器的数据

来自分类Dev

在显示活动之前,如何在android中使用来自广播接收器的数据

来自分类Dev

错误:包含广播接收器的应用程序的“未找到默认活动”

来自分类Dev

永远不要从广播接收器开始活动?

来自分类Dev

从广播接收器更新活动UI组件?

来自分类Dev

从广播接收器向活动发送警报

来自分类Dev

自定义广播接收器,用于活动测量

来自分类Dev

在非活动类别中注册广播接收器

来自分类Dev

与广播接收器进行关闭活动时强制关闭

来自分类Dev

Android:将值从活动传递到广播接收器

来自分类Dev

广播接收器如何在活动之间工作?

来自分类Dev

与活动生命周期无关的广播接收器

来自分类Dev

从另一个应用程序活动广播时广播接收器不显示结果

来自分类Dev

广播接收器未收到意图

来自分类Dev

在没有活动的情况下启动应用程序,我的广播接收器无法正常工作

来自分类Dev

片段中的广播接收器无法从服务接收意图

来自分类Dev

广播接收器未在android中接收意图数据。

来自分类Dev

从广播接收器启动服务

来自分类Dev

从广播接收器开始活动时,无法访问SharedPreferences

来自分类Dev

通过从广播接收器的onReceive的主要活动开始关闭ProgressDialog

来自分类Dev

即使不在视线中也能保持片段广播接收器处于活动状态

来自分类Dev

从广播接收器开始活动时,无法访问SharedPreferences

来自分类Dev

广播接收器,服务和活动共享应用程序对象吗?

来自分类Dev

广播接收器onReceive没收到意图包

Related 相关文章

  1. 1

    通知广播接收器的片段或活动

  2. 2

    尝试从广播接收器开始活动

  3. 3

    活动中的意图过滤器和广播接收器之间有什么区别?

  4. 4

    启动应用程序而没有任何活动,我的广播接收器不起作用

  5. 5

    通过从广播接收器的onReceive的主要活动启动Dismiss ProgressDialog

  6. 6

    在显示活动之前,如何在android中使用来自广播接收器的数据

  7. 7

    在显示活动之前,如何在android中使用来自广播接收器的数据

  8. 8

    错误:包含广播接收器的应用程序的“未找到默认活动”

  9. 9

    永远不要从广播接收器开始活动?

  10. 10

    从广播接收器更新活动UI组件?

  11. 11

    从广播接收器向活动发送警报

  12. 12

    自定义广播接收器,用于活动测量

  13. 13

    在非活动类别中注册广播接收器

  14. 14

    与广播接收器进行关闭活动时强制关闭

  15. 15

    Android:将值从活动传递到广播接收器

  16. 16

    广播接收器如何在活动之间工作?

  17. 17

    与活动生命周期无关的广播接收器

  18. 18

    从另一个应用程序活动广播时广播接收器不显示结果

  19. 19

    广播接收器未收到意图

  20. 20

    在没有活动的情况下启动应用程序,我的广播接收器无法正常工作

  21. 21

    片段中的广播接收器无法从服务接收意图

  22. 22

    广播接收器未在android中接收意图数据。

  23. 23

    从广播接收器启动服务

  24. 24

    从广播接收器开始活动时,无法访问SharedPreferences

  25. 25

    通过从广播接收器的onReceive的主要活动开始关闭ProgressDialog

  26. 26

    即使不在视线中也能保持片段广播接收器处于活动状态

  27. 27

    从广播接收器开始活动时,无法访问SharedPreferences

  28. 28

    广播接收器,服务和活动共享应用程序对象吗?

  29. 29

    广播接收器onReceive没收到意图包

热门标签

归档