Esta é uma parte do meu manifesto:
<?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 é o arquivo de caminhos de arquivo em 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>
Faço o download de um vídeo da Internet e o salvo no armazenamento interno desta maneira:
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;
}
}
Eu tento usá-lo assim:
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();
}
}
Nesta linha:
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
Estou tendo o erro a seguir:
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)
Respostas:
O problema era que no Manifest eu tinha essa linha:
e ao chamar getUriForFile eu estava passando:
Então mudou de
"com.example.asd"
para"com.example.asd.fileprovider"
e funcionoufonte
android:authorities="${applicationId}"
sempre; código nunca estará com defeito.Você pode fazer isso sem codificar o nome do pacote com um benefício adicional de poder executar várias variantes no mesmo dispositivo (pense
release
edebug
comapplicationIdSuffix
, veja estes problemas ):Baseado em
FileProvider.java:560
você estava usando o errado
authority
e ele não encontrou oContentProvider
(info == null
).Alterar seu manifesto para (
${applicationId}
será substituído por Manifest Merger)e
O
.share
sufixo é opcional, caso você tenha um real,ContentProvider
é melhor ter o nome do pacote como autoridade.fonte
No meu caso, recebi o erro porque o
estava sendo importado de
Portanto, a string retornada foi
"android.support.v4"
substituída pelo nome do pacote do meu projeto. Verifique se o arquivo de importação é do seuimport project.Buildconfig
e não de outro. Exemplo:Por fim, na
<provider>
tag Manifest,android:authorities="${applicationId}"
sempre tenho que obter o nome do pacote do meu projeto como autoridadefonte
Primeiro, verifique se o seu provedor
android:authorities
não entra em conflito com seus outros fornecedores. Além disso, você pode escolher qualquer nome para a última parte do nome: "provider", "fileprovider" etc. etc., mas o aplicativo trava quando há mais de umandroid:authorities
listado, enquanto a documentação afirma que permite vários valores listados.file://
Agora, o esquema não pode ser anexado ao Intent no targetSdkVersion> = 24 (Android N 7.0), mascontent://
sempre é passado para todos os dispositivos (Android 5, 6 e 7). Mas descobrimos que a Xiaomi quebra essa convenção do Google e enviafile://
, portanto,data.getData().getAuthority()
fornece uma string vazia.Além disso, o bug quando
FileProvider.getUriForFile()
resultou em falhajava.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example/files/attachments/image.jpg
foi corrigido na Android Support Library v24.2.0. O problema foi que o FileProvider.java não viu as pastas de caminho externo.fonte
Se você estiver construindo sua AUTHORITY em tempo de execução,
BuildConfig
use o nome completo da classe, incluindo o nome do pacote.Ruim:
final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
Boa:
final String AUTHORITY = com.mycompany.myapp.BuildConfig.APPLICATION_ID + ".provider";
fonte
A seguir funcionou para mim.
fonte
Aqui está o que eu fiz para corrigir o problema. Eu dei o nome completo no android: name. Funciona no Android 6,7,8
fonte
Você deveria tentar:
fonte
Isso é o que você precisa fazer:
fonte