Sự khác biệt giữa getExternalFilesDir và getExternalStorageDirectory ()


89

Tôi hiểu rằng ExternalFiles sẽ được sử dụng trên API 8 trở lên và getExternalStorageDirectory dành cho 7 trở xuống. Tuy nhiên tôi hơi phân vân giữa việc sử dụng. Ví dụ: tôi muốn kiểm tra xem một thư mục có tồn tại và trước đó bạn sẽ sử dụng một cái gì đó như:

File ChildFolder = new File(Environment.getExternalStorageDirectory() + "/ParentFolder/Child");

Tuy nhiên, mọi ví dụ tôi thấy đều nói sử dụng getExternalFilesDir (null), File.ext. Vì tôi ở trên API 8 nên tôi muốn sử dụng phương pháp này nhưng làm cách nào để kiểm tra thư mục? Tôi sẽ kiểm tra sự tồn tại của các tệp tại một thời điểm khác nhưng bây giờ tôi chỉ muốn xem liệu các thư mục có tồn tại không ??

Câu trả lời:


132
getExternalFilesDir()

Nó trả về đường dẫn đến thư mục tệp bên trong Android / data / data / your_package / trên thẻ SD của bạn. Nó được sử dụng để lưu trữ bất kỳ tệp bắt buộc nào cho ứng dụng của bạn (ví dụ: hình ảnh được tải xuống từ web hoặc tệp bộ đệm). Sau khi ứng dụng được gỡ cài đặt, mọi dữ liệu được lưu trữ trong thư mục này cũng sẽ biến mất.

getExternalStorageDirectory()

Nó trả về đường dẫn gốc đến thẻ SD của bạn (ví dụ: mnt / sdcard / ). Nếu bạn lưu dữ liệu trên đường dẫn này và gỡ cài đặt ứng dụng, dữ liệu đó sẽ không bị mất.


4
Google Android muốn bạn sử dụng bất kỳ thứ gì họ cung cấp trong khuôn khổ. Vì vậy, nó tùy thuộc vào sự lựa chọn của bạn và yêu cầu thiết kế. Nếu bạn không muốn các tập tin để duy trì trái khi ứng dụng được gỡ bỏ sau đó bạn được khuyến khích sử dụng getExternalFilesDir () hoặc getExternalCacheDir ()
waqaslam

5
Đó là vì trong API 8, họ đã giới thiệu các tính năng quét phương tiện nâng cao cho phép quét dữ liệu từ các thư mục như nhạc, hình ảnh, nhạc chuông, v.v. Những thư mục đó chỉ được tạo tự động nếu bạn sử dụng getExternalFilesDir () . Vì tính năng này không có sẵn trong API 7 nên họ khuyên bạn nên sử dụng getExternalStorageDirectory () . Đơn giản ...
waqaslam

2
được rồi, hãy cho nó một chút thời gian, sẽ sớm có thời điểm eureka :)
waqaslam

3
Điều quan trọng là phải biết rằng getExternalStorageDirectory()không không nhất thiết phải - thậm chí có thể không thường - "đường dẫn đến thẻ SD của bạn" trả lại Thay vào đó, nó trả về "thư mục lưu trữ bên ngoài chính". Tài liệu ( developer.android.com/reference/android/os/… ) cho biết:
LarsH

2
'Lưu ý: đừng nhầm lẫn với từ "bên ngoài" ở đây. Thư mục này có thể được coi là phương tiện / bộ nhớ được chia sẻ. Đây là một hệ thống tệp có thể chứa một lượng dữ liệu tương đối lớn và được chia sẻ trên tất cả các ứng dụng (không thực thi quyền). Theo truyền thống, đây là thẻ SD , nhưng nó cũng có thể được triển khai dưới dạng bộ nhớ tích hợp trong một thiết bị khác với bộ nhớ trong được bảo vệ và có thể được gắn như một hệ thống tệp trên máy tính. '
LarsH

69

Trước hết, chúng ta cần hiểu về sự khác biệt giữa Bộ nhớ trong, Bộ nhớ ngoài (hay còn gọi là bộ nhớ ngoài chính) và Bộ nhớ ngoài thứ cấp?

Bộ nhớ trong: là bộ nhớ mà người dùng không thể truy cập, ngoại trừ thông qua các ứng dụng đã cài đặt (hoặc bằng cách root thiết bị của họ). Ví dụ: data / data / app_packageName

Bộ nhớ ngoài chính: Trong bộ nhớ dùng chung được tích hợp sẵn "người dùng có thể truy cập bằng cách cắm cáp USB và gắn nó làm ổ đĩa trên máy tính chủ". Ví dụ: Khi chúng tôi nói Nexus 5 32 GB.

Bộ nhớ ngoài phụ: Bộ nhớ có thể tháo rời. Ví dụ: Thẻ SD.

getExternalFilesDir (String type)

Nó trả về đường dẫn đến thư mục tệp bên trong Android / data / data / your_package / trên bộ nhớ ngoài chính. Đó là lưu trữ sẵn có.

Environment.getExternalStorageDirectory(type)

Nó sẽ trả về đường dẫn của thư mục lưu trữ bên ngoài phụ


Cảm ơn bạn đã giải thích các loại lưu trữ khác nhau. Tuy nhiên, có thể chỉnh sửa mục lưu trữ nội bộ để đề cập rằng cuộc gọi phương thức để nhận giá trị đó là getFilesDir (). Tôi đoán rằng phương pháp đó thực sự trả về dữ liệu / data / app_packageName / files nhưng nó vẫn là bộ nhớ trong.
raddevus

3
@VicJordan Vui lòng viết về File getExternalStoragePublicDirectory (String type)File getFilesDir ()cũng như
AnV,

2
Cảm ơn Vic. Environment.getExternalStorageDirectory () kết quả đầu ra / lưu trữ / mô phòng / 0
gimmegimme

Bạn có bất kỳ tài liệu nào cho tuyên bố rằng bộ nhớ ngoài chính luôn được tích hợp sẵn, trong khi bộ nhớ phụ luôn có thể tháo rời không? Tôi nghĩ đó là những vấn đề độc lập ... một số điện thoại không có bộ nhớ ngoài "tích hợp", trong trường hợp đó, bộ nhớ ngoài chính có thể là thẻ SD có thể tháo rời.
LarsH

@LarsH, theo hiểu biết của tôi, hiện tại không có điện thoại nào trên thị trường hoặc sắp tới sẽ không có bộ nhớ ngoài chính được tích hợp sẵn. Có những chiếc điện thoại vào thời điểm bánh gừng khi những chiếc điện thoại như vậy tồn tại nhưng không phải bây giờ. Bạn có thể vui lòng kể tên "một số" điện thoại không được tích hợp "bộ nhớ ngoài chính" không?
Vikasdeep Singh

17

! CẬP NHẬT QUAN TRỌNG ! cho bất cứ ai gặp câu hỏi này.

Vì đây là một câu hỏi hơi cũ nên chỉ muốn cung cấp thêm một số thông tin. Vì KitKat ngay cả các ứng dụng có quyền WRITE_EXTERNAL_STORAGE cũng chỉ được phép ghi vào Android / data / data / your_package / trên bộ nhớ ngoài, hay còn gọi là getExternalFilesDir()

Nếu bạn cố gắng viết thư cho getExternalStorageDirectory() + "/somefolder/anotherfolder/"bạn, bạn sẽ nhận được SecurityException trên hầu hết các thiết bị


9
Theo tài liệu, các ứng dụng có quyền WRITE_EXTERNAL_STORAGE CÓ THỂ ghi vào bộ nhớ ngoài của các gói khác, không chỉ của riêng chúng. Đó là các ứng dụng KHÔNG có quyền chỉ có thể ghi vào thư mục của riêng chúng: developer.android.com/reference/android/content/… "Bắt đầu từ KITKAT, không cần có quyền để đọc hoặc ghi vào đường dẫn trả về; nó luôn có thể truy cập vào ứng dụng gọi điện ... Để truy cập đường dẫn thuộc các gói khác, cần có WRITE_EXTERNAL_STORAGE và / hoặc READ_EXTERNAL_STORAGE. "
Hoạt động

Đây là lúc "trên hầu hết các thiết bị" bắt đầu quan trọng khi tài liệu android khái quát ý tưởng, nhưng các nhà sản xuất đôi khi có những thứ như InternalStorage (lưu trữ tích hợp cho dữ liệu ứng dụng), ExternalStorage-Primary ( cũng là lưu trữ tích hợp với phạm vi truy cập lớn hơn) và ExternalStorage-Secondary (cái này sẽ được gắn vào những thứ như thẻ SD). Bây giờ bạn có thể mất một đoán mà con đường có được ngoài StorageDirectory lợi nhuận
SGal

7
Điều đó không giải quyết thông tin không chính xác trong câu trả lời của bạn. "Vì KitKat ngay cả các ứng dụng có quyền WRITE_EXTERNAL_STORAGE cũng chỉ được phép ghi vào Android / data / data / your_package / trên bộ nhớ ngoài, hay còn gọi là getExternalFilesDir ()". Theo tài liệu, điều này là sai. Với WRITE_EXTERNAL_STORAGE, các ứng dụng có thể ghi vào tất cả bộ nhớ ngoài.
Oded

1
@Oded, bạn đã test cái này chưa? Sự hiểu biết của tôi về tài liệu và trải nghiệm của tôi với KitKat và các thiết bị sau này khác với kinh nghiệm của bạn. (Ước gì tôi có thời gian để băm ra tất cả các chi tiết ngay bây giờ. Có lẽ sau này.) Kinh nghiệm của tôi là SGal đã đúng. Sau đó, cũng có Lollipop hơi khác một chút.
LarsH

2
Câu trả lời này là sai một cách trắng trợn, theo tài liệu của Android. Xem developer.android.com/reference/android/… "Bắt đầu từ cấp API 19, quyền này không bắt buộc để đọc / ghi tệp trong các thư mục dành riêng cho ứng dụng của bạn được trả về bởi getExternalFilesDir (String) và getExternalCacheDir ()." (Lưu ý rằng API cấp 19 = KitKat.) Không hiểu sao nó lại nhận được nhiều lượt ủng hộ đến vậy.
Ajedi32 5/1017

6

!! QUAN TRỌNG !!

Environment.getExternalStorageDirectory()đang bị phản đối và bối cảnh # getExternalFilesDir (String), MediaStore, hoặc Ý định # ACTION_OPEN_DOCUMENT, nên được sử dụng để thay thế.

Phương pháp này không được chấp nhận ở cấp API 29. Để cải thiện quyền riêng tư của người dùng, quyền truy cập trực tiếp vào các thiết bị lưu trữ bên ngoài / được chia sẻ sẽ không được dùng nữa. Khi một ứng dụng 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 ứng dụng. Các ứng dụng có thể tiếp tục truy cập nội dung được lưu trữ trên bộ nhớ dùng chung / bên ngoài bằng cách chuyển sang các lựa chọn thay thế như Context # getExternalFilesDir (String), MediaStore hoặc Intent # ACTION_OPEN_DOCUMENT.

https://developer.android.com/reference/android/os/Enosystem.html#getExternalStorageDirectory ()

Cũng bắt đầu từ Android.M các nhà phát triển cần yêu cầu quyền tại thời điểm chạy.

Xem thêm chi tiết trong tài liệu tại đâycâu hỏi này

Environment.getExternalStorageDirectory () không được dùng trong java API cấp 29


nếu ai đó đang tìm kiếm liên kết tràn ngăn xếp và không phải thứ gì đó sao chép được dán từ tài liệu của google, hãy xem ở đây stackoverflow.com/questions/57116335/…
Rowan Berry
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.