这是我的清单的一部分:
<?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>
这是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>
我从互联网上下载视频并以这种方式将其保存到内部存储:
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;
}
}
我试着像这样使用它:
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();
}
}
在这一行:
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
我收到以下错误:
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)
答案 0 :(得分:228)
问题是在Manifest中我有这条线:
android:authorities="com.example.asd.fileprovider"
当调用getUriForFile时,我正在传递:
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
已从"com.example.asd"
更改为"com.example.asd.fileprovider"
并且有效
答案 1 :(得分:38)
您可以在不对软件包名称进行硬编码的情况下执行此操作,还可以在同一台设备上运行多个变体(请release
和debug
与applicationIdSuffix
一起使用,请参阅{{ 3}}):
基于FileProvider.java:560
final ProviderInfo info = context.getPackageManager()
.resolveContentProvider(authority, PackageManager.GET_META_DATA);
final XmlResourceParser in = info.loadXmlMetaData( //560
context.getPackageManager(), META_DATA_FILE_PROVIDER_PATHS);
您使用的是错误的authority
,但未找到ContentProvider
(info == null
)。
将您的清单更改为(${applicationId}
将由Manifest Merger取代)
android:authorities="${applicationId}.share"
和
Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".share", result);
.share
后缀是可选的,如果你有一个真正的ContentProvider
,最好将包名作为权限。
答案 2 :(得分:21)
在我的情况下,我得到了错误,因为
BuildConfig.APPLICATION_ID
正在从
导入import android.support.v4.BuildConfig;
因此它返回的字符串是"android.support.v4"
而不是我的项目包名称。检查导入文件来自import project.Buildconfig
,而不是另一个。{1}}。例如:
import com.example.yourProjectName.BuildConfig;
最后,在Manifest中的<provider>
标记中,android:authorities="${applicationId}"
总是将我的项目包名称作为权限
<manifest>
..
..
<application>
..
..
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/ruta_fileprovider" />
</provider>
</application>
</manifest>
答案 3 :(得分:5)
首先,请确保提供商android:authorities
与其他提供商不冲突。除此之外,您可以为其名称的最后部分选择任何名称:&#34; provider&#34;,&#34; fileprovider&#34;等,但是当列出多个android:authorities
时应用程序崩溃,而文档说明它允许列出多个值。
file://
方案现在不允许在targetSdkVersion&gt; = 24(Android N 7.0)上附加Intent,所有设备(Android 5,6和7)始终只传递content://
。但我们遇到小米打破了这个Google约定并发送file://
,因此data.getData().getAuthority()
给出了空字符串。
final String uriScheme = currentUri.getScheme();
if ("content".equals(uriScheme)) {
// getting full file path (works with some providers, i.e. Gallery)
path = FileUtils.getPath(getContext(), currentUri);
if (path != null) {
currentFile = new File(path);
}
} else if ("file".equals(uriScheme)) {
// in a rare case we received file:// in currentUri, we need to:
// 1. create new File variable from currentUri that looks like "file:///storage/emulated/0/download/50044382b.jpg"
// 2. generate a proper content:// Uri for it
currentFile = new File(currentUri.getPath());
String authority = data.getData().getAuthority();
if (authority != null && !authority.isEmpty()) {
currentUri = FileProvider.getUriForFile(getActivity(), authority, currentFile);
}
} else {
// throw exception
}
此外,Android FileProvider.getUriForFile()
导致崩溃java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example/files/attachments/image.jpg
的错误已在Android支持资源库v24.2.0中修复。问题是FileProvider.java没有看到外部路径文件夹。
答案 4 :(得分:1)
如果您在运行时使用BuildConfig
构建AUTHORITY,请确保使用完整的类名,包括您的包名。
为:
final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";
好:
final String AUTHORITY = com.mycompany.myapp.BuildConfig.APPLICATION_ID + ".provider";
答案 5 :(得分:0)
以下为我工作。
mUri = FileProvider.getUriForFile(this,
BuildConfig.APPLICATION_ID + ".provider",
fileObject);
答案 6 :(得分:0)
这是我为解决此问题所做的工作。我在android:name中给出了完全限定的名称。它可以在android 6,7,8中运行
<provider android:authorities="${applicationId}.opener.provider"
android:exported="false" android:grantUriPermissions="true"
android:name="io.github.pwlin.cordova.plugins.fileopener2.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
</provider>
答案 7 :(得分:0)
您应该尝试:
Context context = PostAdapter.this.activity;
StringBuilder stringBuilder2 = new StringBuilder();
stringBuilder2.append(PostAdapter.this.activity.getPackageName());
stringBuilder2.append(".provider");
Uri uri;
uri = FileProvider.getUriForFile(context,stringBuilder2.toString(), newFile);
答案 8 :(得分:0)
这是您需要做的:
Uri fileURI = FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".fileprovider", file);