FileProvider - IllegalArgumentException: Yapılandırılmış kök bulunamadı

Fotoğraf makinesiyle bir fotoğraf çekmeye çalışıyorum, ancak aşağıdaki hatayı alıyorum:

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>

Bütün gün bu hata hakkında araştırma yaptım ve FileProviderı anlamaya çalıştım, ancak bu hata mesajının bana ne anlatmaya çalıştığı hakkında hiçbir fikrim yok. Eğer daha fazla bilgi/kod istiyorsanız, bana yorum olarak yazın.

Çözüm

Dosyanız getExternalFilesDir() altında saklanır. Bu `

Yorumlar (16)

Bu benim de biraz kafamı karıştırıyor.

Sorun xml dosyanızdaki "path" niteliğindedir.

Bu belgeden FileProvider 'path' bir alt dizindir, ancak başka bir belgede (kamera/fotobasik) gösterilen 'path' tam yoldur.

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

Sadece bu 'yolu' tam yol olarak değiştiriyorum ve çalışıyor.

Yorumlar (0)

Cihazınızın kaç depolama alanı sunduğunu kontrol edin - ikincil depolamadan dosya paylaşımı desteklenmez. FileProvider.java` kaynağına bakın (support-core-utils 25.3.1'den):

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

Bu yüzden sadece ilk depoyu alırlar.

Ayrıca, getExternalCacheDirs()in ContextCompat arayüzü aracılığıyla depoların listesini elde etmek için kullanıldığını görebilirsiniz. Sınırları için documentation'ya bakın (örneğin USB Flash'ları tanımadığı söylenir). En iyisi, bu API'den depolama listesinin bazı hata ayıklama çıktılarını kendiniz yapmaktır, böylece depolamaya giden yolun getUriForFile()a aktarılan yolla eşleşip eşleşmediğini kontrol edebilirsiniz.

Google'ın sorun izleyicisinde birden fazla depolama alanını desteklemeyi isteyen bir bilet atanmış (06-2017 için) zaten var. Sonunda, SO question on this adresini de buldum.

Yorumlar (1)