You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android上传PDF至Firebase Storage遇PERMISSION DENIED权限错误

Android Firebase Storage PDF上传权限拒绝问题解决

问题背景

尝试将PDF文件上传至Firebase Storage,已参考官方文档修改代码,但在已声明权限、申请并获取运行时授权的情况下,仍抛出PERMISSION DENIED异常。

预期目标

  • 目标文件:mypdf.pdf,位于公共下载目录/storage/emulated/0/downloads
  • 将该文件上传至Firebase Storage

尝试操作

通过Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/mypdf.pdf"获取文件路径,转换为Uri后传入Firebase的putFile()方法执行上传。

onCreate()中权限检查代码

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {

    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() + "/mypdf.pdf");
    if (file.exists()) {
        uploadFileFromFirebaseTut();
        Log.d("FileLog", "onCreate: found the file");
    } else Log.d("MainActivity.this", "onCreate: could not find file");

} else
    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 81);

文件上传函数

private void uploadFileFromFirebaseTut() {

    StorageReference storageRef = storage.getReference();
    UploadTask uploadTask;

    Uri file = Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/mypdf.pdf"));
    StorageReference riversRef = storageRef.child("uploads/mypdf.pdf");
    uploadTask = riversRef.putFile(file);

    // 监听上传状态
    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Log.d("File Upload failed", "onFailure: "+exception);
            Toast.makeText(MainActivity.this, "File Upload Failed...", Toast.LENGTH_SHORT).show();
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            // taskSnapshot.getMetadata()包含文件元数据,如大小、内容类型等
            Toast.makeText(MainActivity.this, "File Uploaded..", Toast.LENGTH_SHORT).show();
        }
    });

}

错误日志

An unknown error occurred, please check the HTTP result code and inner exception for server response.
                             Code: -13000 HttpResult: 0
StorageException         E  /storage/emulated/0/Download/mypdf.pdf: open failed: EACCES (Permission denied)
                            java.io.FileNotFoundException: /storage/emulated/0/Download/mypdf.pdf: open failed: EACCES (Permission denied)
                                at libcore.io.IoBridge.open(IoBridge.java:492)
                                at java.io.FileInputStream.<init>(FileInputStream.java:160)
                                at java.io.FileInputStream.<init>(FileInputStream.java:115)
                                at android.content.ContentResolver.openInputStream(ContentResolver.java:1484)
                                at com.google.firebase.storage.UploadTask.<init>(UploadTask.java:152)
                                at com.google.firebase.storage.StorageReference.putFile(StorageReference.java:241)
                                at com.example.firebaseupload.MainActivity.uploadFileFromFirebaseTut(MainActivity.java:84)
                                at com.example.firebaseupload.MainActivity.onCreate(MainActivity.java:55)
                                at android.app.Activity.performCreate(Activity.java:8153)
                                at android.app.Activity.performCreate(Activity.java:8137)
                                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310)
                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3698)
                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3896)
                                at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
                                at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140)
                                at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100)
                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2326)
                                at android.os.Handler.dispatchMessage(Handler.java:106)
                                at android.os.Looper.loop(Looper.java:263)
                                at android.app.ActivityThread.main(ActivityThread.java:8296)
                                at java.lang.reflect.Method.invoke(Native Method)
                                at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006)
                            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:8178)
                                at libcore.io.IoBridge.open(IoBridge.java:478)
                                at java.io.FileInputStream.<init>(FileInputStream.java:160) 
                                at java.io.FileInputStream.<init>(FileInputStream.java:115) 
                                at android.content.ContentResolver.openInputStream(ContentResolver.java:1484) 
                                at com.google.firebase.storage.UploadTask.<init>(UploadTask.java:152) 
                                at com.google.firebase.storage.StorageReference.putFile(StorageReference.java:241) 
                                at com.example.firebaseupload.MainActivity.uploadFileFromFirebaseTut(MainActivity.java:84) 
                                at com.example.firebaseupload.MainActivity.onCreate(MainActivity.java:55) 
                                at android.app.Activity.performCreate(Activity.java:8153) 
                                at android.app.Activity.performCreate(Activity.java:8137) 
                                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1310) 
                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3698) 
                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3896) 
                                at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
                                at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:140) 
                                at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:100) 
                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2326) 
                                at android.os.Handler.dispatchMessage(Handler.java:106) 
                                at android.os.Looper.loop(Looper.java:263) 
                                at android.app.ActivityThread.main(ActivityThread.java:8296) 
                                at java.lang.reflect.Method.invoke(Native Method) 
                                at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612) 
                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1006) 
StorageException         E  StorageException has occurred.

Manifest声明的权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

解决方案

1. 适配Android 10+分区存储规则

从Android 10(API 29)开始,READ_EXTERNAL_STORAGE无法直接访问公共目录文件,需采用以下两种方式:

方式一:通过MediaStore获取Content Uri

改用系统MediaStore查询下载目录中的文件,获取可访问的Content Uri:

// 查询下载目录中的mypdf.pdf
String[] projection = {MediaStore.Files.FileColumns._ID};
String selection = MediaStore.Files.FileColumns.DISPLAY_NAME + " = ?";
String[] selectionArgs = {"mypdf.pdf"};
Uri contentUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI;

Cursor cursor = getContentResolver().query(contentUri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
    long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID));
    Uri fileUri = ContentUris.withAppendedId(contentUri, id);
    // 使用该Uri调用putFile上传
    uploadFileWithContentUri(fileUri);
    cursor.close();
}

方式二:申请MANAGE_EXTERNAL_STORAGE权限(Android 11+)

若需直接操作公共目录,在Android 11及以上需申请全存储访问权限:

  • 添加Manifest权限:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    android:minSdkVersion="30"/>
  • 运行时请求权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!Environment.isExternalStorageManager()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivity(intent);
    }
}

2. 检查Firebase Storage安全规则

确保Storage规则允许上传操作,测试阶段可临时设置为公开规则(上线后需修改为严格权限):

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth == null; // 仅测试用,上线后删除
    }
  }
}

3. 优化代码冗余

避免在onCreate和上传函数中重复构建File对象,可将文件Uri作为参数传递,减少代码冗余。

内容的提问来源于stack exchange,提问作者Anirudhdhsinh Jadeja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:05:22