问题描述
我发布了应用“A”。现在我准备发布应用程序“B”,它应该从应用程序“A”加载副本数据库,以便用户继续写入数据。
来自应用程序“A”的此代码将数据库从内部存储保存到作用域存储上的文件:
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.disPLAY_NAME,"/databasename.db");
values.put(MediaStore.MediaColumns.MIME_TYPE,"application/vnd.sqlite3");
values.put(MediaStore.MediaColumns.RELATIVE_PATH,DIRECTORY_DOWNLOADS);
Uri uri = getContentResolver().insert(MediaStore.Files.getContentUri("external"),values);
if (uri != null) {
OutputStream outputStream = getContentResolver().openOutputStream(uri);
if (outputStream != null) {
outputStream.write("This is menu category data.".getBytes());
outputStream.close();
Toast.makeText(ActivitySettings.this,"File created successfully",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ActivitySettings.this,"outputStream == null",Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(ActivitySettings.this,"uri == null",Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
Toast.makeText(ActivitySettings.this,"Fail to create file",Toast.LENGTH_SHORT).show();
}
应用“B”中的这段代码应该上传应用“A”中保存的数据库文件:
try {
File sd = Environment.getDataDirectory();
File data = Environment.getStorageDirectory();
try {
String currentDBPath = "emulated/0/" + DIRECTORY_DOWNLOADS + "/databasename.db";
String backupDBPath = "/data/com.example.mypackagename/databases/databasename.db";
File currentDB = new File(data,currentDBPath);
File backupDB = new File(sd,backupDBPath);
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src,src.size());
src.close();
dst.close();
Toast.makeText(this,R.string.toast_db_loaded_succesfully,Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,R.string.toast_db_not_exists,Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(this,R.string.toast_not_access,Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Log.e("DBError","exception",e);
Toast.makeText(this,R.string.toast_error_load_db,Toast.LENGTH_LONG).show();
}
它在 Android 10 及更低版本上也能正常工作,但由于 Android 11 范围存储的新访问规则而无法使用。如果获得 MANAGE_EXTERNAL_STORAGE 许可,这是可能的,但在我的情况下,Google 可能会拒绝应用“B”由于违反政策。
SharedUserId 已弃用
Sharing files 通过 FileProvider 由带有 UI 和其他用户操作的 Activity 执行。
但我需要一种无需任何额外操作的方法,只需从应用程序“B”一键加载数据库。可以在 Android 11 上使用吗?也许有 SharedUserId 的替代方案?
任何帮助/想法。 谢谢。
解决方法
从安全角度来看,新的安全要求是一个受欢迎的变化。
最好的解决方案是向现有应用 A 发送升级,以将数据发送到应用 B 可访问的外部端点。
在未经应用 B 许可的情况下让应用 A 修改应用 B 数据是违反安全协议的行为,绝不应被允许。
除非您同时是应用 A 和应用 B 的所有者,否则您所要求的事情是不可能的,也不应该被允许发生。