【问题标题】:Create folder and store file in android 11在android 11中创建文件夹并存储文件
【发布时间】:2021-11-24 16:39:33
【问题描述】:

我正在开发一个使用 SQLite 数据库存储调查数据的 Android 应用。

问题:对于 Android 10 及以上版本的设备,我无法在某些文件夹中存储 SQLite 数据库的备份副本,即使卸载应用程序也不会被删除

对于 Android 10 之前的设备,它可以使用以下代码正常工作:

 folder = Environment.getExternalStoragePublicDirectory("Db_Backup");// Folder Name

 if (!folder.exists())
    folder.mkdirs(); //Db_Backup folder gets created

对于 Android 版本 11 的设备,它无法正常工作

对于 android 10 和 11 设备,我尝试使用如下代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
   Files[] files=getExternalFilesDirs(Environment.DIRECTORY_DOWNLOADS);
   folder=files[0]; 
   // OR
   folder = getFilesDir();

   if (!folder.exists())
      folder.mkdirs(); // Db_Backup folder is created in app directory 
   ......
}

上面的代码只为android/data/com.example.packagename/files/backup/{filename.db}这个位置创建一个备份副本

问题:当应用程序被卸载或应用程序数据被清除时,.db 备份文件也会被删除或清除

我正在使用的

exportDatabaseNew() 函数如下:

    private void exportDatabaseNew(LinearLayout linearLayout) {

    FileOutputStream output = null;
    try {
        File dbFile = getDatabasePath(DatabaseHelper.DATABASE_NAME);
        FileInputStream fis = new FileInputStream(dbFile);
        File[] files;
        File folder = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            files=getExternalFilesDirs("Db_Backup");
            folder=files[0];
            Log.i("export", "exportDatabaseNew: " + folder.getAbsolutePath());
        } else {
            folder = Environment.getExternalStoragePublicDirectory("Db_Backup");//Folder Name
            Log.i("export", "exportDatabaseNew: " + folder.getAbsolutePath());
        }

        if (!folder.exists())
            folder.mkdirs();

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
        String currentDate = df.format(new Date());
     
        String backupName = "Survey_" + currentDate + ".db";

        File myFile = new File(folder, backupName);// Filename

        output = new FileOutputStream(myFile);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = fis.read(buffer)) > 0) {
            output.write(buffer, 0, length);
        }
        // Close the streams
        output.flush();
        output.close();
        fis.close();
      
        Snackbar.make(linearLayout, R.string.backup_complete, Snackbar.LENGTH_LONG)
                .show();
    } catch (Exception e) {
        e.printStackTrace();

    } finally {
        if (output != null) {
            try {
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

【问题讨论】:

  • Environment.getExternalStoragePublicDirectory("Db_Backup"); 'Db_Backup' 不是公共外部文件夹,因此不能用作那里的参数。以 Environment.DIRECTORY_DOCUMENTS 为例。
  • 你整理好了吗?我发现在 Android 11 中备份/导出/导入一个简单的 .db 文件并让用户在卸载/重新安装应用程序时访问它是多么困难。

标签: android android-sqlite database-backups android-10.0 android-11


【解决方案1】:

在公共文档目录中创建您自己的文件夹并将您的文件写入该文件夹。

【讨论】:

    【解决方案2】:

    对于 Android 11,您必须:

    1. 将文件保存在您的应用程序目录中
    2. 将文件保存到公共目录中
    3. 如果你真的必须,任何其他不是不同应用目录的位置,它需要以下权限:

    此权限仅适用于 android 11 及更高版本。请注意,如果您希望在 Google Play 商店上发布您的应用,您需要提供一个充分的理由说明您需要此权限,并且您不愿意简单地将其存储为应用文件的一部分。

    【讨论】:

    • re: 2. 我发现如果您将文件保存在公共文件夹(例如 Documents)中,如果您在面向 API 30 时卸载并重新安装您的应用程序,您将无法再访问它们。我尝试遵循开发指导使用意图获取权限,但我还没有设法让它工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-17
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多