FileProvider - IllegalArgumentException: falha ao localizar a raiz configurada

233

Estou tentando tirar uma foto com a câmera, mas estou recebendo o seguinte erro:

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>

Eu estava pesquisando o dia inteiro sobre esse erro e tentando entender FileProvider, mas não tenho idéia do que essa mensagem de erro tenta me dizer. Se você quiser mais informações / código, escreva-me no comentário.

Pivoman
fonte
2
Você também pode colar o código do método createImageFile?
Ankit Batra
Sinto muito, mas cancelei este projeto e não estou mais trabalhando nele . Aceitarei a resposta mais favorita para "fechar" esta pergunta. Obrigado a todos pela participação e espero que ajude aos outros.
Pivoman # 14/17
Ocorreu o mesmo problema. Encontrei esta solução para obter uma configuração básica do FileProvider usando um projeto de exemplo mínimo do github: stackoverflow.com/a/48103567/2162226 . Ele fornece etapas para que os arquivos para copiar (sem fazer alterações) em um projeto autônomo locais
Gene Bo
Agora, esse problema foi corrigido no Delphi 10.4: quality.embarcadero.com/browse/RSP-26950
Dave Nottage

Respostas:

211

Seu arquivo é armazenado em getExternalFilesDir(). Isso mapeia para <external-files-path>, não <files-path>. Além disso, o caminho do arquivo não contém images/, portanto o pathatributo no seu XML é inválido.

Substitua res/xml/file_paths.xmlpor:

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

ATUALIZAÇÃO 2020 13 DE MAR

Caminho do provedor para um caminho específico, como segue:

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

CommonsWare
fonte
5
ok, adicionei caminho de arquivos externos, mas ainda tenho o mesmo erro: / Talvez haja mais erros. Estou usando o dispositivo Android emulador, tenho que criar essa pasta ou algo assim?
Pivoman 28/02
22
"O atributo 'caminho' deve ser definido", estamos faltando aqui o caminho na configuração.
blackjack
1
Eu estava tendo um problema com múltiplos caminhos no Android 5. Esquerda apenas um caminho, em vez de 2.
ODAXY
3
Recebi um relatório de falha (de 50 a 100 dispositivos, acho) idêntico a isso. <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="extfiles" path="."/> </paths>Foi path="."o que descobri em minha própria pesquisa para permanecer no nível superior. Se você examinar o FileProvider mais de perto, verá que o caminho lido no XML é canônico. Meu melhor palpite é que ContextCompat#getExternalFilesDirsretornou null @line 616 (v26.0.1), portanto, um PathStrategy não foi registrado. Isso ocorreu no dispositivo Huawei.
Androidguy 13/0318
10
Em vez de usar <external-files-path, tentei <external-path e funcionou.
Safeer
166

Isso pode resolver o problema de todos: todas as tags são adicionadas para que você não precise se preocupar com o caminho das pastas. Substitua res / xml / file_paths.xml por:

<?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>
Mitul Varmora
fonte
3
Melhor solução. Obrigado.
Pawan Pillai
1
Solução simples ... mas para isso brilhante! Eu usei um provedor, então entrei na possibilidade do usuário de alterar o diretório de destino ... nada funcionou mais porque nesse momento o provedor deve ser dinâmico ... você salvou meu dia!
Bronz
1
usou esta solução e o código começou a funcionar. Código desnecessário removido por meio de testes que um deles estava trabalhando
Kartik
1
Bro, você salvou meu dia. Thanks a lot :-)
manjunath kallannavar
1
Excelente funcionou para mim, como um novo aprendiz me fez perceber que eu não estava recebendo arquivos externos, mas cache
Tony Merritt
82

Problema semelhante após sabores ativados (dev, estágio).

Antes dos sabores, meu recurso de caminho era assim:

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

Depois de adicionado android: autoridades = "$ {applicationId} .fileprovider" no manifesto, o appId era pl.myapp.dev ou pl.myapp.stage depende do sabor e o aplicativo começou a falhar. Eu removi o caminho completo e o substituí por ponto e tudo começou a funcionar.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="." />
</paths>
antygravity
fonte
7
Trabalhou para mim. Obrigado! Como você criou '.' notação?
NightFury
2
@antygravity você pode fornecer referência / documentação desta solução?
geekoraul
7
Existem consequências negativas desta solução?
RediOne1
Trabalhou para mim, muito obrigado.
Hiren
Essa deve ser a resposta aceita! A única solução que funcionou
egorikem 5/06/19
43

Se você estiver usando cache interno, use.

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="/" />
</paths>
Inocente
fonte
3
obrigado, minha situação: quero instalar um aplicativo que salve em / data / data / pkg_name / files, para que meu correto configure da seguinte forma: <nome do caminho do arquivo = "files" path = "/" />
aolphn
25

Perdeu 2 semanas tentando encontrar alguma solução ... Se você chegar aqui depois de tentar tudo acima:

1 - Verifique se o seu provedor de tags está dentro do aplicativo de tags

<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 - Se você tentar muitos caminhos sem sucesso, teste com o seguinte:

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

Teste isso, se a câmera funcionar, comece a eliminar algumas linhas e continue testando ...

3 - Não esqueça de verificar se a câmera está ativada no seu emulador.

Diego Venâncio
fonte
1
Obrigado, isso funcionou para mim. É necessário remover outros caminhos?
CodeSlave
22

Tenho certeza de que estou atrasado para a festa, mas abaixo funcionou para mim.

<paths>
    <root-path name="root" path="." />
</paths>
espartano
fonte
Este foi o passo final para que meu código funcionasse também! Obrigado.
Dog Dogma
15

Isso também me confunde um pouco.

O problema está no atributo "caminho" no seu arquivo xml.

A partir deste documento, o FileProvider 'path' é um subdiretório, mas em outro documento (câmera / photobasics) mostrado 'path' é o caminho completo.

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

Eu apenas mudei esse 'caminho' para o caminho completo e funcionou.

Supakij
fonte
15

Estou atrasado, mas encontrei uma solução para ele. Funcionando bem para mim, acabei de alterar o arquivo XML de caminhos para:

 <?xml version="1.0" encoding="utf-8"?>
<paths>
    <root-path name="root" path="." />
</paths>
subbu
fonte
1
Para mim, isso provider_paths.xmlfornece um aviso de inspeção "O caminho raiz do elemento não é permitido aqui".
Luis A. Florit
15

Esteja ciente de que o caminho externo não está apontando para seu armazenamento secundário, também conhecido como "armazenamento removível" (apesar do nome "externo"). Se você está recebendo "Falha ao encontrar a raiz configurada", pode adicionar esta linha ao seu arquivo XML.

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

Veja mais detalhes aqui FileProvider e armazenamento externo secundário

Peter Shashkin
fonte
14

Verifique quantos armazenamentos o seu dispositivo oferece - o compartilhamento de arquivos do armazenamento secundário não é suportado. Veja a FileProvider.javafonte (de 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];
                }
            }

Portanto, eles levam apenas o primeiro armazenamento.

Além disso, você pode ver que getExternalCacheDirs()é usado para obter uma lista de armazenamentos por meio da ContextCompatinterface. Consulte a documentação para seus limites (é dito para não reconhecer USB Flashes, por exemplo). O melhor é fazer alguma saída de depuração da lista de armazenamentos dessa API por conta própria, para que você possa verificar se o caminho para o armazenamento corresponde ao caminho passado para ele getUriForFile().

Já existe um ticket atribuído (como em 06-2017) no rastreador de problemas do Google, solicitando suporte a mais de um armazenamento. Eventualmente, eu achei SO questão sobre isso também.

lef
fonte
1
Essa resposta detalhada deve estar recebendo mais votos positivos. Obrigado por pesquisar o que o FileProvider de armazenamento externo realmente reconhece.
LarsH
10

Passei 5 horas para isso ..

Eu tentei todos os métodos acima, mas isso depende do armazenamento do seu aplicativo atualmente em uso.

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

Verifique a documentação antes de tentar os códigos.

No meu caso, uma vez que o files-pathsubdiretório será Context.getFilesDir(). O interessante é que Context.getFilesDir()observa um outro subdiretório.

o que eu estou procurando é

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

Context.getFilesDir()

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

então a tag deve ser

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

Então funciona !!

Seho Park
fonte
1
Obrigado por consultar a documentação. Isso me levou à resposta correta. No meu caso o meu arquivo foi salvo com getExternalStorageDirectory()e eu era suposto fornecer o caminho com <external-path>tag em vez de<files-path>
alierdogan7
Obrigado por esta resposta específica no caminho dos arquivos. Ele ajudou muito. :)
arungiri_10 17/01
Sim funciona !!! o ponto principal é especificar o ".." no início do caminho, como este caminho = "../ myDirectory /"
Robert Apikyan
9

Nada disso funcionou para mim. A única abordagem que funciona é não declarar um caminho explícito no xml. Então faça isso e seja feliz:

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

Aqui também há um excelente tutorial sobre esta questão: https://www.youtube.com/watch?v=9ZxRTKvtfnY&t=613s

Paulo Linhares - Packapps
fonte
7

Meu problema foi que eu tinha nomes sobrepostos nos caminhos dos arquivos para diferentes tipos, como este:

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

Depois de alterar os nomes ("cached_files") para serem exclusivos, me livrei do erro. Meu palpite é que esses caminhos são armazenados em algum HashMap ou em algo que não permita duplicatas.

Perigo
fonte
3

O que eu fiz para resolver isso -

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 (permitindo que o FileProvider compartilhe todos os arquivos que estão dentro do diretório de arquivos externos do aplicativo)

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

e na classe java -

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

Isso funcionou para mim também. Em vez de dar o caminho completo, dei path = "Pictures" e funcionou bem.

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

Depende do tipo de armazenamento que você deseja fazer, INTERNO ou EXTERNO

para ARMAZENAMENTO EXTERNO

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

mas para ARMAZENAMENTO INTERNO, tenha cuidado com o caminho, porque ele usa o método getFilesDir (), o que significa que seu arquivo estará localizado no diretório raiz do aplicativo ("/")

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

Portanto, seu arquivo de provedor deve ser assim:

<paths>
    <files-path name="my_images" path="/" />
</paths>
Christian Altamirano Ayala
fonte
Todos os exemplos assumem que o usuário está usando armazenamento externo. Eu precisava de ajuda com o armazenamento interno e demorou horas para encontrar esta resposta. Obrigado.
zeeshan
2

nenhuma das opções acima funcionou para mim, depois de algumas horas de depuração, descobri que o problema está createImageFile(), especificamente absolute pathvsrelative path

Suponho que vocês estejam usando o guia oficial do Android para tirar uma foto. 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;
    }

Tome nota do storageDir, este é o local onde o arquivo será criado. Portanto, para obter o caminho absoluto desse arquivo, eu simplesmente o uso image.getAbsolutePath(), se esse onActivityResultfor o caso da imagem Bitmap depois de tirar uma foto

abaixo é o file_path.xml, basta usar .para que ele use o caminho absoluto

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

e se você precisar do bitmap depois de tirar uma foto

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();
        }
    }
grandia
fonte
2

Eu estava recebendo esse erro Failed to find configured root that contains...

A solução alternativa a seguir resolve meu problema

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)));
    }
Ali Tamoor
fonte
1

O documento oficial do Android diz que file_paths.xml deve ter:

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

Mas para fazê-lo funcionar no android mais recente, deve haver um "/" no final do caminho, assim:

<?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>
Shripad Bhat
fonte
1

A seguinte alteração no arquivo xml file_paths funcionou para mim.

 <external-files-path name="my_images" path="Pictures"/>
 <external-files-path name="my_movies" path="Movies"/>
Manmohan Soni
fonte
1

Eu tive o mesmo problema, tentei o código abaixo para o seu funcionamento.

1.Crie Xmlfile: provider_paths

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

2. Arquivo 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. No seu arquivo 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);
Suresh kumar
fonte
1

Se nada ajudar e você está recebendo o erro

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

então tente mudar alguma linha como:

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

para:

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

e no arquivo xml:

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

o que é estranho, já que a pasta que eu acesso é /images.

LivinTheNoobLife
fonte
Mudar de .getDir para .getFilesDir me ajudou. Obrigado!
Dmitriy Pavlukhin
1

Meu problema estava errado Nome do arquivo : Eu crio file_paths.xmlem res / xml enquanto o recurso foi definido como 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>

Mudei provider_pathspara file_pathse problema resolvido.

Saeed Arianmanesh
fonte
1

Se o caminho do seu arquivo for como / storage / emulated / 0 / "yourfile"

você só precisa modificar o XML do FileProvider

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

chame essa função quando precisar compartilhar arquivos

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

funciona no android M ~ Pie

preguiçoso
fonte
Funciona! Mas você pode explicar por que usamos path = "." em vez de path = "DCIM", "Imagens" ...?
Hoang Lam
@ Hoo Lam A diferença é se você precisa especificar um diretório, no meu exemplo, você pode acessar todos
preguiçoso
0

Vejo que pelo menos você não está fornecendo o mesmo caminho que os outros em file_paths.xml. Portanto, forneça exatamente o mesmo nome ou caminho do pacote em 3 locais, incluindo:

  • android:authorities atributo no manifesto
  • path atributo em file_paths.xml
  • authority argumento ao chamar FileProvider.getUriForFile ().
Pei
fonte
0
  • Para usuários do Xamarin.Android

Isso também pode resultar da não atualização dos pacotes de suporte ao segmentar o Android 7.1, 8.0+. Atualize-os para a v25.4.0.2 + e esse erro específico pode desaparecer (fornecendo o arquivo file_path configurado corretamente, conforme indicado por outros).


Contexto: mudei para direcionar o Oreo do Nougat em um aplicativo Xamarin.Forms e tirar uma foto com o Xam.Plugin.Media começou a falhar com a mensagem de erro acima, portanto, atualizar os pacotes fez o truque para mim, ok.

Ahmed Alejo
fonte
0

Percebi que a política ou o comportamento referente ao path.xmlarquivo mudou entre a Biblioteca de suporte 26 e 27. Para capturar uma foto da câmera, vi as seguintes alterações:

  • Com 26, eu tive que usar <external-path>e o caminho completo fornecido no pathargumento.

  • Com 27, tive que usar <external-files-path>e apenas a subpasta no pathargumento.

Então, o que funcionou especificamente para mim com a Biblioteca de suporte 27, como o path.xmlarquivo era

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

Olá amigos, tente isso

Neste Código

1) Como declarar 2 arquivos em manifesto.

2) Primeiro provedor para o download do arquivo

3) segundo provedor usado para câmera e galerias

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

Segundo Fornecedor

     <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

Criar classe MyFileProvider (apenas a classe Criar, nenhum método declara)

Quando você utilizou o File Provider (.fileprovider), esse nome e a imagem (.provider), esse nome.

Se houver algum problema para entender esse código, entre em contato com [email protected].

Rahul Patil
fonte
0

O problema pode não ser apenas o caminho xml.

A seguir, minha correção:

Examinando o curso raiz em 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);
        }

        // ...
    }

Isso significa que mRootsdeve conter a tag da uri solicitada. Então, escrevo um código para imprimir mRootse marcar uri e, em seguida, encontro facilmente as tags que não correspondem .

Acontece que definir a autoridade do provedor como ${applicationID}.provideruma ideia estúpida ! Essa autoridade é tão comum que pode ser usada por outros provedores, o que atrapalha a configuração do caminho!

thundertrick
fonte
-1

Você precisa alterar o arquivo xml file_paths.xml de

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

para

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <fexeternal-path name="my_images" path="Android/data/com.example.marek.myapplication/files/Pictures"/>
</paths>
Andrey
fonte
1
Embora você tenha copiado sua resposta de cima, ela não foi feita corretamente. Corrija a incompatibilidade de digitação na sua resposta.
Abhinav Saxena