FileProvider - IllegalArgumentException: Не вдалося знайти налаштований корінь


233

Я намагаюся сфотографуватися фотоапаратом, але отримую таку помилку:

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>

Я цілий день шукав цю помилку і намагався зрозуміти FileProvider, але поняття не маю, що намагається мені сказати це повідомлення про помилку. Якщо ви хочете отримати більше інформації / коду, напишіть мені у коментарі.


2
Чи можете ви також вставити код методу createImageFile?
Анкіт Батра

Мені дуже шкода, але я скасував цей проект і над ним більше не працюю . Я прийму найулюбленішу відповідь, щоб "закрити" це питання. Дякую всім за участь і сподіваюся, що це допомагає іншим.
Півоман

Побіг у тому ж випуску. Знайшов це рішення для отримання базової установки FileProvider, використовуючи мінімальний приклад проекту github: stackoverflow.com/a/48103567/2162226 . Він надає кроки, за допомогою яких файли можна скопіювати (не вносячи змін) у локальний окремий проект
Джин Бо

Зараз ця проблема виправлена ​​в Delphi 10.4: quality.embarcadero.com/browse/RSP-26950
Дейв Нотдж

Відповіді:


209

Ваш файл зберігається під getExternalFilesDir(). Це карти, щоб <external-files-path>не <files-path>. Крім того, ваш шлях до файлу не містить images/його, тому pathатрибут у вашому XML недійсний.

Замінити res/xml/file_paths.xmlна:

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

ОНОВЛЕННЯ 2020 БР 13

Шлях постачальника для певного шляху в наступному:

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

Посилання: https://developer.android.com/reference/androidx/core/content/FileProvider


5
ок, я додав зовнішні файли-шлях, але у мене все ще така ж помилка: / Можливо, більше помилок. Я використовую емулятор Android пристрою, чи потрібно створити цю папку чи щось таке?
Півоман

22
атрибут "path" повинен бути визначений "нам не вистачає тут конфігурації.
блекджек

1
У мене виникли проблеми з кількома шляхами на Android 5. Залишив лише один шлях, а не 2.
ODAXY

3
Я отримав один звіт про збої (я думаю, з 50-100 пристроїв), який ідентичний цьому. <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>Це path="."те, що я виявив у власних дослідженнях, щоб залишатися на вищому рівні. Якщо детальніше пройти через FileProvider, ви побачите, що шлях, прочитаний з XML, стає канонізованим. Я найкраще здогадуюсь, що ContextCompat#getExternalFilesDirsповернувся null @line 616 (v26.0.1), тому PathStrategy не був зареєстрований. Це сталося на пристрої Huawei.
androidguy

10
Замість використання <external-files-path я спробував <external-path і він працював.
Безпечніший

166

Це може вирішити проблему кожного: всі теги додані, тому вам не потрібно турбуватися про шлях папок. Замініть res / xml / file_paths.xml на:

<?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
Найкраще рішення. Дякую.
Pawan Pillai

1
Просте рішення ... але для цього геніального! Я використовував провайдера, тоді я ввів користувачеві можливість змінити каталог призначення ... нічого більше не працювало, тому що в цей момент провайдер повинен бути динамічним .... ти врятував мій день!
Бронз

1
використав це рішення і код почав працювати. Видалили непотрібний код, перевіривши, хто з них працював
Картик

1
Брат, ти врятував мені день. Велике спасибі :-)
manjunath kallannavar

1
Чудово працював для мене, як новий студент, це дало мені зрозуміти, що я не отримую із зовнішніх файлів, а кеш
Тоні Меррітт,

82

Отримала подібну проблему після включених ароматів (розробник, сцена).

Перед ароматами ресурс мого шляху виглядав так:

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

Після додавання android: vlasti = "$ {applicationId} .fileprovider" у додатку Manifest було pl.myapp.dev або pl.myapp.stage залежить від аромату і додаток почав виходити з ладу. Я видалив повний шлях і замінив його крапкою, і все почало працювати.

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

7
Працювали для мене. Дякую! Як ви придумали "." позначення?
NightFury

2
@antygravity чи можете ви надати посилання / документацію цього рішення?
geekoraul

7
Чи є якісь негативні наслідки цього рішення?
RediOne1

Працювали для мене, спасибі велике.
Хірен

Це має бути прийнята відповідь! Єдине рішення, яке спрацювало
egorikem

43

Якщо ви використовуєте внутрішній кеш, тоді використовуйте.

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

3
дякую, моя ситуація: я хочу встановити додаток, яке зберегло в / data / data / pkg_name / файли, тому моя правильна конфігурація наступна: <files-path name = "files" path = "/" />
aolphn

25

Втрачено 2 тижні, намагаючись знайти рішення ... Якщо ви приїдете сюди після того, як спробуйте все вище:

1 - Перевірте, чи є ваш постачальник тегів всередині програми для тегів

<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 - Якщо ви без успіху пробуєте багато шляхів, тестуйте це:

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

Перевірте це, якщо камера працює, тоді почніть усунути деякі рядки та продовжуйте тестування ...

3 - Не забудьте перевірити, чи у вашому емуляторі активна камера.


1
Дякую, це працювало для мене. Чи потрібно видаляти інші шляхи?
CodeSlave

22

Я впевнений, що я спізнився на вечірку, але нижче працював на мене.

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

Це був останній крок, щоб мій код також працював! Дякую.
Собака Догма

15

Це теж мене бентежить.

Проблема полягає в атрибуті "path" у вашому XML-файлі.

З цього документа FileProvider "шлях" є підкаталогом, але в іншому документі (камера / фотобазика) показаний "шлях" - це повний шлях.

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

Я просто змінюю цей "шлях" на повний шлях, і він просто працює.


15

Я запізнився, але знайшов рішення для цього. Працюючи чудово для мене, я просто змінив XML-файл шляхів на:

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

1
Для мене це provider_paths.xmlдає інспекційне попередження "Елемент root-path тут не дозволений".
Луїс А. Флорит

15

Майте на увазі, що зовнішній шлях не вказує на ваш вторинний накопичувач, він називається "знімним сховищем" (незважаючи на назву "зовнішній"). Якщо ви отримуєте "Не вдалося знайти налаштований корінь", ви можете додати цей рядок у свій XML-файл.

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

Детальніше дивіться тут FileProvider та вторинне зовнішнє сховище


14

Перевірте, скільки сховищ пропонує ваш пристрій - обмін файлами з вторинного сховища не підтримується. Подивіться на FileProvider.javaджерело (з підтримки-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];
                }
            }

Отже, вони беруть лише перше сховище.

Також ви бачите, що getExternalCacheDirs()використовується для отримання списку сховищ через ContextCompatінтерфейс. Перегляньте документацію щодо її меж (сказано, наприклад, не розпізнавати спалахи USB). Найкраще самостійно зробити налагодження виводу списку сховищ із цього API, щоб ви могли перевірити, чи відповідає шлях до пам’яті шляху, який пройшов getUriForFile().

У трекері випуску Google вже призначений квиток (як на 06-2017), який просить підтримувати більше одного сховища. Врешті-решт, я знайшов ТАК питання і з цього приводу .


1
Ця поглиблена відповідь повинна отримувати більше результатів. Дякуємо, що дізналися, що насправді розпізнає FileProvider із зовнішнього сховища.
LarsH

10

Я витратив на це 5 годин ..

Я спробував усі вищевикладені методи, але це залежить від того, яке сховище зараз використовує ваша програма.

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

Перевірте документацію, перш ніж спробувати коди.

У моєму випадку, оскільки files-pathпідкаталог буде Context.getFilesDir(). Найцікавішою є те, що вона Context.getFilesDir()зазначає один в одному підкаталозі.

те, що я шукаю, це

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

Context.getFilesDir()

повертає /data/user/0/com.psh.mTest/files

тому тег повинен бути

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

Тоді це працює !!


1
Дякуємо за посилання на документацію. Це привело мене до правильної відповіді. У моєму випадку мій файл було збережено, getExternalStorageDirectory()і я повинен був надати шлях із <external-path>тегом замість<files-path>
alierdogan7

Дякуємо вам за цю конкретну відповідь на шляху до файлів. Це дуже допомогло. :)
arungiri_10

Так, це працює !!! Ключовий момент - вказати ".." на початку шляху, як цей шлях = "../ myDirectory /"
Роберт Апікян

9

Нічого цього не працювало для мене. Єдиний підхід, який працює, - це не оголосити явний шлях у xml. Тож зробіть це і будьте раді:

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

Тут також є чудовий підручник з цього питання: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s


7

Моя проблема полягала в тому, що у мене були перекриваються імена у шляхах до файлів для різних типів, наприклад:

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

Після того як я змінив імена ("cached_files") на унікальні, я позбувся помилки. Я здогадуюсь, що ці шляхи зберігаються в якомусь HashMap або в чомусь, що не дозволяє дублікати.


3

Що я зробив для вирішення цього питання -

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 (Дозволяє FileProvider ділитися всіма файлами, що знаходяться у зовнішньому каталозі файлів програми)

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

і в класі java -

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

3

Це працювало і для мене. Замість того, щоб дати повний шлях, я дав шлях = "Картинки", і це працювало чудово.

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

2

Це залежить від того, який тип зберігання ви хочете зробити, ВНУТРІШНЕ або зовнішнє

ДЛЯ ВНУТРІШНЬОГО ЗБЕРІГАННЯ

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

але для ВНУТРІШНЬОГО СХОДЖЕННЯ будьте обережні з доріжкою, оскільки він використовує метод getFilesDir (), який означає, що ваш файл буде розташований у кореневій директорії програми ("/")

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

Отже, файл вашого постачальника повинен бути таким:

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

Усі приклади припускають, що користувач використовує зовнішню пам’ять. Мені була потрібна допомога з внутрішнім зберіганням, і знадобилося кілька годин, щоб знайти цю відповідь. Дякую.
Zeeshan

2

ніщо з вищезгаданого не працювало для мене, після кількох годин налагодження я з'ясував, що проблема полягає в createImageFile(), зокрема, absolute pathпротиrelative path

Я припускаю, що ви, хлопці, використовуєте офіційний посібник для Android для фотографування. 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;
    }

Зверніть увагу на те storageDir, що саме тут буде створений файл. Отже, щоб отримати абсолютний шлях цього файлу, я просто використовую image.getAbsolutePath(), цей шлях буде використаний, onActivityResultякщо вам потрібно фото Bitmap після фотографування

нижче - file_path.xmlпросто, використовуйте .так, щоб він використовував абсолютний шлях

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

і якщо вам потрібна растрова карта після фотографування

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

Я отримував цю помилку Failed to find configured root that contains...

Наступна робота навколо вирішує мою проблему

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

Офіційний документ Android говорить, що файл file_paths.xml повинен мати:

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

Але для того, щоб він працював на останньому Android, у кінці шляху має бути "/", наприклад:

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

Наступна зміна у файлі xml file_paths працювала на мене.

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

1

У мене була така ж проблема, я спробував наведений нижче код для його роботи.

1.Створіть Xmlfile: провайдер_путь

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

2. Файл 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.У вашому файлі 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

Якщо нічого не допомагає, і ви отримуєте помилку

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

то спробуйте змінити рядок типу:

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

до:

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

і у файлі xml:

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

що дивно, оскільки папка, до якої я є доступ /images.


Перехід від .getDir до .getFilesDir мені допоміг. Дякую!
Дмитро Павлухін

1

Моя проблема була неправильною Ім'я файлу : я створюю file_paths.xmlпід res / xml, тоді як ресурс був встановлений provider_paths.xmlу Manifest:

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

Я змінив provider_pathsдо file_pathsі проблема вирішена.


1

Якщо шлях до файлу схожий / сховище / емуляція / 0 / "ваш файл"

вам просто потрібно змінити файл FileProvider xml

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

потім зателефонуйте до цієї функції, коли вам потрібен файл спільного доступу

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

він працює на android M ~ Pie


Це працює! Але чи можете ви пояснити, чому ми використовуємо path = ". замість path = "DCIM", "Картинки" ...?
Хоанг Лам

@Hoang Lam Різниця в тому, чи потрібно вам вказати каталог, у моєму прикладі ви можете отримати доступ до всіх
ледачий

0

Я бачу, що принаймні ви не надаєте той самий шлях, як інші у file_paths.xml. Тому переконайтеся, що ви вказуєте точно таку ж назву пакета або шлях у трьох місцях, включаючи:

  • android:authorities атрибут у маніфесті
  • path атрибут у file_paths.xml
  • authority аргумент при виклику FileProvider.getUriForFile ().

0
  • Для користувачів Xamarin.Android

Це також може бути результатом не оновлення ваших пакетів підтримки під час націлювання на Android 7.1, 8.0 або новішої версії. Оновіть їх до v25.4.0.2 +, і ця конкретна помилка може усунутись (даючи правильно налаштувати файл file_path, як зазначено в інших).


Даючи контекст: я перейшов на націлювання на Oreo від Nougat в додатку Xamarin.Forms і сфотографуватися за допомогою Xam.Plugin.Media почав виходити з ладу з вищевказаним повідомленням про помилку, тому оновлення пакетів зробило мені трюк добре.


0

Я помітив, що політика або поведінка стосовно path.xmlфайлу змінюються між Бібліотекою підтримки 26 і 27. Для зйомки зображення з камери я побачив такі зміни:

  • З 26 років мені довелося використовувати <external-path>і повний шлях, наведений в pathаргументі.

  • З 27 я мав використовувати <external-files-path>і pathаргумент лише підпапки .

Отже, що спеціально для мене працювало з Бібліотекою підтримки 27, як path.xmlфайл

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

0

Привіт, друзі. Спробуйте це

У цьому Кодексі

1) Як оголосити провайдера файлів 2 у Manifest.

2) Перший постачальник для завантаження файлу

3) другий постачальник, який використовується для камери та галар

КРОК 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>

Другий постачальник

     <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

Створення класу MyFileProvider (тільки Створити клас, жоден метод не оголошує)

Коли ви використовували провайдер файлів (.fileprovider) це ім'я, а ви використовували зображення (.provider).

ЯКЩО є якась проблема для розуміння цього коду Ви можете зв'язатися з rp1741995@gmail.com, я допоможу вам.


0

Проблемою може бути не лише шлях xml.

Далі йде моє виправлення:

Розглядаючи кореневий курс у 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);
        }

        // ...
    }

Цей засіб mRootsповинен містити тег запитуваного урі. Тому я пишу якийсь код для друку mRootsта тегу урі, а потім легко знаходжу теги, які не відповідають .

Виходить, що встановити повноваження постачальника як ${applicationID}.providerдурна ідея ! Цей авторитет настільки поширений, що може бути використаний іншими постачальниками, що зіпсує конфігурацію шляху!


-1

Вам потрібно змінити файл xml file_paths.xml з

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

до

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

1
Хоча ви скопіювали свою відповідь зверху, вона зроблена неправильно. Будь ласка, виправте невідповідність набору тексту у своїй відповіді.
Абхінав Саксена
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.