问题描述
有人可以帮助我了解这有什么问题。
我有 2 个应用程序(服务器和客户端)。我拥有这两个应用程序,它们具有相同的签名。客户端需要从服务器读取一些文件,我想用 FileProvider 来做。
//服务器端
<permission
android:name="${package_name_lite}.permission.FILE_PROVIDER.READ"
android:description="@string/fp_permission_description"
android:icon="@drawable/ic_forward_24dp"
android:label="File provider permission"
android:permissionGroup="Manifest.permission_group.STORAGE"
android:protectionLevel="signature" />
<provider
android:name="provider.fileProvider.FileProvider"
android:authorities="${package_name_lite}.file.provider"
android:enabled="true"
android:exported="false"
android:grantUriPermissions="true"
android:permission="${package_name_lite}.permission.FILE_PROVIDER.READ">
<Meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
//客户端
<uses-permission android:name="${package_name_lite}.permission.FILE_PROVIDER.READ"/>
我的客户知道 uri 路径,我不想问他们任何意图。无论我的服务器能够提供什么,我的客户端都有办法完全了解 uri 路径。 Si 我像这样构建它们
Uri uri = Uri.parse("content://" + AUTHORITY + myPath);
我的问题从这里开始,如果我尝试使用这个非常好的 uri,我会遇到安全问题。
1- 我的客户如何获得我的 uri 获得的表单解析字符串的许可?
2- android:grantUriPermissions="false" -> 我不想向所有人授予权限,我希望这个 FileProvider 只在我的 2 个应用程序之间工作。但是如果我把它设置为 false,应用程序将无法编译
所以总结一下:如何在两个拥有相同签名的应用程序之间使用 FileProvider,以防止任何不需要的访问权限签名,并且不需要请求 Uri 意图?
谢谢,任何帮助将不胜感激
解决方法
所以最后,这很容易做到。如果您需要将输入流文件从一个应用程序打开到您拥有的另一个应用程序(两者)。不要打扰 FileProvider。你只需要使用 ContentProvider 的东西。
只需使用保护您的东西所需的自定义权限设置您的清单
然后在 ContentProvider 中,您只需覆盖 1 个方法。
@Nullable
@Override
public ParcelFileDescriptor openFile(@NonNull Uri uri,@NonNull String mode) throws FileNotFoundException{
String link = uri.getLastPathSegment();
File file = File.from(link);
if(!file.exists()){
throw new FileNotFoundException("no file found for " + link);
}
else {
return ParcelFileDescriptor.open(file.getFile(),ParcelFileDescriptor.MODE_READ_ONLY);
}
}
然后在您需要打开流的应用程序旁边:
Uri uri = new Uri.Builder()
.authority(AUTHORITY)
.scheme(SCHEME_CONTENT)
.appendEncodedPath(file.toLinkString())
.build();
resolver.openInputStream(uri );
ps:file.toLinkString() 和 File.fromLink(...) 是个人方法,它们将路径转换为类似“@:PRIVATE_DATA_FILE:#:test:png”的路径,您可以使用普通路径或使用任何其他路径你要。不需要遵守任何规定,因为授权使您能够访问您的服务器应用程序。