Esta es una parte de mi manifiesto:
<?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>
Este es el archivo filepaths en 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>
Descargo un video de Internet y lo guardo en el almacenamiento interno de esta manera:
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;
}
}
Intento usarlo así:
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();
}
}
En esta línea:
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
Obtuve el siguiente error:
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)
Respuestas:
El problema era que en Manifiesto tenía esta línea:
y al llamar a getUriForFile estaba pasando:
Así que cambió de
"com.example.asd"
a"com.example.asd.fileprovider"
y funcionófuente
android:authorities="${applicationId}"
siempre; El código nunca tendrá la culpa.Puede hacer esto sin codificar el nombre del paquete con un beneficio adicional de ser capaz de ejecutar múltiples variantes en el mismo dispositivo (piensa
release
ydebug
conapplicationIdSuffix
, consulte estos temas ):Residencia en
FileProvider.java:560
estabas usando el error
authority
y no encontró elContentProvider
(info == null
).Cambie su manifiesto a (
${applicationId}
será reemplazado por Manifest Merger)y
El
.share
sufijo es opcional, en caso de que tenga un realContentProvider
que es mejor tener el nombre del paquete como autoridad.fuente
En mi caso, recibí el error porque el
estaba siendo importado de
Entonces, la cadena que devolvió fue en
"android.support.v4"
lugar del nombre del paquete de mi proyecto. Verifique que el archivo de importación sea de ustedimport project.Buildconfig
y no de otro. Ejemplo:Finalmente, en la
<provider>
etiqueta en Manifiesto,android:authorities="${applicationId}"
siempre tengo que obtener el nombre del paquete de mi proyecto como autoridadfuente
Primero, asegúrese de que su proveedor
android:authorities
no entre en conflicto con sus otros proveedores. Además de eso, puede elegir cualquier nombre para la última parte de su nombre: "proveedor", "proveedor de archivos", etc., pero la aplicación se bloquea cuando hay más de uno en laandroid:authorities
lista, mientras que la documentación indica que permite múltiples valores en la lista.file://
ahora no se permite adjuntar el esquema con Intent en targetSdkVersion> = 24 (Android N 7.0), solocontent://
se pasa siempre para todos los dispositivos (Android 5, 6 y 7). Pero descubrimos que Xiaomi rompe esta convención de Google y envíafile://
, por lo tanto,data.getData().getAuthority()
da una cadena vacía.Además, el error cuando se
FileProvider.getUriForFile()
produjo un bloqueojava.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example/files/attachments/image.jpg
se corrigió en Android Support Library v24.2.0. El problema era que FileProvider.java no veía carpetas de ruta externa.fuente
Si está creando su AUTORIDAD en tiempo de ejecución utilizando,
BuildConfig
asegúrese de utilizar el nombre completo de la clase, incluido el nombre del paquete.Malo:
final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
Bueno:
final String AUTHORITY = com.mycompany.myapp.BuildConfig.APPLICATION_ID + ".provider";
fuente
Lo siguiente funcionó para mí.
fuente
Esto es lo que hice para solucionar el problema. Di nombre completo en Android: nombre. Funciona en android 6,7,8
fuente
Deberías probarlo:
fuente
Esto es lo que necesitas hacer:
fuente