Android kotlin:即使在授予权限后也获得 EACCES(权限被拒绝)
Posted
技术标签:
【中文标题】Android kotlin:即使在授予权限后也获得 EACCES(权限被拒绝)【英文标题】:Android kotlin: Getting EACCES (Permission denied) even after giving permissions 【发布时间】: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”导致错误。顺便说一句:它在模拟器中工作,但在我的真实手机上却没有
【参考方案1】:
Extends ActivityCompat.OnRequestPermissionsResultCallback 在 FilesActivity 类中不可用。
class FilesActivity : AppCompatActivity() , ActivityCompat.OnRequestPermissionsResultCallback
您需要为 requestPermissionLauncher 定义调用 ActivityCompat.OnRequestPermissionsResultCallback 接口。
示例代码:
class MainActivity : AppCompatActivity(), ActivityCompat.OnRequestPermissionsResultCallback
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) isGranted: Boolean ->
if (isGranted)
// Permission has been granted. Start camera preview Activity.
startCamera()
else
// Permission request was denied.
requestPermissions()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
requestPermissions()
private fun requestPermissions()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED)
// Permission has been granted. Start camera preview Activity.
startCamera()
else requestPermissionLauncher.launch(Manifest.permission.CAMERA)
private fun startCamera()
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivity(intent)
https://github.com/harunkor/requestPermissionLauncherSample
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。 感谢您的回答。当我在 FilesActivity 中下载文件时,它确实有效。但是我想用 FilesAdapter 类中的一个函数来下载文件,用于上述的回收器视图。我仍然在那里检查权限,但没有运气。 这毫无意义。您在哪里询问并获得许可并不重要。它将在整个应用程序的整个生命周期内有效。只有在获得许可后才能下载和编写。你可以在第二天这样做,以确保安全 ;-)。 感谢您的所有帮助,但在我已经发布的适配器类的代码中,我在下载前检查了权限。我在那里做错了吗?我知道这没有意义。以上是关于Android kotlin:即使在授予权限后也获得 EACCES(权限被拒绝)的主要内容,如果未能解决你的问题,请参考以下文章