2012-01-20 15 views
14

Primero de todo lo que he hecho una búsqueda y no puedo encontrar una respuesta concreta a la pregunta así que aquí va ...Manteniendo la misma base de datos SQLite y al actualizar la aplicación para Android de Lite a la versión Pro

estoy escribiendo mi primera aplicación de Android y plan para tener una versión Lite (funciones limitadas) y una versión de pago (características completas).

La versión Lite y Pro utilizará la misma estructura de base de datos SQLite, y si el usuario comienza con la versión Lite y se actualiza a la versión Pro, no quiero que pierdan los datos que han creado en la versión Lite.

Como las versiones Lite y Pro (a mi entender) tienen que estar en paquetes separados para permitir que el Android Market las distinga, ¿cómo puede la versión Pro ver la base de datos Lite?

Muchas gracias de antemano por sus respuestas.

+0

Esto parece ser un duplicado de http://stackoverflow.com/questions/7053809/share-sqlite-database -between-2-android-apps donde hay una respuesta (segunda abajo). –

+1

@EdJellard No creo que sea un duplicado.Si bien las preguntas son similares, son diferentes. Esa pregunta es sobre compartir el DB entre dos aplicaciones, no necesariamente dos versiones de la aplicación _same_. –

+0

Gracias, voy a echar un vistazo. –

Respuesta

12

Lo que hice y parece funcionar para Hexaddicus, es tener versiones Lite y Pro ejecutadas como el mismo usuario y luego, en la primera ejecución de la versión Pro, copiar la base de datos Lite. Luego informe al usuario de la copia.

Establecer la android:sharedUserId a ser la misma en ambos productos ...

<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"> 

y luego el código para copiar el 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"); 
    } 
} 

La única desventaja de esto es que una vez la copia está hecha, no hay sincronización entre las dos versiones. También debe asegurarse de que el usuario de la versión Lite ejecute una versión que se esté ejecutando como sharedUserId o la copia fallará.

Actualización: tenga en cuenta los comentarios de ChrisCashwells y responda también, ya que trae a colación un punto válido y no puedo recordar lo que hice en su ejemplo.

+0

Solo quería proponer la misma solución. Solo para agregar a esta respuesta, debe mirar el parámetro android: sharedUserId en el archivo de manifiesto. – Yury

+0

Esto requiere tener 'sharedUserId', pero podría ser una solución viable. Si aún no tiene un conjunto 'sharedUserId', enviar una actualización que * does * tenga un conjunto significaría invalidar el acceso de la aplicación al mismo DB. –

+0

@ChrisCashwell: ¿Estás 100% seguro de eso? Me parece recordar ese problema, pero pensé que había funcionado. O eso O lo pensé desde el principio. Actualizando mi respuesta. –

2

Es posible que desee hacer más de un enfoque de "desbloqueo" de una aplicación de pago por separado si es posible. De esa forma, solo usarás un paquete. Si por alguna otra razón, evitará el problema de la propiedad de la base de datos.

El uso de la misma android:sharedUserId sería un buen enfoque si su aplicación ya tiene un conjunto. De lo contrario, invalidará el acceso a todos los datos de sus usuarios si envía una actualización que sí tiene un conjunto. Si está comenzando desde el cero y no tiene una aplicación en libertad con los usuarios que esperan conservar sus datos, defina definitivamente un sharedUserId desde el primer día.

+0

Sí, una sola aplicación suena como una opción deseable, porque mantiene las cosas simples. Mi aplicación todavía está en desarrollo, por lo que en este momento estoy abierto a las ideas ... ¡algo para pensar! –

+0

@GuardianAngel esto también hace que sea más fácil de administrar más tarde. Por ejemplo, si encuentras un error, ¿quieres arreglarlo en dos aplicaciones separadas (gratuitas y de pago) o solo una? –

1

Como @ Chris dijo que se puede utilizar el enfoque de "desbloqueo", voy a explicar cómo hago que en tales condiciones.

Usted puede tener una tabla como "características no debería haber tiene una columna/bandera isAvailable. Si desea restringir ciertas funciones, puede establecer su indicador IsAvailable en FALSE.

Si tiene cambios en la estructura de base de datos, entonces usted debe actualizar la base de datos usando:

@Override 
public void onUpgrade() 
{ 
    if (condition == true) 
    // alter table 
} 
Cuestiones relacionadas