2016-10-29 41 views
5

Làm cách nào để phân phối tệp từ bộ nhớ ngoài SECONDARY bằng cách sử dụng FileProvider?Trình lưu trữ tệp và bộ nhớ ngoài thứ cấp

Việc thực hiện hiện hành của FileProvider xử lý chỉ mục đầu tiên được trả về bởi ContextCompat.getExternalFilesDirs

...  
} else if (TAG_EXTERNAL_FILES.equals(tag)) { 
    File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null); 
    if (externalFilesDirs.length > 0) { 
     target = externalFilesDirs[0]; 
    } 
} 
... 

Dường như, mà không có cách nào để xác định một mục <path> cho FileProvider, phù hợp với đường dẫn lưu trữ bên ngoài thứ yếu. ..

+0

Bạn có ý gì với bộ nhớ ngoài thứ cấp? – greenapps

+0

Các thư mục được trả về bởi 'ContextCompat.getExternalFilesDirs' với chỉ mục mảng> 0. Trên hầu hết các thiết bị, nó có thể là thẻ sd có thể tháo rời. – artkoenig

+0

AFAIK, 'FileProvider' không hỗ trợ điều này. Bạn có thể sắp xếp thứ gì đó với [my 'StreamProvider'] (https://github.com/commonsguy/cwac-provider), mặc dù không có sự hỗ trợ cho điều này" ngoài hộp ". Tôi đã thêm rằng vào danh sách việc cần làm của tôi cho 'StreamProvider', khi bạn thực hiện một điểm tốt. Đặc biệt là vì không có quyền ứng dụng nào liên quan đến các vị trí này, nên chúng phải được phân phát, ít nhất là khi chúng tồn tại. Điều gì có thể phức tạp là xử lý chính xác trường hợp lưu trữ di động không có sẵn, nhưng bạn đã yêu cầu nó được phục vụ. – CommonsWare

Trả lời

4

Và câu trả lời là ... FileProvider không hỗ trợ điều đó. Với Android 7, vấn đề này thậm chí còn là một vấn đề hơn, do việc ngừng sử dụng sơ đồ URI file://.

Tôi đã phát hành bug report.

1

Như workaround bạn có thể sử dụng pathes tuyệt đối:

<!-- secondary external storage with path /storage/extSdCard --> 
<root-path path="/storage/extSdCard/Android/data/YOUR_PACKAGE/files/" name="extSdCard" /> 

<!-- secondary external storage with path /storage/sdcard1 --> 
<root-path path="/storage/sdcard1/Android/data/YOUR_PACKAGE/files/" name="sdcard1" /> 
+1

Với các thiết bị mới hơn, đường dẫn bên ngoài phụ thuộc vào thẻ SD được chèn vào vì nó sử dụng id tham chiếu, vì vậy không thể sử dụng đường dẫn tuyệt đối. – 3c71

1

Vì vậy, tôi đã kết thúc cách làm như sau:

Cố gắng tạo ra để Uri qua FileProvider, Nếu nó không thành công do:

java.lang.IllegalArgumentException: Failed to find configured root that contains 

Tôi chỉ đang tạo một Uri thông thường.

Dưới đây là mã của tôi:

try { 
     uri = FileProvider.getUriForFile(context, 
       MY_AUTHORITY_STRING, 
       imageFile); 
    } catch (Exception e) { 
     CLog.d(TAG, e); 
     uri = Uri.fromFile(imageFile); 
    } 

Tôi không biết tại sao, nhưng nó làm việc, FileProvider không thể truy cập các tập tin (Vì nó là trong bộ nhớ ngoài thứ cấp) và sau đó là uri được tạo thành công trong điều khoản bắt.

Google lạ ... rất lạ.

+1

lỗi trong 7,0+ –

2

Để xử lý các file nằm trên sdcards bên ngoài, tôi đã thay đổi provider_paths.xml tôi để

<paths> 
    <external-path path="." name="external_files" /> 
    <root-path path="." name="sdcard1" /> 

</paths> 
2

FileProvider không hỗ trợ lưu trữ thứ cấp vì vào mã bên dưới:

Mã từ hỗ trợ: hỗ trợ-core-utils : 26.1.0 FileProvider

  } else if (TAG_EXTERNAL_FILES.equals(tag)) { 
       File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null); 
       if (externalFilesDirs.length > 0) { 
        target = externalFilesDirs[0];// Code here, That's why!!! 
       } 
      } else if (TAG_EXTERNAL_CACHE.equals(tag)) { 

Tuy nhiên, có một TAG đặc biệt trong FileProvider: root-path không được đề cập chính thức.

  if (TAG_ROOT_PATH.equals(tag)) { 
       target = DEVICE_ROOT;// DEVICE_ROOT = new File("/"); 
      } else if (TAG_FILES_PATH.equals(tag)) { 

Vì vậy, đường dẫn gốc khớp với tất cả đường dẫn.

Chỉ cần nhập mã này vào FileProvider xml của bạn, sau đó FileProvider có thể xử lý Tệp trong bộ nhớ thứ cấp.

<root-path name="root" path="." /> 

Xin lưu ý, nó có thể làm rò rỉ cấu trúc thư mục của bạn.

Các vấn đề liên quan