微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Android 11 上将数据库从我的应用程序“A”复制到我的应用程序“B”

如何解决在 Android 11 上将数据库从我的应用程序“A”复制到我的应用程序“B”

我发布了应用“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 的所有者,否则您所要求的事情是不可能的,也不应该被允许发生。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。