FileProvider - IllegalArgumentException: Không thể tìm thấy root được cấu hình


233

Tôi đang cố chụp ảnh bằng máy ảnh, nhưng tôi gặp phải lỗi sau:

FATAL EXCEPTION: main
Process: com.example.marek.myapplication, PID: 6747
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example.marek.myapplication/files/Pictures/JPEG_20170228_175633_470124220.jpg
    at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:711)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
    at com.example.marek.myapplication.MainActivity.dispatchTakePictureIntent(MainActivity.java:56)
    at com.example.marek.myapplication.MainActivity.access$100(MainActivity.java:22)
    at com.example.marek.myapplication.MainActivity$1.onClick(MainActivity.java:35)

AndroidManifest.xml:

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.marek.myapplication.fileprovider"
        android:enabled="true"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

Java:

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            Toast.makeText(getApplicationContext(), "Error while saving picture.", Toast.LENGTH_LONG).show();
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,
                    "com.example.marek.myapplication.fileprovider",
                    photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="images/"/>
</paths>

Tôi đã tìm kiếm cả ngày về lỗi này và cố gắng hiểu FileProvider, nhưng tôi không biết thông báo lỗi này cố gắng nói gì với tôi. Nếu bạn muốn biết thêm thông tin / mã, hãy viết cho tôi trong phần bình luận.


2
Bạn cũng có thể dán mã phương thức createdImageFile không?
Ankit Batra

Tôi rất xin lỗi, nhưng tôi đã hủy dự án này và tôi không làm việc với nó nữa . Tôi sẽ chấp nhận câu trả lời yêu thích nhất để "đóng" câu hỏi này. Cảm ơn tất cả đã tham gia và tôi hy vọng nó sẽ giúp ích cho người khác.
Pivoman

Ran vào cùng một vấn đề. Đã tìm thấy giải pháp này để có được thiết lập FileProvider cơ bản bằng cách sử dụng dự án ví dụ github tối thiểu: stackoverflow.com/a/48103567/2162226 . Nó cung cấp các bước để sao chép các tập tin (mà không thực hiện thay đổi) vào một dự án độc lập cục bộ
Gene Bo

Vấn đề này hiện đã được khắc phục trong Delphi 10.4: quality.embarcadero.com/browse/RSP-26950
Dave Nottage

Câu trả lời:


211

Tập tin của bạn được lưu trữ dưới getExternalFilesDir(). Đó là bản đồ <external-files-path>, không <files-path>. Ngoài ra, đường dẫn tệp của bạn không chứa images/trong đó, vì vậy paththuộc tính trong XML của bạn không hợp lệ.

Thay thế res/xml/file_paths.xmlbằng:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="my_images" path="/" />
</paths>

CẬP NHẬT 2020 THÁNG 3 NĂM 13

Đường dẫn của nhà cung cấp cho một đường dẫn cụ thể như sau:

  • <files-path/> -> Context.getFilesDir()
  • <cache-path/> -> Context.getCacheDir()
  • <external-path/> -> Environment.getExternalStorageDirectory()
  • <external-files-path/> -> Context.getExternalFilesDir(String)
  • <external-cache-path/> -> Context.getExternalCacheDir()
  • <external-media-path/> -> Context.getExternalMediaDirs()

Tham chiếu: https://developer.android.com/reference/androidx/core/content/FileProvider


5
ok, tôi đã thêm đường dẫn tập tin bên ngoài, nhưng tôi vẫn gặp lỗi tương tự: / Có thể có nhiều lỗi hơn. Tôi đang sử dụng thiết bị giả lập Android, tôi có phải tạo thư mục đó hay không?
Pivoman

22
Thuộc tính "đường dẫn" phải được xác định "chúng tôi đang thiếu đường dẫn ở đây trong cấu hình.
blackjack

1
Tôi đã gặp sự cố với nhiều đường dẫn trên Android 5. Chỉ còn lại một đường dẫn, thay vì 2.
ODAXY

3
Tôi nghĩ rằng tôi đã nhận được một báo cáo sự cố (trong số 50 - 100 thiết bị) giống hệt với báo cáo này. <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>Các path="."là những gì tôi tìm thấy trong nghiên cứu của riêng tôi ở lại ở cấp cao nhất. Nếu bạn xem qua FileProvider chặt chẽ hơn, bạn sẽ thấy rằng đường dẫn đọc từ XML được hợp quy hóa. Dự đoán tốt nhất của tôi là ContextCompat#getExternalFilesDirstrả về null @line 616 (v26.0.1), vì vậy PathStrargety đã không được đăng ký. Điều này xảy ra trên thiết bị Huawei.
androidguy

10
Thay vì sử dụng <đường dẫn tệp bên ngoài, tôi đã thử <đường dẫn bên ngoài và nó đã hoạt động.
Két sắt

166

Điều này có thể giải quyết vấn đề của mọi người: Tất cả các thẻ được thêm vào, do đó bạn không cần phải lo lắng về đường dẫn thư mục. Thay thế res / xml / file_paths.xml bằng:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-path
    name="external"
    path="." />
  <external-files-path
    name="external_files"
    path="." />
  <cache-path
    name="cache"
    path="." />
  <external-cache-path
    name="external_cache"
    path="." />
<files-path
    name="files"
    path="." />
</paths>

3
Giải pháp tốt nhất. Cảm ơn.
Pawan Pillai

1
Giải pháp đơn giản ... nhưng cho sự xuất sắc này! Tôi đã sử dụng một nhà cung cấp sau đó tôi nhập khả năng người dùng để thay đổi thư mục đích ... không có gì hoạt động nữa vì tại thời điểm đó, nhà cung cấp phải năng động .... bạn đã lưu lại ngày của tôi!
Bronz

1
đã sử dụng giải pháp này và mã bắt đầu làm việc. Đã xóa mã không cần thiết bằng cách kiểm tra cái nào trong số này đang hoạt động
Kartik

1
Bro bạn đã cứu ngày của tôi. Cảm ơn rất nhiều :-)
manjunath kallannavar

1
Làm việc rất tốt cho tôi, với tư cách là một người học mới, nó khiến tôi nhận ra mình không nhận được từ các tệp bên ngoài mà là bộ đệm
Tony Merritt

82

Có vấn đề tương tự sau khi kích hoạt hương vị (dev, giai đoạn).

Trước khi hương vị tài nguyên đường dẫn của tôi trông như thế này:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
    name="my_images"
    path="Android/data/pl.myapp/files/Pictures" />
</paths>

Sau khi thêm android: cơ quan = "$ {applicationId} .fileprovider" trong ứng dụng Manifest là pl.myapp.dev hoặc pl.myapp.stage phụ thuộc vào hương vị và ứng dụng bắt đầu bị sập. Tôi xóa đường dẫn đầy đủ và thay thế nó bằng dấu chấm và mọi thứ bắt đầu hoạt động.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="." />
</paths>

7
Đã làm cho tôi. Cảm ơn! Làm thế nào bạn nghĩ ra '.' ký hiệu?
NightFury

2
@antygravity bạn có thể vui lòng cung cấp tài liệu tham khảo / tài liệu của giải pháp này không?
geekoraul

7
Có bất kỳ hậu quả tiêu cực của giải pháp này?
RediOne1

Làm việc cho tôi, Cảm ơn rất nhiều.
Hiren

Đây phải là câu trả lời được chấp nhận! Giải pháp duy nhất hiệu quả
egorikem

43

Nếu bạn đang sử dụng bộ nhớ cache nội bộ thì hãy sử dụng.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="/" />
</paths>

3
cảm ơn, tình huống của tôi: Tôi muốn cài đặt một ứng dụng đã lưu trong / data / data / pkg_name / files, vì vậy, cấu hình chính xác của tôi như sau: <files-path name = "files" path = "/" />
aolphn

25

Mất 2 tuần cố gắng tìm giải pháp nào đó ... Nếu bạn đến đây sau khi thử mọi thứ ở trên:

1 - Xác minh xem nhà cung cấp thẻ của bạn có trong ứng dụng thẻ không

<application>

    <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.companyname.Pocidadao.fileprovider" android:exported="false" android:grantUriPermissions="true">
      <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
    </provider>

</application>

2 - Nếu bạn thử nhiều cách mà không thành công, hãy thử với điều này:

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <cache-path name="cache" path="." />
  <external-path name="external" path="." />

  <root-path name="root" path="." />
  <files-path name="my_images" path="/" />
  <files-path name="my_images" path="myfile/"/>
  <files-path name="files" path="." />

  <external-path name="external_files" path="." />
  <external-path name="images" path="Pictures" />
  <external-path name="my_images" path="." />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures" />
  <external-path name="my_images" path="Android/data/com.companyname.yourproject/files/Pictures/" />

  <external-files-path name="images" path="Pictures"/>
  <external-files-path name="camera_image" path="Pictures/"/>
  <external-files-path name="external_files" path="." />
  <external-files-path name="my_images" path="my_images" />

  <external-cache-path name="external_cache" path="." />

</paths>

Kiểm tra điều này, nếu máy ảnh hoạt động, sau đó bắt đầu loại bỏ một số dòng và tiếp tục thử nghiệm ...

3 - Không quên xác minh nếu máy ảnh được kích hoạt trong trình giả lập của bạn.


1
Cảm ơn, điều này đã làm việc cho tôi. Có cần thiết phải loại bỏ các đường dẫn khác?
CodeSlave

22

Tôi chắc chắn rằng tôi đến bữa tiệc muộn nhưng dưới đây làm việc cho tôi.

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

Đây là bước cuối cùng để làm cho mã của tôi hoạt động tốt! Cảm ơn.
Dog Dogma

15

Điều này làm tôi bối rối một chút quá.

Vấn đề là thuộc tính "path" trong tệp xml của bạn.

Từ tài liệu này , 'đường dẫn' của FileProvider là thư mục con, nhưng trong một tài liệu khác (máy ảnh / photobasics) hiển thị 'đường dẫn' là đường dẫn đầy đủ.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>

Tôi chỉ thay đổi 'đường dẫn' này thành đường dẫn đầy đủ và nó chỉ hoạt động.


15

Tôi sẽ bị trễ nhưng tôi đã tìm ra giải pháp cho nó. Làm việc tốt với tôi, tôi chỉ thay đổi đường dẫn tệp XML thành:

 <?xml version="1.0" encoding="utf-8"?>
<paths>
    <root-path name="root" path="." />
</paths>

1
Đối với tôi, điều này provider_paths.xmlđưa ra một cảnh báo kiểm tra "Đường dẫn gốc phần tử không được phép ở đây".
Luis A. Florit

15

Xin lưu ý rằng đường dẫn bên ngoài không trỏ đến bộ lưu trữ thứ cấp của bạn, còn gọi là "bộ nhớ di động" (mặc dù tên "bên ngoài"). Nếu bạn nhận được "Không thể tìm thấy root được cấu hình", bạn có thể thêm dòng này vào tệp XML của mình.

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

Xem thêm chi tiết tại đây FileProvider và bộ nhớ ngoài thứ cấp


14

Kiểm tra xem có bao nhiêu kho lưu trữ mà thiết bị của bạn cung cấp - chia sẻ tệp từ bộ lưu trữ thứ cấp không được hỗ trợ. Nhìn vào FileProvider.javanguồn (từ support-core-utils 25.3.1 ):

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

Vì vậy, họ chỉ mất lưu trữ đầu tiên.

Ngoài ra, bạn có thể thấy rằng getExternalCacheDirs()được sử dụng để có được danh sách các kho lưu trữ thông qua ContextCompatgiao diện. Xem tài liệu về các giới hạn của nó (ví dụ như được bảo là không nhận ra USB Flashes). Tốt nhất là tự mình tạo một số đầu ra gỡ lỗi danh sách các kho lưu trữ từ API này, để bạn có thể kiểm tra đường dẫn đến bộ lưu trữ khớp với đường dẫn được truyền tới getUriForFile().

Đã có một vé được chỉ định (kể từ ngày 06-2017) trong trình theo dõi vấn đề của Google, yêu cầu hỗ trợ nhiều hơn một bộ lưu trữ. Cuối cùng, tôi cũng tìm thấy câu hỏi SO về vấn đề này .


1
Câu trả lời sâu sắc này sẽ nhận được nhiều sự ủng hộ hơn. Cảm ơn bạn đã tìm kiếm những gì lưu trữ bên ngoài FileProvider thực sự nhận ra.
LarsH

10

Tôi đã dành 5 giờ cho việc này ..

Tôi đã thử tất cả các phương pháp trên nhưng nó phụ thuộc vào kho lưu trữ ứng dụng của bạn hiện đang sử dụng.

https://developer.android.com/reference/android/support/v4/content/FileProvider#GetUri

Kiểm tra tài liệu trước khi thử mã.

Trong trường hợp của tôi vì files-paththư mục phụ sẽ được Context.getFilesDir(). Điều thú vị là nó Context.getFilesDir()ghi chú một thư mục con khác.

những gì tôi đang tìm kiếm là

data/user/0/com.psh.mTest/app_imageDir/20181202101432629.png

Context.getFilesDir()

trả lại /data/user/0/com.psh.mTest/files

vì vậy thẻ nên

....files-path name="app_imageDir" path="../app_imageDir/" ......

Sau đó, nó hoạt động !!


1
Cảm ơn đã tham khảo tài liệu. Nó dẫn tôi đến câu trả lời đúng. Trong trường hợp của tôi, tập tin của tôi đã được lưu getExternalStorageDirectory()và tôi phải cung cấp đường dẫn bằng <external-path>thẻ thay vì<files-path>
alierdogan7

Cảm ơn bạn đã trả lời cụ thể về đường dẫn tập tin. Nó đã giúp rất nhiều. :)
arungiri_10

Có nó hoạt động!!! điểm quan trọng là chỉ định ".." ở đầu đường dẫn, như đường dẫn này = "../ myDirectory /"
Robert Apikyan

9

Không ai trong số này làm việc cho tôi. Cách tiếp cận duy nhất hoạt động là không khai báo một đường dẫn rõ ràng trong xml. Vì vậy, làm điều này và được hạnh phúc:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="." />
</paths>

Ở đây cũng có một hướng dẫn xuất sắc về câu hỏi này: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s


7

Vấn đề của tôi là tôi có các tên trùng nhau trong đường dẫn tệp cho các loại khác nhau, như thế này:

<cache-path
    name="cached_files"
    path="." />
<external-cache-path
    name="cached_files"
    path="." />

Sau khi tôi thay đổi tên ("cacheed_files") thành duy nhất, tôi đã thoát khỏi lỗi. Tôi đoán là những đường dẫn đó được lưu trữ trong một số HashMap hoặc thứ gì đó không cho phép trùng lặp.


3

Tôi đã làm gì để giải quyết chuyện này -

AndroidManifest.xml

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.mydomain.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"/>
        </provider>

filepaths.xml (Cho phép FileProvider chia sẻ tất cả các tệp nằm trong thư mục tệp bên ngoài của ứng dụng)

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="files"
        path="/" />
</paths>

và trong lớp java -

Uri fileProvider = FileProvider.getUriForFile(getContext(),"com.mydomain.fileprovider",newFile);

3

Điều này cũng làm việc cho tôi. Tiếp tục đưa ra đường dẫn đầy đủ tôi đã cho path = "Pictures" và nó hoạt động tốt.

<?xml version="1.0" encoding="utf-8"?>
 <paths>
  <external-files-path
    name="images"
    path="Pictures">
  </external-files-path>
 </paths>

2

Nó phụ thuộc vào loại lưu trữ bạn muốn làm, NỘI BỘ hoặc NGOẠI THẤT

cho BẢO QUẢN NGOẠI THẤT

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="my_images" path="my_images" />
</paths>

nhưng đối với BẢO QUẢN NỘI BỘ, hãy cẩn thận với đường dẫn, vì nó sử dụng phương thức getFilesDir () có nghĩa là tệp của bạn sẽ nằm trong thư mục gốc cho ứng dụng ("/")

  File storeDir = getFilesDir(); // path "/"

Vì vậy, tập tin nhà cung cấp của bạn phải như thế này:

<paths>
    <files-path name="my_images" path="/" />
</paths>

Tất cả các ví dụ cho rằng người dùng đang sử dụng bộ nhớ ngoài. Tôi cần trợ giúp với bộ nhớ trong và phải mất hàng giờ để tìm câu trả lời này. Cảm ơn bạn.
zeeshan

2

Không có cách nào ở trên làm việc cho tôi, sau vài giờ gỡ lỗi tôi phát hiện ra rằng vấn đề nằm ở chỗ createImageFile(), cụ thể là absolute pathvsrelative path

Tôi cho rằng các bạn đang sử dụng hướng dẫn chính thức của Android để chụp ảnh. https://developer.android.com/training/camera/photobasics

    private static File createImageFile(Context context) throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

Hãy lưu ý storageDir, đây là vị trí mà tệp sẽ được tạo. Vì vậy, để có được đường dẫn tuyệt đối của tệp này, tôi chỉ cần sử dụng image.getAbsolutePath(), đường dẫn này sẽ được sử dụng onActivityResultnếu bạn cần hình ảnh Bitmap sau khi chụp ảnh

bên dưới là file_path.xml, chỉ cần sử dụng .để nó sử dụng đường dẫn tuyệt đối

<paths>
    <external-path
        name="my_images"
        path="." />
</paths>

và nếu bạn cần bitmap sau khi chụp ảnh

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Bitmap bmp = null;
        try {
            bmp = BitmapFactory.decodeFile(mCurrentPhotoPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2

Tôi đã nhận được lỗi này Failed to find configured root that contains...

Các công việc sau đây giải quyết vấn đề của tôi

res / xml / file_paths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="media" path="." />
</paths>

AndroidManifest.xml

<provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="[PACKAGE_NAME]"
      android:exported="false"
      android:grantUriPermissions="true">
         <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths">
         </meta-data>
</provider>

ActivityClass.java

void shareImage() {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this,"com.slappstudio.pencilsketchphotomaker", selectedFilePath));
        startActivity(Intent.createChooser(intent,getString(R.string.string_share_with)));
    }

1

Tài liệu chính thức của Android cho biết file_paths.xml nên có:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures" />
</paths>

Nhưng để làm cho nó hoạt động trong Android mới nhất, cần có "/" ở cuối đường dẫn, như thế này:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">   
    <external-path name="my_images"    
        path="Android/data/com.example.package.name/files/Pictures/" />
</paths>

1

Thay đổi sau đây trong tệp xml file_paths làm việc cho tôi.

 <external-files-path name="my_images" path="Pictures"/>
 <external-files-path name="my_movies" path="Movies"/>

1

Tôi đã có cùng một vấn đề, tôi đã thử đoạn mã dưới đây để nó hoạt động.

1. Tạo Xmlfile: Carrier_paths

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="myfile/"/>
</paths>

2. Tập tin chính

 <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.ril.learnet.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
 </provider>

3.Trong tệp Java của bạn.

      File file =  new File(getActivity().getFilesDir(), "myfile");
        if (!file.exists()) {
            file.mkdirs();
        }
        String  destPath = file.getPath() + File.separator + attachmentsListBean.getFileName();

               file mfile = new File(destPath);
                Uri path;
                Intent intent = new Intent(Intent.ACTION_VIEW);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                {
                    path = FileProvider.getUriForFile(AppController.getInstance().getApplicationContext(), AppController.getInstance().getApplicationContext().getPackageName() + ".provider", mfile );
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                } else {
                    path = Uri.fromFile(mfile);
                }
   intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setDataAndType(path, "image/*");
                    getActivity().startActivity(intent);

1

Nếu không có gì giúp và bạn đang nhận được lỗi

failed to find configured root that contains /data/data/...

sau đó thử thay đổi một số dòng như:

File directory = thisActivity.getDir("images", Context.MODE_PRIVATE);

đến:

File directory = new File(thisActivity.getFilesDir(), "images");

và trong tệp xml:

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

Điều này thật kỳ lạ, vì thư mục tôi truy cập là /images.


Chuyển từ .getDir sang .getFilesDir đã giúp tôi. Cảm ơn!
Dmitriy Pavlukhin

1

Vấn đề của tôi là Tên tệp sai : Tôi tạo file_paths.xmldưới res / xml trong khi tài nguyên được đặt thành provider_paths.xmltrong Bản kê khai:

<provider
        android:authorities="ir.aghigh.radio.fileprovider"
        android:name="android.support.v4.content.FileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

Tôi đã thay đổi provider_pathsđến file_pathsvà vấn đề giải quyết.


1

Nếu đường dẫn tệp của bạn giống như / Storage / giả lập / 0 / "yourfile"

bạn chỉ cần sửa đổi FileProvider xml của bạn

<paths>
    <external-path name="external" path="." />
</paths>

sau đó gọi hàm này khi bạn cần chia sẻ tập tin

Intent sharingIntent = new Intent(Intent.ACTION_SEND);
                    Uri fileUri = FileProvider.getUriForFile(getContext(),
                            "com.example.myapp.fileprovider",
                            file);
                    sharingIntent.setType("*/*"); // any flie type
                    sharingIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
                    startActivity(Intent.createChooser(sharingIntent, "Share file"));

nó hoạt động trên Android M ~ Pie


Nó hoạt động! Nhưng bạn có thể giải thích lý do tại sao chúng tôi sử dụng path = "." thay vì path = "DCIM", "Hình ảnh" ...?
Hoàng Lâm

@Hoang Lam Sự khác biệt là liệu bạn có cần chỉ định một thư mục hay không, trong ví dụ của tôi, bạn có thể truy cập tất cả
lười biếng

0

Tôi thấy rằng ít nhất bạn không cung cấp cùng một đường dẫn như những người khác trong file_paths.xml. Vì vậy, hãy chắc chắn rằng bạn cung cấp chính xác cùng tên gói hoặc đường dẫn ở 3 nơi bao gồm:

  • android:authorities thuộc tính trong bảng kê khai
  • path thuộc tính trong file_paths.xml
  • authority đối số khi gọi FileProvider.getUriForFile ().

0
  • Dành cho người dùng Xamarin.Android

Đây cũng có thể là kết quả của việc không cập nhật các gói hỗ trợ của bạn khi nhắm mục tiêu Android 7.1, 8.0+. Cập nhật chúng lên v25.4.0.2 + và lỗi cụ thể này có thể biến mất (cung cấp cho bạn công thức cấu hình tệp file_path chính xác như những người khác đã nêu).


Đưa ra bối cảnh: Tôi đã chuyển sang nhắm mục tiêu Oreo từ Nougat trong ứng dụng Xamarin.Forms và chụp ảnh bằng Xam.Plugin.Media bắt đầu thất bại với thông báo lỗi ở trên, vì vậy việc cập nhật các gói đã giúp tôi rất ổn.


0

Tôi nhận thấy rằng chính sách hoặc hành vi liên quan đến path.xmltệp đã thay đổi giữa Thư viện hỗ trợ 26 và 27. Để chụp ảnh từ máy ảnh, tôi đã thấy các thay đổi sau:

  • Với 26, tôi phải sử dụng <external-path>và đường dẫn đầy đủ được đưa ra trong pathđối số.

  • Với 27, tôi đã phải sử dụng <external-files-path>và chỉ có thư mục con trong pathđối số.

Vì vậy, những gì đặc biệt làm việc cho tôi với Thư viện hỗ trợ 27 là path.xmltệp

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="camera_image" path="Pictures/"/>
</paths>

0

Xin chào bạn bè Hãy thử điều này

Trong mã này

1) Cách khai báo 2 nhà cung cấp tệp trong tệp kê khai.

2) Nhà cung cấp đầu tiên cho tập tin Tải xuống

3) Nhà cung cấp thứ hai được sử dụng cho máy ảnh và thư viện

BƯỚC 1

     <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>

Nhà cung cấp_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="apks" path="." />
</paths>

Nhà cung cấp thứ hai

     <provider
        android:name=".Utils.MyFileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true"
        tools:replace="android:authorities"
        tools:ignore="InnerclassSeparator">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_path" />
    </provider>

file_path.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="storage/emulated/0" path="."/>
</paths>

.Utils.MyFileProvider

Tạo lớp MyFileProvider (chỉ Tạo lớp không có bất kỳ phương thức nào khai báo)

Khi bạn sử dụng Trình cung cấp tệp được sử dụng (.fileprovider) tên này và bạn đã sử dụng cho hình ảnh (.provider) đã sử dụng tên này.

NẾU có một vấn đề để hiểu mã này Bạn có thể liên hệ trên rp1741995 @ gmail tôi sẽ giúp bạn.


0

Vấn đề có thể không chỉ là đường dẫn xml.

Sau đây là cách khắc phục của tôi:

Nhìn vào khóa học gốc trong android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile():

    public File getFileForUri(Uri uri) {
        String path = uri.getEncodedPath();

        final int splitIndex = path.indexOf('/', 1);
        final String tag = Uri.decode(path.substring(1, splitIndex));
        path = Uri.decode(path.substring(splitIndex + 1));

        final File root = mRoots.get(tag); // mRoots is parsed from path xml
        if (root == null) {
            throw new IllegalArgumentException("Unable to find configured root for " + uri);
        }

        // ...
    }

Điều này có nghĩa là mRootsnên chứa thẻ của uri được yêu cầu. Vì vậy, tôi viết một số mã để in mRootsvà gắn thẻ của uri, và sau đó dễ dàng tìm thấy các thẻ không khớp .

Nó xuất hiện rằng thiết lập thẩm quyền nhà cung cấp ${applicationID}.providerlà một ý tưởng ngu ngốc ! Quyền này rất phổ biến đến mức có thể được sử dụng bởi các nhà cung cấp khác, điều này sẽ làm rối cấu hình đường dẫn!


-1

Bạn cần thay đổi tệp xml file_paths.xml từ

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="my_images" path="images/"/>
</paths>

đến

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <fexeternal-path name="my_images" path="Android/data/com.example.marek.myapplication/files/Pictures"/>
</paths>

1
Mặc dù bạn đã sao chép câu trả lời của mình từ phía trên, nhưng nó không được thực hiện đúng. Vui lòng sửa lỗi không khớp trong câu trả lời của bạn.
Abhinav Saxena
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.