【问题标题】:android keep database after uninstalling appandroid在卸载应用程序后保留数据库
【发布时间】:2014-03-27 13:53:02
【问题描述】:

我正在开发一个 sq-lite 数据库,我可以在其中找到三星设备中的问题。当我卸载应用程序时,android 操作系统会保留导致数据库版本冲突的数据库 - 以前我使用版本 2,现在我使用版本 1 作为 sqllitehelper 构造函数中的参数。按照惯例,卸载应用时,Android 操作系统会删除所有数据库、共享首选项和缓存文件。

我在 app 文件夹中使用了数据库存储的默认位置。

这是我得到的错误:

Caused by: android.database.sqlite.SQLiteException: Can't downgrade database from version 2 to 1

【问题讨论】:

  • 你传递给ctor的数据库路径是什么?
  • DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); }
  • 你不能将你的数据库版本降级到更低的版本,即2到1。如果你的数据库结构有任何变化,请始终增加数据库版本
  • 我知道我们不能降级数据库版本,但我卸载应用程序然后降级版本然后出现此错误
  • 在卸载前删除数据库文件并清除数据。除非你删除并清除数据 android 保留数据库文件和共享首选项即使在卸载应用程序后

标签: android sqlite sharedpreferences


【解决方案1】:

SQlite 数据库只是文件,它们被视为任何其他文件:它们(默认情况下)存储在应用程序的私有数据区域(/data/data/$PACKAGENAME/databases)中。它们与应用程序私有数据区域中的所有其他内容一起被删除。

您可以根据需要在 SD 卡上创建数据库。当然,它们不会在卸载时被删除。

【讨论】:

    【解决方案2】:

    解决方案是将便携式Sqlite 文件从其目录备份到SD-Card 目录。您可以按照以下步骤执行此操作:-

    1) 将此permission 添加到您的Manifest.XML 文件中:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    2)Java 类中调用以下方法:

    public boolean packupDatabaseFile(){
        try {
            File sdCardDir = Environment.getExternalStorageDirectory();
            File dataDir = Environment.getDataDirectory();
    
            if (sdCard.canWrite()) {
                String dbPath = "//data//{your package name}//databases//{your database name}";
                String backupDBPath = "{database name}";
                File dbFile = new File(dataDir , currentDBPath);
                File backupDbFile = new File(sdCardDir , backupDBPath);
    
                if (currentDB.exists()) {
                    FileChannel src = new FileInputStream(dbFile ).getChannel();
                    FileChannel dst = new FileOutputStream(backupDbFile ).getChannel();
                    dst.transferFrom(src, 0, src.size());
                    src.close();
                    dst.close();
                }
            }
        return true;//Success
        } catch (Exception e) {
        return false;//Failed to backup
        }
    }
    

    借助这个Question

    【讨论】:

      【解决方案3】:

      您可以使用以下方法在 SDCard 上备份您的数据库:

      public void writeToSDCard() throws IOException {
          File f=new File("/data/data/com.YourPackage/databases/YourDB");
          FileInputStream fis=null;
          FileOutputStream fos=null;
          try{
              fis=new FileInputStream(f);
              fos=new FileOutputStream("/mnt/sdcard/backup.db");
              while(true){
                  int i=fis.read();
                  if(i!=-1){
                      fos.write(i);
                  }
                  else{
                      break;
                  }
              }
              fos.flush();
          }
          catch(Exception e){
              e.printStackTrace();
          }
          finally{
              try{
                  fos.close();
                  fis.close();
              }
              catch(IOException ioe){
                  System.out.println(ioe);
              }
          }
      } 
      

      【讨论】:

      • 你最终可能会得到一个 NPE
      【解决方案4】:

      因为您使用的是SQLiteOpenHelperhttp://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html,所以这可以检测数据库的升级和降级。

      所以方法

      onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

      onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)

      可以重写以在创建新数据库之前删除旧数据库

      【讨论】:

        【解决方案5】:

        我在三星 S8 上遇到了同样的问题 - 显然,在三星 Android 设备上,删除应用程序时应用程序内存不会自动删除。因此,当安装新的应用版本时,旧数据库仍然存在,如果数据库架构发生更改但数据库版本号保持不变甚至降低,则会发生冲突。

        解决方案:要安全删除数据库,您必须在系统设置的应用区域打开受影响应用的详细视图。在这里,您可以显式删除数据(以及数据库)并清空缓存。之后,您可以删除该应用程序。 下次您在三星设备上安装该应用程序时,将新建数据库。

        【讨论】:

          猜你喜欢
          • 2016-06-16
          • 2013-11-10
          • 1970-01-01
          • 1970-01-01
          • 2016-12-11
          • 2020-07-04
          • 1970-01-01
          • 2021-11-01
          • 1970-01-01
          相关资源
          最近更新 更多