Keeping the same SQLite database when upgrading and Android app from Lite to Pro version

前端 未结 3 755
说谎
说谎 2021-01-31 06:06

First of all I have done a search and can\'t find a specific answer to my question so here goes...

I am writing my first Android application and plan to have a Lite vers

相关标签:
3条回答
  • 2021-01-31 06:48

    What I did in and it seems to work for Hexaddicus, is have both Lite and Pro versions run as the same user and then on the first time run of the Pro version, copy the Lite database over. Then inform the user of the copy.

    Set the android:sharedUserId to be the same in both products...

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.mycompany.package"
          android:sharedUserId="com.mycompany.package" <---- IMPORTANT
          android:versionCode="10"
          android:versionName="@string/app_version"
          android:installLocation="auto">
    

    And then the code to copy the DB...

        try {
            final Context free_context = this.createPackageContext("com.mycompany.package", Context.CONTEXT_INCLUDE_CODE);
            final File    full_db      = this.getDatabasePath(GameData.DATABASE_NAME);
            final File    full_db_dir  = full_db.getParentFile();
            final File    free_db      = free_context.getDatabasePath(GameData.DATABASE_NAME);
            final File    free_db_dir  = free_db.getParentFile();
    
            if (free_db.exists() == false)     return;
            if (full_db_dir.exists() == false) full_db_dir.mkdir();
            if (full_db.exists() == false)     full_db.createNewFile();
    
            FileUtils.copyDirectory(free_db_dir, full_db_dir);
            this.gameData.getWritableDatabase();
        }
        catch (NameNotFoundException e) {
            /* do nothing here since this is an semi expected case */
            Log.w("mytag", "No Lite version found");
        } catch (IOException e) {
            Log.w("mytag", "Failed to create file");
        }
    }
    

    The only downside of this is that once the copy is done, there is no syncing between the two versions. You also have to make sure that the user of the Lite version is running a version that is running as the sharedUserId or the copy will fail.

    Update: please consider ChrisCashwells comments and answer too since he brings up a valid point and I can't remember what I did in his example.

    0 讨论(0)
  • 2021-01-31 06:48

    You might want to do more of an "unlock" approach than a separate paid app if possible. That way you're only ever using one package. If for no other reason, you'll be avoiding the issue of database ownership.

    Using the same android:sharedUserId would be a good approach if your app already has one set. If not, you'll invalidate access to all of your users' data if you send out an update that does have one set. If you're starting from square zero and don't already have an app in the wild with users expecting to keep their data, definitely set a sharedUserId from day one.

    0 讨论(0)
  • 2021-01-31 06:49

    As @Chris told that you can use "unlock" approach, i will explain it how i do in such conditions.

    You can have a table like 'Features' should have have a column/flag IsAvailable. If you want to restrict certain features you can set its IsAvailable flag to FALSE.

    If you have changes in DB structure, then you should upgrade the DB using:

    @Override
    public void onUpgrade()
    {
      if (condition == true)
        // alter table
    }
    
    0 讨论(0)
提交回复
热议问题