android - ver - Enviar una aplicación con una base de datos




ver base de datos sqlite android studio (11)

Si su aplicación requiere una base de datos y viene con datos integrados, ¿cuál es la mejor manera de enviar esa aplicación? Debería:

  1. Precreate la base de datos SQLite e inclúyala en el .apk ?

  2. ¿Incluir los comandos SQL con la aplicación y hacer que cree la base de datos e inserte los datos en el primer uso?

Los inconvenientes que veo son:

  1. Las posibles discrepancias de la versión de SQLite pueden causar problemas y actualmente no sé dónde debería ir la base de datos y cómo acceder a ella.

  2. Puede llevar mucho tiempo crear y completar la base de datos en el dispositivo.

¿Alguna sugerencia? Los punteros a la documentación sobre cualquier problema serían muy apreciados.


Envío de la aplicación con un archivo de base de datos, en Android Studio 3.0

Enviar la aplicación con un archivo de base de datos es una buena idea para mí. La ventaja es que no necesita realizar una inicialización compleja, que a veces cuesta mucho tiempo, si su conjunto de datos es enorme.

Paso 1: Preparar archivo de base de datos

Tenga su archivo de base de datos listo. Puede ser un archivo .db o un archivo .sqlite. Si usa un archivo .sqlite, todo lo que necesita hacer es cambiar los nombres de las extensiones de archivo. Los pasos son los mismos.

En este ejemplo, preparé un archivo llamado testDB.db. Tiene una tabla y algunos datos de muestra como esta.

Paso 2: Importa el archivo a tu proyecto

Cree la carpeta de activos si no ha tenido uno. Luego copia y pega el archivo de base de datos en esta carpeta

Paso 3: Copie el archivo a la carpeta de datos de la aplicación

Debe copiar el archivo de la base de datos en la carpeta de datos de la aplicación para seguir interactuando con él. Esta es una acción de una sola vez (inicialización) para copiar el archivo de base de datos. Si llama a este código varias veces, el archivo de la base de datos en la carpeta de datos será sobrescrito por el de la carpeta de activos. Este proceso de sobrescritura es útil cuando desea actualizar la base de datos en el futuro durante la actualización de la aplicación.

Tenga en cuenta que durante la actualización de la aplicación, este archivo de base de datos no se modificará en la carpeta de datos de la aplicación. Sólo la desinstalación lo borrará.

El archivo de base de datos necesita ser copiado a la /databasescarpeta. Abra el Explorador de archivos del dispositivo. Introduce la data/data/<YourAppName>/ubicación. Esta es la carpeta de datos por defecto de la aplicación mencionada anteriormente. Y de forma predeterminada, el archivo de la base de datos se colocará en otra carpeta llamada bases de datos en este directorio

Ahora, el proceso de copia de archivos es muy parecido a lo que está haciendo Java. Usa el siguiente código para hacer la copia pegada. Este es el código de iniciación. También se puede utilizar para actualizar (sobrescribiendo) el archivo de base de datos en el futuro.

//get context by calling "this" in activity or getActivity() in fragment
//call this if API level is lower than 17  String appDataPath = "/data/data/" + context.getPackageName() + "/databases/"
String appDataPath = context.getApplicationInfo().dataDir;

File dbFolder = new File(appDataPath + "/databases");//Make sure the /databases folder exists
dbFolder.mkdir();//This can be called multiple times.

File dbFilePath = new File(appDataPath + "/databases/testDB.db");

try {
    InputStream inputStream = context.getAssets().open("testDB.db");
    OutputStream outputStream = new FileOutputStream(dbFilePath);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer))>0)
    {
        outputStream.write(buffer, 0, length);
    }
    outputStream.flush();
    outputStream.close();
    inputStream.close();
} catch (IOException e){
    //handle
}

A continuación, actualice la carpeta para verificar el proceso de copia

Paso 4: Crear una base de datos abierta de ayuda

Crear una subclase para SQLiteOpenHelper, con connect, close, path, etc. Lo nombréDatabaseOpenHelper

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseOpenHelper extends SQLiteOpenHelper {
    public static final String DB_NAME = "testDB.db";
    public static final String DB_SUB_PATH = "/databases/" + DB_NAME;
    private static String APP_DATA_PATH = "";
    private SQLiteDatabase dataBase;
    private final Context context;

    public DatabaseOpenHelper(Context context){
        super(context, DB_NAME, null, 1);
        APP_DATA_PATH = context.getApplicationInfo().dataDir;
        this.context = context;
    }

    public boolean openDataBase() throws SQLException{
        String mPath = APP_DATA_PATH + DB_SUB_PATH;
        //Note that this method assumes that the db file is already copied in place
        dataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.OPEN_READWRITE);
        return dataBase != null;
    }

    @Override
    public synchronized void close(){
        if(dataBase != null) {dataBase.close();}
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

Paso 5: crear una clase de nivel superior para interactuar con la base de datos

Esta será la clase que leerá y escribirá su archivo de base de datos. También hay una consulta de muestra para imprimir el valor en la base de datos.

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class Database {
    private final Context context;
    private SQLiteDatabase database;
    private DatabaseOpenHelper dbHelper;

    public Database(Context context){
        this.context = context;
        dbHelper = new DatabaseOpenHelper(context);
    }

    public Database open() throws SQLException
    {
        dbHelper.openDataBase();
        dbHelper.close();
        database = dbHelper.getReadableDatabase();
        return this;
    }

    public void close()
    {
        dbHelper.close();
    }

    public void test(){
        try{
            String query ="SELECT value FROM test1";
            Cursor cursor = database.rawQuery(query, null);
            if (cursor.moveToFirst()){
                do{
                    String value = cursor.getString(0);
                    Log.d("db", value);
                }while (cursor.moveToNext());
            }
            cursor.close();
        } catch (SQLException e) {
            //handle
        }
    }
}

Paso 6: Prueba de funcionamiento

Pruebe el código ejecutando las siguientes líneas de códigos.

Database db = new Database(context);
db.open();
db.test();
db.close();

Presiona el botón de correr y anima!


Acabo de encontrar una manera de hacer esto en el ReignDesign blog en un artículo titulado Uso de su propia base de datos SQLite en aplicaciones de Android . Básicamente, crea previamente su base de datos, la coloca en su directorio de activos en su apk, y en el primer uso, copie a /data/data/YOUR_PACKAGE/databases/ directory.


Mi solución no usa ninguna biblioteca de terceros ni lo obliga a llamar a métodos personalizados en la subclase SQLiteOpenHelper para inicializar la base de datos en la creación. También se encarga de las actualizaciones de la base de datos también. Todo lo que hay que hacer es SQLiteOpenHelper subclase de SQLiteOpenHelper .

Requisito previo:

  1. La base de datos que desea enviar con la aplicación. Debe contener una tabla 1x1 llamada android_metadata con una locale atributo con el valor en_US además de las tablas exclusivas de su aplicación.

SQLiteOpenHelper :

  1. Subclase SQLiteOpenHelper .
  2. Cree un método private dentro de la subclase SQLiteOpenHelper . Este método contiene la lógica para copiar el contenido de la base de datos desde el archivo de la base de datos en la carpeta 'elementos' a la base de datos creada en el contexto del paquete de la aplicación.
  3. Reemplace los onCreate , onUpgrade y onOpen de SQLiteOpenHelper .

Basta de charla. Aquí va la subclase SQLiteOpenHelper :

public class PlanDetailsSQLiteOpenHelper extends SQLiteOpenHelper {
    private static final String TAG = "SQLiteOpenHelper";

    private final Context context;
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "my_custom_db";

    private boolean createDb = false, upgradeDb = false;

    public PlanDetailsSQLiteOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
    }

    /**
     * Copy packaged database from assets folder to the database created in the
     * application package context.
     * 
     * @param db
     *            The target database in the application package context.
     */
    private void copyDatabaseFromAssets(SQLiteDatabase db) {
        Log.i(TAG, "copyDatabase");
        InputStream myInput = null;
        OutputStream myOutput = null;
        try {
            // Open db packaged as asset as the input stream
            myInput = context.getAssets().open("path/to/shipped/db/file");

            // Open the db in the application package context:
            myOutput = new FileOutputStream(db.getPath());

            // Transfer db file contents:
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.flush();

            // Set the version of the copied database to the current
            // version:
            SQLiteDatabase copiedDb = context.openOrCreateDatabase(
                DATABASE_NAME, 0, null);
            copiedDb.execSQL("PRAGMA user_version = " + DATABASE_VERSION);
            copiedDb.close();

        } catch (IOException e) {
            e.printStackTrace();
            throw new Error(TAG + " Error copying database");
        } finally {
            // Close the streams
            try {
                if (myOutput != null) {
                    myOutput.close();
                }
                if (myInput != null) {
                    myInput.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                throw new Error(TAG + " Error closing streams");
            }
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.i(TAG, "onCreate db");
        createDb = true;
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.i(TAG, "onUpgrade db");
        upgradeDb = true;
    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        Log.i(TAG, "onOpen db");
        if (createDb) {// The db in the application package
            // context is being created.
            // So copy the contents from the db
            // file packaged in the assets
            // folder:
            createDb = false;
            copyDatabaseFromAssets(db);

        }
        if (upgradeDb) {// The db in the application package
            // context is being upgraded from a lower to a higher version.
            upgradeDb = false;
            // Your db upgrade logic here:
        }
    }
}

Finalmente, para obtener una conexión de base de datos, simplemente llame getReadableDatabase()o getWritableDatabase()en la SQLiteOpenHelpersubclase y se encargará de crear una base de datos, copiando el contenido de la base de datos del archivo especificado en la carpeta de "activos", si la base de datos no existe.

En resumen, puede usar la SQLiteOpenHelpersubclase para acceder a la base de datos enviada en la carpeta de activos tal como lo haría para una base de datos que se inicializa mediante consultas SQL en el onCreate()método.


Supongo que la mejor forma y la más nueva hasta hoy es usar la clase SQLiteAssetHelper .

Este tutorial lo guía perfectamente a través de la importación y el uso de bases de datos externas en Android

La biblioteca de SQLiteAssetHelper Android SQLiteAssetHelper permite crear su SQLite datos SQLite en su computadora de escritorio, e importarla y usarla en su aplicación de Android. Vamos a crear una aplicación sencilla para demostrar la aplicación de esta biblioteca.

Paso 1 : cree una base de datos quotes.db utilizando su aplicación de base de datos favorita de SQLite (DB Browser for SQLite es un software gratuito multiplataforma portátil, que se puede usar para crear y editar bases de datos SQLite). Crear una tabla 'citas' con una sola columna 'cita'. Insertar algunas citas aleatorias en la tabla 'citas'.

Paso 2 : la base de datos se puede importar al proyecto directamente como está o como un archivo comprimido. Se recomienda el archivo comprimido, si su base de datos es de tamaño demasiado grande. Puede crear una compresión ZIP o una compresión GZ .

El nombre de archivo del archivo db comprimido debe ser quotes.db.zip , si está utilizando la compresión ZIP o quotes.db.gz , si está utilizando la compresión GZ.

Paso 3 : Cree una nueva aplicación External Database Demo con un nombre de paquete com.javahelps.com.javahelps.externaldatabasedemo .

Paso 4 : Abra el build.gradle (Module: app) y agregue la siguiente dependencia.

dependencies {
    compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
}

Una vez que haya guardado el archivo build.gradle , haga clic en el enlace 'Sincronizar ahora' para actualizar el proyecto. Puede sincronizar el build.gradle , haciendo clic derecho en el archivo build.gradle y seleccionando la opción Synchronize build.gradle también.

Paso 5 : Haga clic derecho en la carpeta de la aplicación y cree una nueva carpeta de activos.

Paso 6 : Cree una nueva carpeta 'bases de datos' dentro de la carpeta de activos.

Paso 7 : Copie y pegue el archivo quotes.db.zip dentro de la carpeta de assets/databases .

Paso 8 : Crear una nueva clase DatabaseOpenHelper

package com.javahelps.externaldatabasedemo;

import android.content.Context;

import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;

public class DatabaseOpenHelper extends SQLiteAssetHelper {
    private static final String DATABASE_NAME = "quotes.db";
    private static final int DATABASE_VERSION = 1;

    public DatabaseOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
}  Notice that rather than extending SQLiteOpenHelper, the DatabaseOpenHelper extends  SQLiteAssetHelper class.

Paso 9 : Cree una nueva clase DatabaseAccess e ingrese el código como se muestra a continuación. Más detalles sobre esta clase están disponibles en el tutorial avanzado de la base de datos de Android.

package com.javahelps.externaldatabasedemo;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.List;

public class DatabaseAccess {
    private SQLiteOpenHelper openHelper;
    private SQLiteDatabase database;
    private static DatabaseAccess instance;

    /**
     * Private constructor to aboid object creation from outside classes.
     *
     * @param context
     */
    private DatabaseAccess(Context context) {
        this.openHelper = new DatabaseOpenHelper(context);
    }

    /**
     * Return a singleton instance of DatabaseAccess.
     *
     * @param context the Context
     * @return the instance of DabaseAccess
     */
    public static DatabaseAccess getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseAccess(context);
        }
        return instance;
    }

    /**
     * Open the database connection.
     */
    public void open() {
        this.database = openHelper.getWritableDatabase();
    }

    /**
     * Close the database connection.
     */
    public void close() {
        if (database != null) {
            this.database.close();
        }
    }

    /**
     * Read all quotes from the database.
     *
     * @return a List of quotes
     */
    public List<String> getQuotes() {
        List<String> list = new ArrayList<>();
        Cursor cursor = database.rawQuery("SELECT * FROM quotes", null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            list.add(cursor.getString(0));
            cursor.moveToNext();
        }
        cursor.close();
        return list;
    }
}  In this class only the `getQuotes` method is implemented to read the data from the database. You have the full freedom to insert,

actualiza y elimina cualquier fila en la base de datos como de costumbre. Para más detalles, siga este enlace Advanced Android Database.

Todas las configuraciones relacionadas con la base de datos están completas y ahora necesitamos crear un ListView para mostrar las citas.

Paso 10 : Agregue un ListView en su activity_main.xml .

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
</FrameLayout>  

Paso 11 : Encuentre el objeto de ListView en el método MainActivity de MainActivity y alimente las citas que se leen desde la base de datos.

package com.javahelps.externaldatabasedemo;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.List;


public class MainActivity extends ActionBarActivity {
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.listView = (ListView) findViewById(R.id.listView);
        DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
        databaseAccess.open();
        List<String> quotes = databaseAccess.getQuotes();
        databaseAccess.close();

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
quotes);
        this.listView.setAdapter(adapter);
    }
}

Paso 12 : Guarda todos los cambios y ejecuta la aplicación.

Además de este artículo, puede descargar SQLiteAssetHelper here


Estoy usando ORMLite y debajo del código funcionó para mí

public class DatabaseProvider extends OrmLiteSqliteOpenHelper {
    private static final String DatabaseName = "DatabaseName";
    private static final int DatabaseVersion = 1;
    private final Context ProvidedContext;

    public DatabaseProvider(Context context) {
        super(context, DatabaseName, null, DatabaseVersion);
        this.ProvidedContext= context;
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        boolean databaseCopied = preferences.getBoolean("DatabaseCopied", false);
        if (databaseCopied) {
            //Do Nothing
        } else {
            CopyDatabase();
            SharedPreferences.Editor editor = preferences.edit();
            editor.putBoolean("DatabaseCopied", true);
            editor.commit();
        }
    }

    private String DatabasePath() {
        return "/data/data/" + ProvidedContext.getPackageName() + "/databases/";
    }

    private void CopyDatabase() {
        try {
            CopyDatabaseInternal();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private File ExtractAssetsZip(String zipFileName) {
        InputStream inputStream;
        ZipInputStream zipInputStream;
        File tempFolder;
        do {
            tempFolder = null;
            tempFolder = new File(ProvidedContext.getCacheDir() + "/extracted-" + System.currentTimeMillis() + "/");
        } while (tempFolder.exists());

        tempFolder.mkdirs();

        try {
            String filename;
            inputStream = ProvidedContext.getAssets().open(zipFileName);
            zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream));
            ZipEntry zipEntry;
            byte[] buffer = new byte[1024];
            int count;

            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                filename = zipEntry.getName();
                if (zipEntry.isDirectory()) {
                    File fmd = new File(tempFolder.getAbsolutePath() + "/" + filename);
                    fmd.mkdirs();
                    continue;
                }

                FileOutputStream fileOutputStream = new FileOutputStream(tempFolder.getAbsolutePath() + "/" + filename);
                while ((count = zipInputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, count);
                }

                fileOutputStream.close();
                zipInputStream.closeEntry();
            }

            zipInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        return tempFolder;
    }

    private void CopyDatabaseInternal() throws IOException {

        File extractedPath = ExtractAssetsZip(DatabaseName + ".zip");
        String databaseFile = "";
        for (File innerFile : extractedPath.listFiles()) {
            databaseFile = innerFile.getAbsolutePath();
            break;
        }
        if (databaseFile == null || databaseFile.length() ==0 )
            throw new RuntimeException("databaseFile is empty");

        InputStream inputStream = new FileInputStream(databaseFile);

        String outFileName = DatabasePath() + DatabaseName;

        File destinationPath = new File(DatabasePath());
        if (!destinationPath.exists())
            destinationPath.mkdirs();

        File destinationFile = new File(outFileName);
        if (!destinationFile.exists())
            destinationFile.createNewFile();

        OutputStream myOutput = new FileOutputStream(outFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        myOutput.flush();
        myOutput.close();
        inputStream.close();
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int fromVersion, int toVersion) {

    }
}

Tenga en cuenta que el código extrae el archivo de base de datos de un archivo zip en los activos


Modifiqué la clase y las respuestas a la pregunta y escribí una clase que permite actualizar la base de datos a través de DB_VERSION.

public class DatabaseHelper extends SQLiteOpenHelper {
    private static String DB_NAME = "info.db";
    private static String DB_PATH = "";
    private static final int DB_VERSION = 1;

    private SQLiteDatabase mDataBase;
    private final Context mContext;
    private boolean mNeedUpdate = false;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        if (android.os.Build.VERSION.SDK_INT >= 17)
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        else
            DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        this.mContext = context;

        copyDataBase();

        this.getReadableDatabase();
    }

    public void updateDataBase() throws IOException {
        if (mNeedUpdate) {
            File dbFile = new File(DB_PATH + DB_NAME);
            if (dbFile.exists())
                dbFile.delete();

            copyDataBase();

            mNeedUpdate = false;
        }
    }

    private boolean checkDataBase() {
        File dbFile = new File(DB_PATH + DB_NAME);
        return dbFile.exists();
    }

    private void copyDataBase() {
        if (!checkDataBase()) {
            this.getReadableDatabase();
            this.close();
            try {
                copyDBFile();
            } catch (IOException mIOException) {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    private void copyDBFile() throws IOException {
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        //InputStream mInput = mContext.getResources().openRawResource(R.raw.info);
        OutputStream mOutput = new FileOutputStream(DB_PATH + DB_NAME);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0)
            mOutput.write(mBuffer, 0, mLength);
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    public boolean openDataBase() throws SQLException {
        mDataBase = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() {
        if (mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion)
            mNeedUpdate = true;
    }
}

Usando una clase.

En la clase de actividad, declarar variables.

private DatabaseHelper mDBHelper;
private SQLiteDatabase mDb;

En el método onCreate, escriba el siguiente código.

mDBHelper = new DatabaseHelper(this);

try {
    mDBHelper.updateDataBase();
} catch (IOException mIOException) {
    throw new Error("UnableToUpdateDatabase");
}

try {
    mDb = mDBHelper.getWritableDatabase();
} catch (SQLException mSQLException) {
    throw mSQLException;
}

Si agrega un archivo de base de datos a la carpeta res / raw, use la siguiente modificación de la clase.

public class DatabaseHelper extends SQLiteOpenHelper {
    private static String DB_NAME = "info.db";
    private static String DB_PATH = "";
    private static final int DB_VERSION = 1;

    private SQLiteDatabase mDataBase;
    private final Context mContext;
    private boolean mNeedUpdate = false;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        if (android.os.Build.VERSION.SDK_INT >= 17)
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        else
            DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        this.mContext = context;

        copyDataBase();

        this.getReadableDatabase();
    }

    public void updateDataBase() throws IOException {
        if (mNeedUpdate) {
            File dbFile = new File(DB_PATH + DB_NAME);
            if (dbFile.exists())
                dbFile.delete();

            copyDataBase();

            mNeedUpdate = false;
        }
    }

    private boolean checkDataBase() {
        File dbFile = new File(DB_PATH + DB_NAME);
        return dbFile.exists();
    }

    private void copyDataBase() {
        if (!checkDataBase()) {
            this.getReadableDatabase();
            this.close();
            try {
                copyDBFile();
            } catch (IOException mIOException) {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    private void copyDBFile() throws IOException {
        //InputStream mInput = mContext.getAssets().open(DB_NAME);
        InputStream mInput = mContext.getResources().openRawResource(R.raw.info);
        OutputStream mOutput = new FileOutputStream(DB_PATH + DB_NAME);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0)
            mOutput.write(mBuffer, 0, mLength);
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    public boolean openDataBase() throws SQLException {
        mDataBase = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() {
        if (mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion)
            mNeedUpdate = true;
    }
}

http://blog.harrix.org/article/6784


Actualmente no hay manera de crear una base de datos SQLite para enviar con su apk. Lo mejor que puede hacer es guardar el SQL apropiado como un recurso y ejecutarlos desde su aplicación. Sí, esto conduce a la duplicación de datos (la misma información existe como un recurso y como una base de datos), pero no hay otra manera ahora. El único factor atenuante es que el archivo apk está comprimido. Mi experiencia es 908KB compresas a menos de 268KB.

El hilo a continuación tiene la mejor discusión / solución que he encontrado con un buen código de muestra.

http://groups.google.com/group/android-developers/msg/9f455ae93a1cf152

Almacené mi declaración CREATE como un recurso de cadena para leer con Context.getString () y la ejecuté con SQLiteDatabse.execSQL ().

Almacené los datos para mis inserciones en res / raw / inserts.sql (creé el archivo sql, 7000+ líneas). Usando la técnica del enlace anterior, ingresé en un bucle, leí el archivo línea por línea y pacté los datos en "INSERT INTO tbl VALUE" e hice otra SQLiteDatabase.execSQL (). No tiene sentido guardar 7000 "INSERT INTO tbl VALUE" s cuando solo pueden ser contactados.

El emulador tarda unos veinte segundos, no sé cuánto tiempo tomaría en un teléfono real, pero solo ocurre una vez, cuando el usuario inicia la aplicación por primera vez.


Android ya proporciona un enfoque compatible con la versión de la administración de bases de datos. Este enfoque se ha aprovechado en el marco de BARACUS para aplicaciones de Android.

Le permite administrar la base de datos a lo largo de todo el ciclo de vida de la versión de una aplicación, pudiendo actualizar la base de datos sqlite desde cualquier versión anterior a la actual.

Además, le permite ejecutar copias de seguridad en caliente y recuperación en caliente de SQLite.

No estoy 100% seguro, pero una recuperación en caliente para un dispositivo específico puede permitirle enviar una base de datos preparada en su aplicación. Pero no estoy seguro acerca del formato binario de la base de datos que puede ser específico para ciertos dispositivos, proveedores o generaciones de dispositivos.

Ya que se trata de Apache License 2, siéntase libre de reutilizar cualquier parte del código, que se puede encontrar en github

EDITAR:

Si solo desea enviar datos, puede considerar la creación de una instancia y la persistencia de POJO en el primer inicio de las aplicaciones. BARACUS obtuvo un soporte integrado para esto (Almacén de valores de clave integrado para información de configuración, por ejemplo, "APP_FIRST_RUN" más un enlace post-contexto-bootstrap para ejecutar las operaciones posteriores al lanzamiento en el contexto). Esto le permite tener datos acoplados ajustados enviados con su aplicación; En la mayoría de los casos esto se ajusta a mis casos de uso.


Enviar la base de datos dentro de la apk y luego copiarla /data/data/...duplicará el tamaño de la base de datos (1 en apk, 1 en data/data/...), y aumentará el tamaño de apk (por supuesto). Por lo que su base de datos no debe ser demasiado grande.


Escribí una library para simplificar este proceso.

dataBase = new DataBase.Builder(context, "myDb").
//        setAssetsPath(). // default "databases"
//        setDatabaseErrorHandler().
//        setCursorFactory().
//        setUpgradeCallback()
//        setVersion(). // default 1
build();

Se creará una base de datos desde el assets/databases/myDb.dbarchivo. Además obtendrás todas esas funcionalidades:

  • Cargar base de datos desde archivo
  • Acceso sincronizado a la base de datos.
  • Usando sqlite-android por consulta, distribución específica de Android de las últimas versiones de SQLite.

library desde library .


Si los datos requeridos no son demasiado grandes (los límites no lo sé, dependerían de muchas cosas), también puede descargar los datos (en XML, JSON, lo que sea) desde un sitio web / aplicación web. Después de recibir, ejecute las sentencias de SQL utilizando los datos recibidos, creando sus tablas e insertando los datos.

Si su aplicación móvil contiene muchos datos, puede ser más fácil actualizar los datos en las aplicaciones instaladas con datos o cambios más precisos.





android-database