Ini adalah bagian dari manifes saya:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.asd"
android:versionCode="118"
android:versionName="118" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<application
android:name="com.example.asd.AsdApplication"
android:allowBackup="true"
android:allowTaskReparenting="true"
android:theme="@style/AsdTheme" >
...
<provider
android:name="com.example.asd.database.hq.ContentProviderDB"
android:authorities="ourContentProviderAuthorities" >
</provider>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.asd.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
...
</application>
</manifest>
Ini adalah file filepaths di raw / xml / filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="media"/>
</paths>
Saya mengunduh video dari internet dan menyimpannya ke penyimpanan internal dengan cara ini:
public static boolean saveInputStreamToInternalStorageFile(Context context, String filename, byte[] dataToWrite, Context ctx) {
FileOutputStream fos;
try {
fos = new FileOutputStream(context.getFilesDir() + File.separator + filename);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(dataToWrite);
oos.close();
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
Saya mencoba menggunakannya seperti ini:
private void playVideoFromDeviceWithWorkaround(String fileName) {
File newFile = new File(getFilesDir(), fileName);
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
try {
vvVideoFullscreen.setVideoURI(contentUri);
showMediaControls = true;
playVideo();
} catch (Exception e) {
playVideoFromNetwork();
}
}
Di baris ini:
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
Saya mendapatkan kesalahan berikut:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:560)
at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:534)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:376)
Jawaban:
Masalahnya adalah bahwa dalam Manifest saya memiliki baris ini:
dan ketika memanggil getUriForFile saya melewati:
Jadi berubah dari
"com.example.asd"
ke"com.example.asd.fileprovider"
dan berhasilsumber
android:authorities="${applicationId}"
always; kode tidak akan pernah salah.Anda dapat melakukan ini tanpa hardcoding nama paket dengan manfaat tambahan untuk dapat menjalankan beberapa varian pada perangkat yang sama (pikirkan
release
dandebug
denganapplicationIdSuffix
, lihat masalah ini ):Berdasarkan
FileProvider.java:560
Anda menggunakan yang salah
authority
dan tidak menemukanContentProvider
(info == null
).Ubah manifes Anda menjadi (
${applicationId}
akan digantikan oleh Manifest Merger)dan
The
.share
akhiran adalah opsional, jika anda memiliki nyataContentProvider
yang lebih baik untuk memiliki nama paket sebagai otoritas.sumber
Dalam kasus saya, saya mendapat kesalahan karena
sedang diimpor dari
Jadi string yang dikembalikannya
"android.support.v4"
bukan nama paket proyek saya. Lihat file impor dari Andaimport project.Buildconfig
dan bukan yang lain. Contoh:Akhirnya, dalam
<provider>
tag di Manifest saya harusandroid:authorities="${applicationId}"
selalu mendapatkan nama paket proyek saya sebagai otoritassumber
Pertama, pastikan penyedia
android:authorities
Anda tidak bertentangan dengan penyedia lainnya. Selain itu, Anda dapat memilih nama untuk bagian terakhir namanya: "provider", "fileprovider" dll., Tetapi aplikasi macet ketika ada lebih dari satu yangandroid:authorities
terdaftar, sementara dokumentasi menyatakan bahwa itu memungkinkan beberapa nilai terdaftar.file://
Skema sekarang tidak diizinkan untuk dilampirkan dengan Intent on targetSdkVersion> = 24 (Android N 7.0), hanyacontent://
selalu dilewati untuk semua perangkat (Android 5, 6 dan 7). Tetapi kami menemukan bahwa Xiaomi melanggar konvensi dan pengiriman Google inifile://
, karenanyadata.getData().getAuthority()
memberikan string kosong.Juga, bug saat
FileProvider.getUriForFile()
mengakibatkan kerusakanjava.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example/files/attachments/image.jpg
diperbaiki di Android Support Library v24.2.0. Masalahnya adalah bahwa FileProvider.java tidak melihat folder jalur eksternal.sumber
Jika Anda membangun OTORITAS saat runtime menggunakan,
BuildConfig
pastikan Anda menggunakan nama kelas lengkap termasuk nama paket Anda.Buruk:
final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
Baik:
final String AUTHORITY = com.mycompany.myapp.BuildConfig.APPLICATION_ID + ".provider";
sumber
Mengikuti berhasil untuk saya.
sumber
Inilah yang saya lakukan untuk memperbaiki masalah ini. Saya memberikan nama yang sepenuhnya memenuhi syarat di android: name. Ini bekerja di Android 6,7,8
sumber
Kamu harus mencobanya:
sumber
Ini adalah hal yang perlu kamu lakukan:
sumber