【问题标题】:Android/Kotlin - local BroadcastReceiver is never activated by DownloadManagerAndroid/Kotlin - 本地 BroadcastReceiver 永远不会被 DownloadManager 激活
【发布时间】:2019-07-24 15:06:53
【问题描述】:

我正在尝试检测 DownloadManager 下载何时完成。不幸的是,我尝试使用的本地 BroadcastReceiver 永远不会被调用。我见过多个类似的问题,但没有一个能解决我的问题;另外,如果 BroadcastReceiver 不是本地的,而是在清单中声明的​​,它确实会被调用,所以我认为这不是 DownloadManager 的问题。

我不能使用外部广播接收器,因为我需要在下载完成时更新 UI(更具体地说,打开另一个活动),据我所知,这不能从外部接收器完成(请如果我错了,请纠正我)。

DownloadManager 调用:

private fun download() {
    val mobileNetSSDConfigRequest: DownloadManager.Request = DownloadManager.Request(
            Uri.parse("https://s3.eu-west-3.amazonaws.com/gotcha-weights/weights/MobileNetSSD/MobileNetSSD.prototxt")
    )
    mobileNetSSDConfigRequest.setDescription("Downloading MobileNetSSD configuration")
    mobileNetSSDConfigRequest.setTitle("MobileNetSSD configuration")

    mobileNetSSDConfigRequest.setDestinationInExternalPublicDir(
            "Android/data/giorgioghisotti.unipr.it.gotcha/files/weights/", "MobileNetSSD.prototxt")

    val manager: DownloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    manager.enqueue(mobileNetSSDConfigRequest)
}

在被授予权限时调用:

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when (requestCode) {
        PERMISSION_REQUEST_CODE -> {
            if (grantResults.isEmpty()
                    || grantResults[0] != PackageManager.PERMISSION_GRANTED
                    || grantResults[1] != PackageManager.PERMISSION_GRANTED
                    || grantResults[2] != PackageManager.PERMISSION_GRANTED
                    || grantResults[3] != PackageManager.PERMISSION_GRANTED
                    || grantResults[4] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this,
                        "Sorry, this app requires camera and storage access to work!",
                        Toast.LENGTH_LONG).show()
                finish()
            } else {
                val mobileSSDConfig = File(sDir + mobileNetSSDConfigPath)
                if (!mobileSSDConfig.exists()) download()
                else {
                    val myIntent = Intent(this, MainMenu::class.java)
                    this.startActivity(myIntent)
                }
            }
        }
    }
}

BroadcastIntent 是这样声明的(Splash 是活动的名称):

private val broadcastReceiver = object: BroadcastReceiver() {

    override fun onReceive(context: Context?, intent: Intent?) {
        when (intent?.action) {
            DownloadManager.ACTION_DOWNLOAD_COMPLETE -> {
                val myIntent = Intent(this@Splash, MainMenu::class.java)
                this@Splash.startActivity(myIntent)
            }
        }
    }
}

并在activity的onCreate()方法中注册:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    LocalBroadcastManager.getInstance(this).registerReceiver(
            broadcastReceiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
    )

    ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.CAMERA,
            android.Manifest.permission.READ_EXTERNAL_STORAGE,
            android.Manifest.permission.INTERNET,
            android.Manifest.permission.ACCESS_NETWORK_STATE,
            android.Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_REQUEST_CODE)
}

我尝试在 onResume 方法中注册接收器并在 onCreate 方法中声明它,没有变化。据我所知,我正在这样做,就像我在一些公认的答案中看到的那样,我看不到问题所在。我知道 BroadcastReceiver 从未被调用过,我通过调试和各种控制台日志进行了检查。 DownloadManager 似乎按预期工作,因为文件已正确下载并且外部服务已正确调用。

我错过了什么?

【问题讨论】:

    标签: kotlin broadcastreceiver android-download-manager


    【解决方案1】:

    我遇到了类似的问题,结果证明只调用registerReceiver(broadcastReceiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE),而不获取LocalBroadcastManager 的实例解决了这个问题。

    所以问题可能是接收者在错误的上下文对象上注册。 [记住还要注意接收者的注销]

    我就是这样做的

    public void onResume() 
    {
        super.onResume();
        registerReceiver(broadcastReceiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
    }
    
    public void onPause() 
    {
        super.onPause();
        unregisterReceiver(broadcastReceiver);
    }
    

    【讨论】:

    • 我放弃并使用了一个专用的类文件,尽管它有点复杂 - 我有时间会尝试你的解决方案,但我通过调试器运行我的代码,广播接收器是从未调用过,如果只是上下文问题,(据我所知)不应该是这种情况。
    猜你喜欢
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 2014-04-08
    • 2020-10-21
    相关资源
    最近更新 更多