【发布时间】:2022-01-01 08:54:28
【问题描述】:
我正在开发一个 Android 应用,但在权限处理方面遇到了问题(API lvl 30,Android 版本 11)
我尝试按照此处的步骤操作:https://developer.android.com/training/permissions/requesting.html
当使用“checkSelfPermission()”函数时,看起来我有必要的权限,但是当我尝试写入文件时,我得到了显示在这篇文章底部的日志中的错误。
这是我的代码:
class FilesActivity : AppCompatActivity() {
val requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted: Boolean ->
if (isGranted) {
Log.d("access granted", isGranted.toString())
} else {
Log.d("access granted", isGranted.toString())
}
}
private lateinit var binding: ActivityFilesBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestPermissions()
检查权限的方法如下:
private fun requestPermissions() {
when {
ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED -> {
Log.d("Permission","Already granted")
}
else -> {
requestPermissionLauncher.launch(
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
}
}
我得到权限提示,在授予权限后我尝试下载文件。下载文件的代码位于回收站视图的适配器类中。
try{
if(ContextCompat.checkSelfPermission(
mContext,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED) {
val myFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),file.getFilename()!!)
val fileRef = Firebase.storage.getReferenceFromUrl(file.getUrl()!!)
fileRef.getFile(myFile).addOnSuccessListener {
// Local temp file has been created
Toast.makeText(mContext,"File downloaded to Downloads Dir.",Toast.LENGTH_LONG).show()
}.addOnFailureListener {
Toast.makeText(mContext,it.toString(),Toast.LENGTH_LONG).show()
}
}
} catch(e :Error){
Toast.makeText(mContext,e.toString(),Toast.LENGTH_LONG).show()
}
我不确定,我做错了什么。 也许这里有人可以帮助我。 提前致谢
编辑:我的 AndroidManifest.xml 看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:icon="@drawable/round_logo_app"
android:label="@string/app_name"
android:roundIcon="@drawable/app_logo_round"
android:supportsRtl="true"
android:requestLegacyExternalStorage="true"
android:theme="@style/Theme.app">
<activity android:name=".UserRatingsActivity"></activity>
<activity
android:name=".ui.myFiles.FilesActivity"
android:label="@string/title_activity_files"
android:theme="@style/Theme.StuddyV0_1.NoActionBar" />
<activity android:name=".Register" />
<activity android:name=".EnterCourses" />
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" />
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".PushNotifications.FirebaseService"
android:permission="com.google.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".NotificationsPckg.MyFirebaseMessaging"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
在我手机的设置中,我可以看到该应用有权访问存储。
编辑:它可以在模拟器中运行,但不能在真实手机上运行。 (银河s20)
日志如下所示:
E/FileDownloadTask: Exception occurred during file write. Aborting.
java.io.FileNotFoundException: /storage/emulated/0/Download/SKE_Labor.pdf: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:492)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at com.google.firebase.storage.FileDownloadTask.processResponse(FileDownloadTask.java:147)
at com.google.firebase.storage.FileDownloadTask.run(FileDownloadTask.java:228)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7$StorageTask(StorageTask.java:1072)
at com.google.firebase.storage.-$$Lambda$StorageTask$q9YBoR_A8LB-JxTCx8JRQvabaZs.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8494)
at libcore.io.IoBridge.open(IoBridge.java:478)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at com.google.firebase.storage.FileDownloadTask.processResponse(FileDownloadTask.java:147)
at com.google.firebase.storage.FileDownloadTask.run(FileDownloadTask.java:228)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7$StorageTask(StorageTask.java:1072)
at com.google.firebase.storage.-$$Lambda$StorageTask$q9YBoR_A8LB-JxTCx8JRQvabaZs.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
E/StorageException: StorageException has occurred.
An unknown error occurred, please check the HTTP result code and inner exception for server response.
Code: -13000 HttpResult: 200
/storage/emulated/0/Download/SKE_Labor.pdf: open failed: EACCES (Permission denied)
java.io.FileNotFoundException: /storage/emulated/0/Download/SKE_Labor.pdf: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:492)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at com.google.firebase.storage.FileDownloadTask.processResponse(FileDownloadTask.java:147)
at com.google.firebase.storage.FileDownloadTask.run(FileDownloadTask.java:228)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7$StorageTask(StorageTask.java:1072)
at com.google.firebase.storage.-$$Lambda$StorageTask$q9YBoR_A8LB-JxTCx8JRQvabaZs.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8494)
at libcore.io.IoBridge.open(IoBridge.java:478)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at com.google.firebase.storage.FileDownloadTask.processResponse(FileDownloadTask.java:147)
at com.google.firebase.storage.FileDownloadTask.run(FileDownloadTask.java:228)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7$StorageTask(StorageTask.java:1072)
at com.google.firebase.storage.-$$Lambda$StorageTask$q9YBoR_A8LB-JxTCx8JRQvabaZs.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
E/StorageException: StorageException has occurred.
An unknown error occurred, please check the HTTP result code and inner exception for server response.
Code: -13000 HttpResult: 200
/storage/emulated/0/Download/SKE_Labor.pdf: open failed: EACCES (Permission denied)
java.io.FileNotFoundException: /storage/emulated/0/Download/SKE_Labor.pdf: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:492)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at com.google.firebase.storage.FileDownloadTask.processResponse(FileDownloadTask.java:147)
at com.google.firebase.storage.FileDownloadTask.run(FileDownloadTask.java:228)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7$StorageTask(StorageTask.java:1072)
at com.google.firebase.storage.-$$Lambda$StorageTask$q9YBoR_A8LB-JxTCx8JRQvabaZs.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:8494)
at libcore.io.IoBridge.open(IoBridge.java:478)
at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
at com.google.firebase.storage.FileDownloadTask.processResponse(FileDownloadTask.java:147)
at com.google.firebase.storage.FileDownloadTask.run(FileDownloadTask.java:228)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7$StorageTask(StorageTask.java:1072)
at com.google.firebase.storage.-$$Lambda$StorageTask$q9YBoR_A8LB-JxTCx8JRQvabaZs.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
编辑:回到这个问题后,我注意到,它只发生在 .pdf 文件中。其他所有内容均已正确下载并保存。
【问题讨论】:
-
如果您进入应用程序的设置,您可以查看您是否确实具有写入权限。 `
-
Android kotlin: Getting EACCES (Permission denied) ..不清楚该文件是哪个文件。用于在您的设备上创建文件或用于 Firebase 中的文件。 -
这是我在下载之前创建的文件,用于将下载写入文件。 “验证我的文件”
-
val myFile = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),file.getFilename()!!你创建了一个 File 实例。那不会创建文件。所以不会导致访问失败。请调查。 -
我以为会是这一行:“fileRef.getFile(myFile).addOnSuccessListener”导致错误。顺便说一句:它在模拟器中工作,但在我的真实手机上却没有
标签: android firebase kotlin storage