FileProvider - IllegalArgumentException: Nie można znaleźć skonfigurowanego katalogu głównego


233

Próbuję zrobić zdjęcie aparatem, ale pojawia się następujący błąd:

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>

Jawa:

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);
        }
    }

ścieżka_pliku.xml

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

Cały dzień szukałem informacji o tym błędzie i próbowałem zrozumieć FileProvider, ale nie mam pojęcia, co ten komunikat o błędzie próbuje mi powiedzieć. Jeśli chcesz uzyskać więcej informacji / kodu, napisz do mnie w komentarzu.


2
Czy możesz również wkleić kod metody createImageFile?
Ankit Batra

Przykro mi, ale anulowałem ten projekt i już go nie pracuję . Zaakceptuję najbardziej ulubioną odpowiedź, aby „zamknąć” to pytanie. Dziękujemy wszystkim za udział i mam nadzieję, że to pomoże innym.
Pivoman

Wpadłem na ten sam problem. Znaleziono to rozwiązanie, aby uzyskać podstawową konfigurację FileProvider przy użyciu minimalnego przykładowego projektu github: stackoverflow.com/a/48103567/2162226 . Zawiera kroki, które należy skopiować (bez wprowadzania zmian) do lokalnego autonomicznego projektu
Gene Bo

Ten problem został teraz rozwiązany w Delphi 10.4: quality.embarcadero.com/browse/RSP-26950
Dave Nottage

Odpowiedzi:


209

Twój plik jest przechowywany pod getExternalFilesDir(). To odwzorowuje <external-files-path>, nie <files-path>. Ponadto ścieżka do pliku images/w nim nie zawiera , więc pathatrybut w pliku XML jest nieprawidłowy.

Zamień na res/xml/file_paths.xml:

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

AKTUALIZACJA 2020 MAR 13

Ścieżka dostawcy dla określonej ścieżki w następujący sposób:

  • <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()

Ref: https://developer.android.com/reference/androidx/core/content/FileProvider


5
ok, dodałem ścieżkę do plików zewnętrznych, ale nadal mam ten sam błąd: / Być może jest więcej błędów. Używam emulatora urządzenia z Androidem, czy muszę utworzyć ten folder czy coś takiego?
Pivoman

22
Należy zdefiniować atrybut „ścieżka”. W konfiguracji brakuje nam ścieżki.
blackjack,

1
Miałem problem z wieloma ścieżkami na Androidzie 5. Zostawiłem tylko jedną ścieżkę, zamiast 2.
ODAXY

3
Otrzymałem jeden raport o awarii (chyba 50-100 urządzeń), który jest identyczny z tym. <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>To, path="."co znalazłem w moich własnych badaniach, by pozostać na najwyższym poziomie. Jeśli przejdziesz bliżej przez FileProvider, zobaczysz, że ścieżka odczytywana z XML zostaje sprowadzona do kanonu. Domyślam się, że ContextCompat#getExternalFilesDirszwróciło wartość null @ line 616 (v26.0.1), więc PathStrategy nie zostało zarejestrowane. Stało się to na urządzeniu Huawei.
androidguy 13.03.18

10
Zamiast używać <ścieżka-zewnętrznych plików-próbowałem <ścieżka-zewnętrznych i zadziałało.
Bezpieczniejszy

166

To może rozwiązać problem każdego: wszystkie tagi są dodawane, więc nie musisz się martwić o ścieżkę folderów. Zamień res / xml / file_paths.xml na:

<?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
Najlepsze rozwiązanie Dzięki.
Pawan Pillai

1
Proste rozwiązanie ... ale za to genialne! Skorzystałem z usługodawcy, a następnie wprowadziłem możliwość zmiany katalogu docelowego ... nic już nie działało, ponieważ w tym momencie dostawca powinien być dynamiczny ... uratowałeś mi dzień!
Bronz

1
skorzystałem z tego rozwiązania i kod zaczął działać. Usunięto niepotrzebny kod, testując, który z nich działał
Kartik

1
Stary, uratowałeś mi dzień.
Wielkie

1
Świetnie działało dla mnie, jako nowy uczeń uświadomiłem sobie, że nie otrzymuję z plików zewnętrznych, ale z pamięci podręcznej
Tony Merritt

82

Podobny problem występuje po włączeniu smaków (program, scena).

Przed smakami mój zasób ścieżki wyglądał tak:

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

Po dodaniu Androida: władze = "$ {applicationId} .fileprovider" w Manifeście appId to pl.myapp.dev lub pl.myapp.stage zależy od smaku i aplikacja zaczęła się zawieszać. Usunąłem pełną ścieżkę i zastąpiłem ją kropką i wszystko zaczęło działać.

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

7
Pracował dla mnie. Dzięki! Jak wymyśliłeś „.” notacja ?
NightFury,

2
@antygravity czy możesz podać referencje / dokumentację tego rozwiązania?
geekoraul

7
Czy są jakieś negatywne konsekwencje tego rozwiązania?
RediOne1

Pracował dla mnie, wielkie dzięki.
Hiren

To powinna być zaakceptowana odpowiedź! Jedyne rozwiązanie, które zadziałało
egorikem

43

Jeśli używasz wewnętrznej pamięci podręcznej, użyj.

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

3
dzięki, moja sytuacja: chcę zainstalować aplikację, która zapisała się w / data / data / pkg_name / files, więc moja poprawna konfiguracja wygląda następująco: <files-path name = "files" path = "/" />
aolphn

25

Straciłem 2 tygodnie, próbując znaleźć rozwiązanie ... Jeśli przyjedziesz tutaj po wypróbowaniu czegoś powyżej:

1 - Sprawdź, czy Twój dostawca tagów znajduje się w aplikacji tagów

<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 - Jeśli wypróbujesz wiele ścieżek bez powodzenia, przetestuj za pomocą:

<?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>

Przetestuj to, jeśli kamera działa, a następnie zacznij eliminować niektóre linie i kontynuuj testowanie ...

3 - Nie zapomnij sprawdzić, czy kamera jest aktywowana w emulatorze.


1
Dzięki, to zadziałało dla mnie. Czy konieczne jest usunięcie innych ścieżek?
CodeSlave,

22

Jestem pewien, że spóźniłem się na przyjęcie, ale poniżej działało dla mnie.

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

To był ostatni krok do uruchomienia mojego kodu! Dzięki.
Dog Dogma

15

To też trochę mnie dezorientuje.

Problem dotyczy atrybutu „path” w pliku xml.

Z tego dokumentu FileProvider „ścieżka” jest podkatalogiem, ale w innym dokumencie (kamera / fotobazika) pokazana „ścieżka” jest pełną ścieżką.

<?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>

Po prostu zmieniam tę „ścieżkę” na pełną i to po prostu działa.


15

Spóźnię się, ale znalazłem rozwiązanie tego problemu. Po prostu zmieniłem plik XML ścieżek na:

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

1
Dla mnie to provider_paths.xmldaje ostrzeżenie z inspekcji „Ścieżka do elementu nie jest tutaj dozwolona”.
Luis A. Florit,

15

Należy pamiętać, że ścieżka zewnętrzna nie wskazuje na pamięć dodatkową, czyli „pamięć wymienną” (pomimo nazwy „zewnętrzna”). Jeśli otrzymujesz komunikat „Nie można znaleźć skonfigurowanego katalogu głównego”, możesz dodać ten wiersz do pliku XML.

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

Zobacz więcej szczegółów tutaj FileProvider i dodatkowa pamięć zewnętrzna


14

Sprawdź, ile pamięci oferuje urządzenie - udostępnianie plików z pamięci dodatkowej nie jest obsługiwane. Spójrz na FileProvider.javaźródło (z 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];
                }
            }

Biorą więc tylko pierwsze miejsce do przechowywania.

Można również zobaczyć, że getExternalCacheDirs()służy do uzyskania listy magazynów za pośrednictwem ContextCompatinterfejsu. Zobacz dokumentację jego limitów (na przykład nie rozpoznaje Flash USB). Najlepszym rozwiązaniem jest samodzielne wykonanie niektórych wyników debugowania listy magazynów z tego interfejsu API, aby można było sprawdzić, czy ścieżka do magazynu jest zgodna z przekazaną ścieżką getUriForFile().

W narzędziu do śledzenia problemów Google jest już przypisany bilet (jak na 06-2017) z prośbą o obsługę więcej niż jednego miejsca. W końcu znalazłem również SO pytanie w tej sprawie .


1
Ta dogłębna odpowiedź powinna zyskać więcej głosów pozytywnych. Dziękujemy za sprawdzenie, co faktycznie rozpoznaje zewnętrzny magazyn danych FileProvider.
LarsH

10

Spędziłem na to 5 godzin ..

Wypróbowałem wszystkie powyższe metody, ale zależy to od tego, jakiego magazynu używa Twoja aplikacja.

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

Sprawdź dokumentację przed wypróbowaniem kodów.

W moim przypadku files-pathbędzie to podkatalog Context.getFilesDir(). To jest funkyContext.getFilesDir() , zauważa inny podkatalog.

to czego szukam

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

Context.getFilesDir()

zwroty /data/user/0/com.psh.mTest/files

więc tag powinien być

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

To działa !!


1
Dziękujemy za odwołanie się do dokumentacji. Doprowadziło mnie to do poprawnej odpowiedzi. W moim przypadku mój plik został zapisany getExternalStorageDirectory()i powinienem podać ścieżkę ze <external-path>znacznikiem zamiast<files-path>
alierdogan7

Dziękujemy za tę konkretną odpowiedź na ścieżce plików. To bardzo pomogło. :)
arungiri_10

Tak to działa!!! kluczowym punktem jest określenie „..” na początku ścieżki, jak ta ścieżka = „../ myDirectory /”
Robert Apikyan

9

Nic z tego nie działało dla mnie. Jedyne podejście, które działa, to nie deklarować wyraźnej ścieżki w xml. Zrób to i bądź szczęśliwy:

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

Tutaj również znajduje się doskonały samouczek na temat tego pytania: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s


7

Mój problem polegał na tym, że w ścieżkach plików zachodziły na siebie nazwy różnych typów, na przykład:

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

Po zmianie nazw („cached_files”) na unikalne, pozbyłem się błędu. Domyślam się, że te ścieżki są przechowywane w HashMap lub czymś, co nie pozwala na duplikaty.


3

Co zrobiłem, aby to rozwiązać -

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 (Zezwolenie FileProvider na udostępnianie wszystkich plików znajdujących się w katalogu plików zewnętrznych aplikacji)

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

oraz w klasie java -

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

3

Działa to również dla mnie. Zamiast podania pełnej ścieżki podałem path = "Pictures" i działało dobrze.

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

2

Zależy, jaki rodzaj pamięci chcesz zrobić, WEWNĘTRZNY lub ZEWNĘTRZNY

do PRZECHOWYWANIA ZEWNĘTRZNEGO

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

ale w przypadku PRZECHOWYWANIA WEWNĘTRZNEGO należy uważać na ścieżkę, ponieważ używa ona metody getFilesDir (), co oznacza, że ​​plik będzie znajdować się w katalogu głównym aplikacji („/”)

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

Twój plik dostawcy musi być taki:

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

Wszystkie przykłady zakładają, że użytkownik korzysta z pamięci zewnętrznej. Potrzebowałem pomocy z pamięcią wewnętrzną i znalezienie tej odpowiedzi zajęło wiele godzin. Dziękuję Ci.
zeeshan

2

żadne z powyższych nie działało dla mnie, po kilku godzinach debugowania dowiedziałem się, że problem jest w createImageFile()szczególnościabsolute path vsrelative path

Zakładam, że korzystacie z oficjalnego przewodnika na Androida do robienia zdjęć. 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;
    }

Zwróć uwagę na to storageDir, gdzie zostanie utworzony plik. Aby uzyskać bezwzględną ścieżkę do tego pliku, po prostu używam image.getAbsolutePath()tej ścieżkionActivityResult jeśli potrzebujesz obrazu bitmapowego po zrobieniu zdjęcia

poniżej jest file_path.xml, po prostu użyj, .aby używał ścieżki bezwzględnej

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

a jeśli potrzebujesz mapy bitowej po zrobieniu zdjęcia

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

Otrzymałem ten błąd Failed to find configured root that contains...

Poniższe obejście rozwiązuje mój problem

res / xml / ścieżka_pliku.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

Oficjalny dokument Androida mówi, że file_paths.xml powinien mieć:

<?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>

Aby jednak działało w najnowszym Androidzie, na końcu ścieżki powinien znajdować się znak „/”:

<?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

Dla mnie zadziałała następująca zmiana w pliku xml file_paths.

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

1

Miałem ten sam problem, wypróbowałem poniższy kod do jego działania.

1. Utwórz plik Xml: ścieżka_ dostawcy

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

2. Plik Mainfest

 <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. W pliku Java.

      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

Jeśli nic nie pomaga i pojawia się błąd

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

następnie spróbuj zmienić jakąś linię, np .:

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

do:

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

oraz w pliku xml:

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

co jest dziwne, ponieważ folder, do którego mam dostęp, to /images.


Pomogło mi przejście z .getDir na .getFilesDir. Dzięki!
Dmitriy Pavlukhin,

1

Mój problem był nieprawidłowy Nazwa pliku : tworzę file_paths.xmlw res / xml, gdy zasób był ustawiony na provider_paths.xmlManifest:

<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>

Zmieniłem provider_pathssię file_pathsi problem rozwiązany.


1

Jeśli twoja ścieżka do pliku jest podobna do / storage / emulated / 0 / "yourfile"

wystarczy zmodyfikować plik XML FileProvider

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

następnie wywołaj tę funkcję, gdy potrzebujesz udostępnić plik

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"));

działa na Androidzie M ~ Pie


To działa! Ale czy możesz wyjaśnić, dlaczego używamy path = "." zamiast ścieżki = „DCIM”, „Obrazy” ...?
Hoang Lam

@Hoang Lam Różnica polega na tym, czy musisz podać katalog, w moim przykładzie możesz uzyskać dostęp do wszystkich
leniwy

0

Widzę, że przynajmniej nie podajesz tej samej ścieżki, co inni w file_paths.xml. Upewnij się, że podałeś dokładnie taką samą nazwę paczki lub ścieżkę w 3 miejscach, w tym:

  • android:authorities atrybut w manifeście
  • path atrybut w pliku ścieżka_pliku.xml
  • authority argument podczas wywoływania funkcji FileProvider.getUriForFile ().

0
  • Dla użytkowników Xamarin.Android

Może to również wynikać z nieaktualizowania pakietów pomocy technicznej w przypadku systemu Android 7.1, 8.0+. Zaktualizuj je do wersji 25.4.0.2 +, a ten konkretny błąd może zniknąć (co oznacza, że ​​poprawnie skonfigurowałeś plik file_path, jak twierdzą inni).


Dając kontekst: przełączyłem się na celowanie w Oreo z Nougat w aplikacji Xamarin.Forms i zrobienie zdjęcia za pomocą Xam.Plugin.Media zaczęło się nie powieść z powyższym komunikatem o błędzie, więc aktualizacja pakietów pomogła mi.


0

Zauważyłem, że zasady lub zachowanie dotyczące path.xmlpliku zmieniły się między biblioteką pomocy 26 i 27. W przypadku przechwytywania obrazu z kamery widziałem następujące zmiany:

  • Z 26 musiałem użyć <external-path>i pełną ścieżkę podaną w pathargumencie.

  • Mając 27, musiałem użyć <external-files-path>i tylko podfolder w pathargumencie.

Co konkretnie zadziałało dla mnie z biblioteką pomocy technicznej 27 w postaci path.xmlpliku

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

0

Cześć przyjaciele, spróbuj tego

W tym kodeksie

1) Jak zadeklarować 2 dostawców plików w Manifeście.

2) Pierwszy dostawca pobierania plików

3) drugi dostawca używany do kamery i galerii

KROK 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>

Provider_paths.xml

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

Drugi dostawca

     <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>

ścieżka_pliku.xml

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

.Utils.MyFileProvider

Utwórz klasę MyFileProvider (tylko Utwórz klasę, żadna metoda nie deklaruje)

Kiedy używałeś dostawcy plików (.fileprovider), używałeś tej nazwy i używałeś obrazu (.provider).

JEŚLI ktokolwiek Problem ze zrozumieniem tego kodu Możesz skontaktować się z rp1741995@gmail.com. Pomogę ci.


0

Problemem może być nie tylko ścieżka xml.

Oto moja poprawka:

Patrząc na kurs root w 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);
        }

        // ...
    }

Oznacza to, że mRootspowinien zawierać znacznik żądanego URI. Piszę więc kod do wydrukowania mRootsi oznaczenia URI, a następnie łatwo znajduję, że znaczniki się nie zgadzają .

Okazuje się, że ustawienie autorytetu dostawcy jako ${applicationID}.providergłupi pomysł ! Ten autorytet jest tak powszechny, że może być używany przez innych dostawców, co zepsuje konfigurację ścieżki!


-1

Musisz zmienić plik xml ścieżka_pliku.xml z

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

do

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

1
Mimo że skopiowałeś odpowiedź z góry, nie jest to zrobione poprawnie. Popraw niedopasowanie pisania w swojej odpowiedzi.
Abhinav Saxena
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.