首页 > 解决方案 > 我正在从 URL 下载照片并请求运行时权限,但是在授予权限时它第一次崩溃

问题描述

我的应用程序在第一次允许权限时崩溃,然后它会准确下载文件。

堆栈跟踪:

java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1000, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example.unsplashapi/com.example.unsplashapi.ViewPagerActivity}: java.lang.IndexOutOfBoundsException: Index: 11, Size: 0
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5319)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5360)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2296)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:257)
        at android.app.ActivityThread.main(ActivityThread.java:8104)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)
     Caused by: java.lang.IndexOutOfBoundsException: Index: 11, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.example.unsplashapi.ViewPagerActivity.startDownloading(ViewPagerActivity.kt:96)
        at com.example.unsplashapi.ViewPagerActivity.onRequestPermissionsResult(ViewPagerActivity.kt:130)
        at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:8571)
        at android.app.Activity.dispatchActivityResult(Activity.java:8419)

我的代码

//...
downloadBtn.setOnClickListener {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_DENIED
        ) {
            ActivityCompat.requestPermissions(
                    this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                    STORAGE_PERMISSION_CODE
            )
        } else {
            startDownloading(list)
        }
    } else {
        startDownloading(list)
    }
}
//...
        
private fun startDownloading (list:ArrayList<ImageModel>){
    Toast.makeText(this, "Downloading", Toast.LENGTH_SHORT).show()
    val downloadList = list[viewPager.currentItem].urls.full
    val request = DownloadManager.Request(Uri.parse(downloadList))
            .setDestinationInExternalPublicDir(
                    Environment.DIRECTORY_PICTURES, "/unsplash/${list[viewPager.currentItem].id}.jpg"
            )
            .setTitle("Downloading").setDescription("downloading image").setAllowedOverMetered(true)
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
    val manager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
    myId = manager.enqueue(request)
    var br = object :BroadcastReceiver() {
        override fun onReceive(context:Context ?, intent:Intent ?){
            var id = intent ?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
            if (id == myId) {
                Toast.makeText(
                        this @ViewPagerActivity,
                "Downloaded Successfully",
                        Toast.LENGTH_SHORT
                ).show()
            }
        }
    }
    registerReceiver(br, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}

override fun onRequestPermissionsResult(requestCode:Int, permissions:Array<out String>, grantResults: IntArray){
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when(requestCode) {
        STORAGE_PERMISSION_CODE -> {
            if (grantResults.isNotEmpty() && grantResults[0] ==
                    PackageManager.PERMISSION_GRANTED
            ) {
                startDownloading(ArrayList < ImageModel > ())
            } else {
                Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

标签: androidkotlinruntime-errorandroid-download-managerruntime-permissions

解决方案


首先检查您的堆栈跟踪。

java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1000, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example.unsplashapi/com.example.unsplashapi.ViewPagerActivity}: java.lang.IndexOutOfBoundsException: Index: 11, Size: 0
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5319)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5360)
        ...

具体来说,java.lang.IndexOutOfBoundsException. 有关更多信息,请参阅此处的文档。

此类错误的一个示例是:

int[] array = int[1];
array[1] = 3;

在你的情况下,你可能有这样的事情:

T[] t = T[2];
t[11] = //something   <--------- the error, i.e. accessing an index that isn't that is larger than 2.

现在我们知道什么是IndexOutOfBoundsException,让我们看看你的代码,并且总是使用堆栈跟踪!

我们使用堆栈跟踪的后半部分进行分析

Caused by: java.lang.IndexOutOfBoundsException: Index: 11, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.example.unsplashapi.ViewPagerActivity.startDownloading(ViewPagerActivity.kt:96)
        at com.example.unsplashapi.ViewPagerActivity.onRequestPermissionsResult(ViewPagerActivity.kt:130)

转到函数onRequestPermissionsResult,然后让我们看看堆栈跟踪中的下一行,startDownloading我们知道:

onRequestPermissionsResult --- > startDownloading

那条线是:

startDownloading(ArrayList < ImageModel > ())

在内部startDownloading,您拥有的第二行:

val downloadList = list[viewPager.currentItem].urls.full

这看起来对IndexOutOfBoundsException我之前描述的很熟悉吗?


解决方案:

list[viewPager.currentItem].forEach((item) {
    // item.urls.full
})

或执行长度检查


推荐阅读