Không thể tạo thư mục trong Android 10


8

Tôi không thể tạo thư mục trong Android 10. Nó hoạt động trên các thiết bị cho đến Android Oreo.

Tôi đã thử hai cách để tạo thư mục.

Sử dụng File.mkdir() :

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                               success =  f.mkdir();
                        }

Ở đây, biến success luôn là sai , có nghĩa là thư mục không được tạo.

Sử dụng Files.createDirectory() :

   File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pastebin");
                    if (!f.isFile()) {
                        if (!(f.isDirectory())) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                try {
                                    Files.createDirectory(Paths.get(f.getAbsolutePath()));
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    Toast.makeText(getApplicationContext(), R.string.unable_to_download, Toast.LENGTH_LONG).show();
                                }
                            } else {
                                f.mkdir();
                            }
                        }

nguyên nhân gây ra ngoại lệ này:

pzy64.pastebinpro W/System.err: java.nio.file.AccessDeniedException: /storage/emulated/0/Pastebin
pzy64.pastebinpro W/System.err:     at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:391)
pzy64.pastebinpro W/System.err:     at java.nio.file.Files.createDirectory(Files.java:674)

Tôi đã thực hiện các quyền thời gian chạy và

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

tất cả đã được thiết lập

Câu trả lời:


24

Như được tiết lộ lần đầu tiên vào tháng 3 năm 2019, theo mặc định, bạn không còn có quyền truy cập vào các vị trí tùy ý trên bộ nhớ ngoài hoặc bộ nhớ di động trên Android 10+. Điều này bao gồm Environment.getExternalStorageDirectory()và các phương pháp khác trên Environment(ví dụ , getExternalStoragePublicDirectory().

Đối với Android 10, bạn có thể thêm android:requestLegacyExternalStorage="true"vào <application>phần tử của mình trong tệp kê khai. Điều này đưa bạn vào mô hình lưu trữ cũ và mã lưu trữ ngoài hiện tại của bạn sẽ hoạt động. Tuy nhiên, điều đó sẽ không hoạt động trên Android R và cao hơn, vì vậy đây chỉ là một sửa chữa ngắn hạn.

Lựa chọn của bạn là:

  • Sử dụng các phương thức trên Context, chẳng hạn như getExternalFilesDir(), để truy cập vào các thư mục trên bộ nhớ ngoài mà ứng dụng của bạn có thể viết. Bạn không cần bất kỳ quyền để sử dụng các thư mục đó trên Android 4.4 trở lên. Tuy nhiên, dữ liệu bạn lưu trữ ở đó sẽ bị xóa khi gỡ cài đặt ứng dụng của bạn.

  • Sử dụng Khung truy cập lưu trữ, chẳng hạn như ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT.

  • Nếu nội dung của bạn là phương tiện, bạn có thể sử dụng MediaStoređể đặt phương tiện vào các vị trí phương tiện tiêu chuẩn.


1
bạn đang nói rằng không có cách nào để tạo thư mục của riêng tôi trên Android Q?
Xihuny

1
@Xihuny: Bạn có thể tạo các thư mục con getExternalFilesDir()và các vị trí tương tự được cung cấp bởi Context. Bạn không thể tạo thư mục con từ gốc của bộ nhớ ngoài hoặc bộ lưu trữ di động trực tiếp, sử dụng API hệ thống tệp.
CommonsWare

1
Tôi không muốn làm điều đó vì các tệp sẽ bị xóa khi người dùng gỡ cài đặt ứng dụng.
Xihuny

1
@Xihuny: Sau đó, sử dụng Khung truy cập lưu trữ và cho phép người dùng chọn vị trí trên thiết bị của người dùng mà bạn đặt nội dung của người dùng.
CommonsWare

1
Tôi đã thử, nhưng tôi không thể tạo thư mục của riêng mình. Có cách nào để tạo thư mục có tên tùy chỉnh của riêng tôi bằng SAF không?
Xihuny

3

Đối với Android 10, bạn có thể thêm

android:requestLegacyExternalStorage="true"

để phần tử của bạn trong bảng kê khai. Điều này đưa bạn vào mô hình lưu trữ cũ và mã lưu trữ ngoài hiện tại của bạn sẽ hoạt động. Khắc phục sự cố này sẽ không hoạt động trên Android R và cao hơn, vì vậy đây chỉ là một sửa chữa ngắn hạn.


1

Vì Q beta 4 nên có thể từ chối tính năng đó bằng cách:

nhắm mục tiêu api 28 (hoặc thấp hơn) bằng cách sử dụng thuộc tính tệp kê khai requestLegacyExternalStorage:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting Android Q. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

-1

Điều này hoạt động với tôi và tôi nghĩ rằng nó hoạt động trên Android 10>

            ContentResolver resolver = getContentResolver();
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Folder Example");
            String path = String.valueOf(resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues));
            File folder = new File(path);
            boolean isCreada = folder.exists();
            if(!isCreada) {
                folder.mkdirs();
            }

Bạn đang truy vấn a File, vì vậy bạn sẽ phải thêm android:requestLegacyExternalStorage="true"khi nhắm mục tiêu Android 10>. Trong trường hợp đó, bạn cũng có thể tiếp tục sử dụng getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).
HB.

getExternalStoragePublicDirectory không được dùng ở cấp API 29
JP711

Đúng và? Như tài liệu nêu When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible, vì vậy nếu bạn có android:requestLegacyExternalStorage="true"trong bảng kê khai của mình, bạn vẫn có thể sử dụng nó.
HB.

"Đúng và?" và, như tài liệu nói rằng Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENTtôi chưa quen với điều này nhưng sau đó câu hỏi của tôi sẽ là, đề xuất của tôi sai hay tại sao bỏ phiếu tiêu cực? Tôi không biết rõ làm thế nào nó hoạt động, sau đó tốt hơn là tiếp tục getExternalStoragePublicDirectory?
JP711

1
Bạn không phải tạo một thư mục. Khi bạn ghi vào Urithư mục sẽ được tạo tự động.
HB.
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.