Android APIv29 FileNotFoundException EACCES (Quyền bị từ chối)


8

Tôi không thể truy cập bộ nhớ khi xây dựng cho targetSdkVersion v29.

Đây là cấu hình lớp của tôi:

    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    ...
        minSdkVersion 15
        targetSdkVersion 29

LƯU Ý rằng sự WRITE_EXTERNAL_STORAGEcho phép được cấp và thiết lập tương tự hoạt động tốt khi xây dựng targetSdkVersion 28.

Đây là cách thực hiện của tôi:

        val outputFolder = File(baseFolder + File.separator + "Output Folder")
        if (!outputFolder.exists()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Files.createDirectory(outputFolder.toPath()) //This allways returns false with targetSdkVersion 29
            } else {
                if (!outputFolder.mkdirs()) {
                    Log.e("SaveRaw", "Unable to create folder for audio recording")
                }
            }
        }

        outputFile = File("$baseFolder/Output Folder/$filename")
        try {
            fileOutputStream = FileOutputStream(outputFile)
        } catch (e: FileNotFoundException) {
            e.printStackTrace() // allways throwing exception here, even if Output Folder exists 
        }

và đây là ngoại lệ:

W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Chirp Auto Tester/2019_10_17 10:44:43.raw: open failed: EACCES (Permission denied)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:496)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:186)

Hy vọng ai có câu trả lời, tôi còn thiếu gì ở đây?

Cập nhật:

Đây là nơi baseFolderđến từ. Lưu ý rằng đó getExternalStorageDirectorylà một phương pháp không dùng nữa.

        val baseFolder: String = if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            Environment.getExternalStorageDirectory().absolutePath
        } else {
            context.filesDir.absolutePath
        }

Cảm ơn


Hãy thử sử dụng thư viện này để giới thiệu github.com/googlesamples/easypermissions
Ruben Meires

Như tôi đã đề cập, các quyền cần thiết để ghi bộ nhớ ngoài được cấp và thiết lập tương tự hoạt động khi xây dựng với targetSdkVersion 28. Đây không phải là một vấn đề cho phép!
Dinu

Tiền tố của nó liền kề, theo lỗi, nó không thể nhận được premsiion để truy cập tệp / lưu trữ / mô phỏng / 0 / Chirp Auto Tester / 2019_10_17 10: 44: 43.raw: mở thất bại: EACCES (Quyền bị từ chối) , Nếu sử dụng Android 10 lưu trữ trong phạm vi
Ruben Meires

Làm thế nào để bạn giải thích rằng nó hoạt động khi xây dựng targetSdkVersion 28sau đó? Theo lỗi, có, đó là vấn đề liên quan đến quyền nhưng không phải vì quyền không được cấp.
Dinu

2
Bạn không có quyền truy cập hệ thống tập tin vào các vị trí tùy ý trên bộ nhớ ngoài và bộ nhớ di động. Các lưu trữ di động hạn chế đã được bổ sung trong Android 4.4. Các giới hạn lưu trữ bên ngoài đã được bổ sung trong Android 10
CommonsWare

Câu trả lời:


14

Bắt đầu với Android 11 , quyền lưu trữ sẽ bị thu hồi và các nhà phát triển sẽ cần xem xét các cách khác để truy cập vào bộ lưu trữ mà họ cần thông qua SAF hoặc Media Store . Hiện tại, bạn có thể tiếp tục sử dụng những gì bạn đang sử dụng bằng cách thêm các mục sau vào bảng kê khai của bạn trong các thẻ ứng dụng:

android:requestLegacyExternalStorage="true"

Bạn có thể muốn xem xét thay đổi minSDK của mình thành 19 và sử dụng getExternalFilesDir()để có được một đường dẫn không yêu cầu bất kỳ quyền nào.


Vẫn không hoạt động nhưng chắc chắn đang nhìn đúng hướng, bây giờ tôi đang nhận được ENOENT (No such file or directory), tuy nhiên, thư mục chắc chắn tồn tại. getExternalFilesDir()âm thanh về quyết định đúng để khắc phục vấn đề.
Dinu

1
Chỉ cần một bản cập nhật nhanh chóng, cuối cùng tôi đã sử dụng getExternalFilesDir().
Dinu

2

Khi ứng dụng của bạn nhắm mục tiêu Build.VERSION_CODES.Q, đường dẫn được trả về từ phương thức này không còn có thể truy cập trực tiếp vào các ứng dụng.

    val path = getExternalFilesDir(Environment.DIRECTORY_PICTURES.toString() + 
    File.separator + "Output Folder")
    val file = File(getExternalFilesDir(null), "filename.jpg")

Để biết thêm chi tiết, hãy truy cập Tài liệu


-1

bạn cần có quyền yêu cầu Manifest-01.WRITE_EXTERNAL_STORAGE một lần nữa.

trước 9.0, bạn chỉ yêu cầu Manifest-01.READ_EXTERNAL_STORAGE và bạn cũng sẽ nhận được Manifest-01.WRITE_EXTERNAL_STORAGE, nhưng bắt đầu với 9.0, bạn chỉ có thể nhận được một quyền mà bạn đã yêu cầu.

Tha thứ cho tiếng anh kém của tôi.


Đây không phải là vấn đề về quyền yêu cầu, tôi đã đề cập đến vấn đề này một vài lần, cả hai quyền, VIẾT và ĐỌC EXTERNAL_STORAGE đều được cấp. Xem câu trả lời của Nikos để biết chi tiết về lý do tại sao bạn vẫn không thể truy cập bộ nhớ ngoài ngay cả khi quyền được cấp. Và đừng lo lắng về tiếng Anh của bạn, nó thật tuyệt.
Dinu

/ ** * 申请 相册 权限 相册 * / công khai {Manifest-01.READ_EXTERNAL_STORAGE, Manifest-01 } other {openPic (mContext, CODE_GALLERY_REQUEST); }}
Gerry_Liang
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.