我遵循了以下教程并修改了代码 https://medium.com/@egemenhamutcu/fixing-securityexception-requiring-a-valid-contentprovider-on-android-8-1110d840522
我在清单文件中定义了提供程序。
update tablex
set columnb = datefromparts(year(column_a),month(column_b), day(column_b))
这就是我定义权限的方式
<provider
android:name="com.test.PhotoProvider"
android:authorities="${applicationId}.PhotoProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
provider paths has the below line
<external-path name="/storage/emulated/0" path="/" />
I’m loading the uri using below code
Uri decodedImgUri = PhotoProvider.getPhotoUri(new File(imgPath));
ContentResolver cr = activity.getContentResolver();
cr.notifyChange(decodedImgUri, null);
ImageLoader.getInstance().displayImage(decodedImgUri.toString(), holder.image);
public static Uri getPhotoUri(File file) {
Uri outputUri = Uri.fromFile(file);
Uri.Builder builder = new Uri.Builder()
.authority(CONTENT_PROVIDER_AUTHORITY)
.scheme("file")
.path(outputUri.getPath())
.query(outputUri.getQuery())
.fragment(outputUri.getFragment());
return builder.build();
}
但是,当我尝试将uri加载到图像视图中时,我总是收到以下错误消息。
java.io.FileNotFoundException:com.test.PhotoProvider / data / user / 0 / com.test / cache / cropped953508219.jpg:打开失败:ENOENT(没有此类文件或目录)
甚至在<8.0版本上也会发生这种情况。
答案 0 :(得分:1)
我已经从该链接实现了,并且对我有用。
这是您的解决方案,创建一个名为PhotoProvider
的类,以扩展ContentProvider并自动实现其方法。声明一个静态的最终String来定义权限,最后实现一个静态方法以返回我们全新的Uri
。这是下面的整个课程:
public class PhotoProvider extends ContentProvider {
public static final String CONTENT_PROVIDER_AUTHORITY = "com.example.magnificentapp.PhotoProvider";
@Override
public boolean onCreate() {
return true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
return 0;
}
public static Uri getPhotoUri(File file) {
Uri outputUri = Uri.fromFile(file);
Uri.Builder builder = new Uri.Builder()
.authority(CONTENT_PROVIDER_AUTHORITY)
.scheme("file")
.path(outputUri.getPath())
.query(outputUri.getQuery())
.fragment(outputUri.getFragment());
return builder.build();
}
}
ContentProvider
权限由 CONTENT_PROVIDER_AUTHORITY 拥有。
不要忘记在 onCreate 方法中返回true。
最后getPhotoUri(File file)
方法成就了我们的一天。您没有像上面一样将File对象传递给方法,并使用fromFile(file)
获取Uri。然后,您必须使用Uri.Builder
并从我们非法的outputUri
复制必要的字段,最后将权限设置为 CONTENT_PROVIDER_AUTHORITY 。
除了设置自定义权限外,我实际上模仿了Uri.fromFile(file)
方法。原始方法类似于Uri类中的以下方法:
public static Uri fromFile(File file) {
if (file == null) {
throw new NullPointerException("file");
}
PathPart path = PathPart.fromDecoded(file.getAbsolutePath());
return new HierarchicalUri(
"file", Part.EMPTY, path, Part.NULL, Part.NULL);
}
此方法将权限设置为Part.EMPTY,因此Android Oreo崩溃,因为它必须具有未导出的ContentProvider
来定义所有Uris的权限。
设置权限可以解决此问题,并帮助Android保护您的数据(以我为例的照片)不泄漏给恶意应用程序。
不要忘记将提供程序添加到 AndroidManifest.xml :
<provider
android:name="com.example.magnificentapp.PhotoProvider"
android:authorities="com.example.magnificentapp.PhotoProvider"
android:exported="false"
android:grantUriPermissions="true" />
最后,您必须像下面这样呼叫PhotoProvider.getPhotoUri(file)
而不是Uri.fromFile(file)
:
outputUri = PhotoProvider.getPhotoUri(new File(activity.getCacheDir(), "cropped"));
ContentResolver cr = activity.getContentResolver();
cr.notifyChange(outputUri, null);
尝试一下- 开心编码:) :) :)
答案 1 :(得分:0)
试试这个... 清单
$permission1 = Permission::create(['name' => 'Create Client']);
$permission2 = Permission::create(['name' => 'View Invoice']);
$permission3 = Permission::create(['name' => 'Add Product']);
$role = Role::findById(1);
$role->givePermissionTo([$permission1, $permission2, $permission3]);
并在xml / provider_path文件中
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.xyz.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
希望这会有所帮助...!