Dies ist ein Teil meines Manifests:
<?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>
Dies ist die Dateipfaddatei in 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>
Ich lade ein Video aus dem Internet herunter und speichere es folgendermaßen im internen Speicher:
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;
}
}
Ich versuche es so zu benutzen:
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();
}
}
In dieser Zeile:
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
Ich erhalte folgende Fehlermeldung:
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)
Antworten:
Das Problem war, dass ich in Manifest diese Zeile hatte:
und als ich getUriForFile aufrief, ging ich vorbei:
Also wechselte von
"com.example.asd"
zu"com.example.asd.fileprovider"
und es funktioniertequelle
android:authorities="${applicationId}"
immer verwenden. Code wird niemals schuld sein.Sie können dies zu tun , die Paketnamen mit einem zusätzlichen Nutzen von mehreren Varianten auf demselben Gerät (denken Sie laufen zu können , ohne hartzucodieren
release
unddebug
mitapplicationIdSuffix
, sieht diese Probleme ):Beyogen auf
FileProvider.java:560
Sie haben das falsche verwendet
authority
und es hat dasContentProvider
(info == null
) nicht gefunden.Ändern Sie Ihr Manifest in (
${applicationId}
wird durch Manifest Merger ersetzt)und
Das
.share
Suffix ist optional, falls Sie ein Real haben,ContentProvider
das besser den Paketnamen als Autorität hat.quelle
In meinem Fall habe ich den Fehler bekommen, weil die
wurde aus importiert
Die zurückgegebene Zeichenfolge war also
"android.support.v4"
anstelle meines Projektpaketnamens. Überprüfen Sie, ob die Importdatei von Ihrerimport project.Buildconfig
und nicht von einer anderen stammt. Beispiel:Schließlich muss
<provider>
ich im Tag in Manifestandroid:authorities="${applicationId}"
immer meinen Projektpaketnamen als Autorität erhaltenquelle
Stellen Sie zunächst sicher, dass Ihr Anbieter
android:authorities
nicht mit Ihren anderen Anbietern in Konflikt steht. Außerdem können Sie einen beliebigen Namen für den letzten Teil des Namens auswählen: "Provider", "Fileprovider" usw. Die App stürzt jedoch ab, wenn mehrereandroid:authorities
aufgeführt sind. In der Dokumentation wird angegeben, dass mehrere Werte aufgelistet werden dürfen.file://
Das Schema darf jetzt nicht mit Intent auf targetSdkVersion> = 24 (Android N 7.0) angehängt werden, sonderncontent://
wird immer nur für alle Geräte (Android 5, 6 und 7) übergeben. Wir haben jedoch festgestellt, dass Xiaomi gegen diese Google-Konvention verstößt und sendetfile://
und daherdata.getData().getAuthority()
eine leere Zeichenfolge angibt.Außerdem wurde der Fehler, der zum
FileProvider.getUriForFile()
Absturzjava.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example/files/attachments/image.jpg
führte, in der Android Support Library v24.2.0 behoben. Das Problem war, dass FileProvider.java keine Ordner mit externen Pfaden sah.quelle
Wenn Sie Ihre AUTHORITY zur Laufzeit mit
BuildConfig
erstellen , stellen Sie sicher, dass Sie den vollständigen Klassennamen einschließlich Ihres Paketnamens verwenden.Schlecht:
final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
Gut:
final String AUTHORITY = com.mycompany.myapp.BuildConfig.APPLICATION_ID + ".provider";
quelle
Das Folgende hat bei mir funktioniert.
quelle
Hier ist, was ich getan habe, um das Problem zu beheben. Ich gab voll qualifizierten Namen in Android: Name. Es funktioniert in Android 6,7,8
quelle
Du solltest es versuchen:
quelle
Folgendes müssen Sie tun:
quelle