FileProviderのの罠

FileProvider.java

if (TAG_EXTERNAL_CACHE.equals(tag)) {
    File[] externalCacheDirs = ContextCompat.getExternalCacheDirs(context);
    if (externalCacheDirs.length > 0) {
        target = externalCacheDirs[0];
    }
}

file_paths.xml に設定された external-cache-path の情報を登録するとき、getExternalCacheDirs()[0] を登録している。
通常は getExternalCacheDir() == getExternalCacheDirs()[0] だけど...

端末にSDカードがささっていて、デフォルトの保存先の設定(よくわからんけどHuaweiの端末にはある)が「SDカード」に設定されていてると、getExternalCacheDir() の値は getExternalCacheDirs()[1] の値になる。
なので getExternalCacheDir() で取得したパスで FileProvider#getUriForFile() を呼び出すと、

Caused by java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/0123-4567/Android/data/com.example.externalcachedirtest/cache/file.tmp

となる。


まとめ。

getExternalCacheDirs()[0]: /storage/emulated/0/Android/data/jp.syoboi.externalcachedirtest/cache
getExternalCacheDirs()[1]: /storage/C8F7-13FD/Android/data/jp.syoboi.externalcachedirtest/cache

で、デフォルトの内部ストレージだと

getExternalCacheDir(): /storage/emulated/0/Android/data/jp.syoboi.externalcachedirtest/cache

保存先がSDカードだと

getExternalCacheDir(): /storage/C8F7-13FD/Android/data/jp.syoboi.externalcachedirtest/cache

external-cache-dir は getExternalCacheDirs()[0]


これは com.android.support:support-v4:26.1.0 での話。