Frage

Wenn Ihre Anwendung eine Datenbank benötigt und es kommt mit den Daten gebaut, was der beste Weg ist, dass die Anwendung zu versenden? Soll ich:

  1. PreCreate die SQLite-Datenbank und schließen sie in den .apk?

  2. Fügen Sie die SQL mit dem Anwendungsbefehle und haben es auf die Datenbank erstellen und die Daten bei der ersten Verwendung ein?

Die Nachteile ich sehe, sind:

  1. Mögliche SQLite Versionskonflikte können Probleme verursachen, und ich weiß noch nicht, wo sollte die Datenbank gehen und wie sie zugreifen zu können.

  2. Es kann eine wirklich lange Zeit in Anspruch nehmen zu schaffen und die Datenbank auf dem Gerät zu füllen.

Irgendwelche Vorschläge? Hinweise auf die Dokumentation alle Probleme in Bezug auf würden sehr geschätzt.

War es hilfreich?

Lösung

Ich habe gerade einen Weg, dies zu tun in ReignDesign blog in einem Artikel mit dem Titel mit dem eigenen SQLite-Datenbank in Android-Anwendungen . Grundsätzlich Sie Ihre Datenbank vorab erstellen, legen Sie sie in Ihr Vermögen Verzeichnis in Ihrem apk, und bei der ersten Verwendung Kopie Verzeichnis /data/data/YOUR_PACKAGE/databases/.

Andere Tipps

Es gibt zwei Möglichkeiten für die Erstellung und Aktualisierung von Datenbanken.

Eine davon ist eine Datenbank extern zu erstellen, legen Sie sie dann in den Assets Ordner des Projekts und dann die gesamte Datenbank von dort kopieren. Dies ist viel schneller, wenn die Datenbank eine Menge von Tabellen und anderen Komponenten. Upgrades werden ausgelöst, indem die Datenbank Versionsnummer in der res / Werte / strings.xml Datei zu ändern. Upgrades würde dann durch die Schaffung einer neuen Datenbank extern durchgeführt werden, die alte Datenbank zu ersetzen in dem Ordnern Assets mit der neuen Datenbank, die alte Datenbank in internen Speichern unter einem anderen Namen speichern, die neue Datenbank aus dem Vermögen Kopieren Ordner in interne Speicher, um alle Daten aus der alten Datenbank zu übertragen (das war früher umbenannt) in die neuen Datenbank und schließlich die alte Datenbank zu löschen. Sie können ursprünglich eine Datenbank erstellen, indem Sie die SQLite-Manager FireFox-Plugin Ihre Erstellung von SQL-Anweisungen auszuführen.

Die andere Option ist eine Datenbank intern aus einer SQL-Datei zu erstellen. Das ist nicht so schnell, aber die Verzögerung würde wahrscheinlich den Benutzer nicht wahrnehmbar sein, wenn die Datenbank nur ein paar Tische hat. Upgrades ausgelöst werden, indem die Datenbank Versionsnummer in der res / Werte / strings.xml Datei zu ändern. Upgrades dann durch Verarbeiten eines Upgrade-SQL-Datei erreicht werden würde. Die Daten in der Datenbank bleiben unverändert, außer wenn sein Behälter wird entfernt, zum Beispiel einer Tabelle löschen.

Das folgende Beispiel zeigt, wie beide Methoden verwenden.

Hier ist ein Beispiel create_database.sql Datei. Es ist im Anlagenordner des Projektes für das interne Verfahren oder kopiert in die „SQL ausführen‘ von SQLite-Manager platziert werden, um die Datenbank für die externe Methode erstellen . (Anmerkung: Beachten Sie den Kommentar über die erforderlich Tabelle von Android.)

--Android requires a table named 'android_metadata' with a 'locale' column
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US');
INSERT INTO "android_metadata" VALUES ('en_US');

CREATE TABLE "kitchen_table";
CREATE TABLE "coffee_table";
CREATE TABLE "pool_table";
CREATE TABLE "dining_room_table";
CREATE TABLE "card_table"; 

Hier ist ein Beispiel update_database.sql Datei. Es ist im Anlagenordner des Projektes für das interne Verfahren oder kopiert in die „SQL ausführen‘ von SQLite-Manager platziert werden, um die Datenbank für die externe Methode erstellen . (Anmerkung: Beachten Sie, dass alle drei Typen von SQL-Kommentare werden von dem SQL-Parser ignoriert werden, die in diesem Beispiel enthalten ist.)

--CREATE TABLE "kitchen_table";  This is one type of comment in sql.  It is ignored by parseSql.
/*
 * CREATE TABLE "coffee_table"; This is a second type of comment in sql.  It is ignored by parseSql.
 */
{
CREATE TABLE "pool_table";  This is a third type of comment in sql.  It is ignored by parseSql.
}
/* CREATE TABLE "dining_room_table"; This is a second type of comment in sql.  It is ignored by parseSql. */
{ CREATE TABLE "card_table"; This is a third type of comment in sql.  It is ignored by parseSql. }

--DROP TABLE "picnic_table"; Uncomment this if picnic table was previously created and now is being replaced.
CREATE TABLE "picnic_table" ("plates" TEXT);
INSERT INTO "picnic_table" VALUES ('paper');

Hier ist ein Eintrag in die /res/values/strings.xml Datei für die Datenbank Versionsnummer hinzuzufügen.

<item type="string" name="databaseVersion" format="integer">1</item>

Hier ist eine Tätigkeit, die auf die Datenbank zugreift und dann verwendet sie. ( . Hinweis: Möglicherweise möchten Sie die Datenbank-Code in einem separaten Thread ausgeführt werden, wenn es eine Menge von Ressourcen verwendet )

package android.example;

import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;

/**
 * @author Danny Remington - MacroSolve
 * 
 *         Activity for demonstrating how to use a sqlite database.
 */
public class Database extends Activity {
     /** Called when the activity is first created. */
     @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        DatabaseHelper myDbHelper;
        SQLiteDatabase myDb = null;

        myDbHelper = new DatabaseHelper(this);
        /*
         * Database must be initialized before it can be used. This will ensure
         * that the database exists and is the current version.
         */
         myDbHelper.initializeDataBase();

         try {
            // A reference to the database can be obtained after initialization.
            myDb = myDbHelper.getWritableDatabase();
            /*
             * Place code to use database here.
             */
         } catch (Exception ex) {
            ex.printStackTrace();
         } finally {
            try {
                myDbHelper.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                myDb.close();
            }
        }

    }
}

Hier ist die Datenbank Helper-Klasse, wo die Datenbank erstellt oder aktualisiert, falls erforderlich. . (Anmerkung: Android erfordert, dass Sie eine Klasse erstellen, die SQLiteOpenHelper erstreckt, um mit einer SQLite-Datenbank zu arbeiten)

package android.example;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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

/**
 * @author Danny Remington - MacroSolve
 * 
 *         Helper class for sqlite database.
 */
public class DatabaseHelper extends SQLiteOpenHelper {

    /*
     * The Android's default system path of the application database in internal
     * storage. The package of the application is part of the path of the
     * directory.
     */
    private static String DB_DIR = "/data/data/android.example/databases/";
    private static String DB_NAME = "database.sqlite";
    private static String DB_PATH = DB_DIR + DB_NAME;
    private static String OLD_DB_PATH = DB_DIR + "old_" + DB_NAME;

    private final Context myContext;

    private boolean createDatabase = false;
    private boolean upgradeDatabase = false;

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     * 
     * @param context
     */
    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, context.getResources().getInteger(
                R.string.databaseVersion));
        myContext = context;
        // Get the path of the database that is based on the context.
        DB_PATH = myContext.getDatabasePath(DB_NAME).getAbsolutePath();
    }

    /**
     * Upgrade the database in internal storage if it exists but is not current. 
     * Create a new empty database in internal storage if it does not exist.
     */
    public void initializeDataBase() {
        /*
         * Creates or updates the database in internal storage if it is needed
         * before opening the database. In all cases opening the database copies
         * the database in internal storage to the cache.
         */
        getWritableDatabase();

        if (createDatabase) {
            /*
             * If the database is created by the copy method, then the creation
             * code needs to go here. This method consists of copying the new
             * database from assets into internal storage and then caching it.
             */
            try {
                /*
                 * Write over the empty data that was created in internal
                 * storage with the one in assets and then cache it.
                 */
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        } else if (upgradeDatabase) {
            /*
             * If the database is upgraded by the copy and reload method, then
             * the upgrade code needs to go here. This method consists of
             * renaming the old database in internal storage, create an empty
             * new database in internal storage, copying the database from
             * assets to the new database in internal storage, caching the new
             * database from internal storage, loading the data from the old
             * database into the new database in the cache and then deleting the
             * old database from internal storage.
             */
            try {
                FileHelper.copyFile(DB_PATH, OLD_DB_PATH);
                copyDataBase();
                SQLiteDatabase old_db = SQLiteDatabase.openDatabase(OLD_DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
                SQLiteDatabase new_db = SQLiteDatabase.openDatabase(DB_PATH,null, SQLiteDatabase.OPEN_READWRITE);
                /*
                 * Add code to load data into the new database from the old
                 * database and then delete the old database from internal
                 * storage after all data has been transferred.
                 */
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }

    }

    /**
     * Copies your database from your local assets-folder to the just created
     * empty database in the system folder, from where it can be accessed and
     * handled. This is done by transfering bytestream.
     * */
    private void copyDataBase() throws IOException {
        /*
         * Close SQLiteOpenHelper so it will commit the created empty database
         * to internal storage.
         */
        close();

        /*
         * Open the database in the assets folder as the input stream.
         */
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        /*
         * Open the empty db in interal storage as the output stream.
         */
        OutputStream myOutput = new FileOutputStream(DB_PATH);

        /*
         * Copy over the empty db in internal storage with the database in the
         * assets folder.
         */
        FileHelper.copyFile(myInput, myOutput);

        /*
         * Access the copied database so SQLiteHelper will cache it and mark it
         * as created.
         */
        getWritableDatabase().close();
    }

    /*
     * This is where the creation of tables and the initial population of the
     * tables should happen, if a database is being created from scratch instead
     * of being copied from the application package assets. Copying a database
     * from the application package assets to internal storage inside this
     * method will result in a corrupted database.
     * <P>
     * NOTE: This method is normally only called when a database has not already
     * been created. When the database has been copied, then this method is
     * called the first time a reference to the database is retrieved after the
     * database is copied since the database last cached by SQLiteOpenHelper is
     * different than the database in internal storage.
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        /*
         * Signal that a new database needs to be copied. The copy process must
         * be performed after the database in the cache has been closed causing
         * it to be committed to internal storage. Otherwise the database in
         * internal storage will not have the same creation timestamp as the one
         * in the cache causing the database in internal storage to be marked as
         * corrupted.
         */
        createDatabase = true;

        /*
         * This will create by reading a sql file and executing the commands in
         * it.
         */
            // try {
            // InputStream is = myContext.getResources().getAssets().open(
            // "create_database.sql");
            //
            // String[] statements = FileHelper.parseSqlFile(is);
            //
            // for (String statement : statements) {
            // db.execSQL(statement);
            // }
            // } catch (Exception ex) {
            // ex.printStackTrace();
            // }
    }

    /**
     * Called only if version number was changed and the database has already
     * been created. Copying a database from the application package assets to
     * the internal data system inside this method will result in a corrupted
     * database in the internal data system.
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        /*
         * Signal that the database needs to be upgraded for the copy method of
         * creation. The copy process must be performed after the database has
         * been opened or the database will be corrupted.
         */
        upgradeDatabase = true;

        /*
         * Code to update the database via execution of sql statements goes
         * here.
         */

        /*
         * This will upgrade by reading a sql file and executing the commands in
         * it.
         */
        // try {
        // InputStream is = myContext.getResources().getAssets().open(
        // "upgrade_database.sql");
        //
        // String[] statements = FileHelper.parseSqlFile(is);
        //
        // for (String statement : statements) {
        // db.execSQL(statement);
        // }
        // } catch (Exception ex) {
        // ex.printStackTrace();
        // }
    }

    /**
     * Called everytime the database is opened by getReadableDatabase or
     * getWritableDatabase. This is called after onCreate or onUpgrade is
     * called.
     */
    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
    }

    /*
     * Add your public helper methods to access and get content from the
     * database. You could return cursors by doing
     * "return myDataBase.query(....)" so it'd be easy to you to create adapters
     * for your views.
     */

}

Hier ist die FileHelper Klasse, die Methoden für Bytedatenstream Kopieren von Dateien und Parsen von SQL-Dateien enthält.

package android.example;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.channels.FileChannel;

/**
 * @author Danny Remington - MacroSolve
 * 
 *         Helper class for common tasks using files.
 * 
 */
public class FileHelper {
    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - InputStream for the file to copy from.
     * @param toFile
     *            - InputStream for the file to copy to.
     */
    public static void copyFile(InputStream fromFile, OutputStream toFile) throws IOException {
        // transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;

        try {
            while ((length = fromFile.read(buffer)) > 0) {
                toFile.write(buffer, 0, length);
            }
        }
        // Close the streams
        finally {
            try {
                if (toFile != null) {
                    try {
                        toFile.flush();
                    } finally {
                        toFile.close();
                    }
            }
            } finally {
                if (fromFile != null) {
                    fromFile.close();
                }
            }
        }
    }

    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - String specifying the path of the file to copy from.
     * @param toFile
     *            - String specifying the path of the file to copy to.
     */
    public static void copyFile(String fromFile, String toFile) throws IOException {
        copyFile(new FileInputStream(fromFile), new FileOutputStream(toFile));
    }

    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - File for the file to copy from.
     * @param toFile
     *            - File for the file to copy to.
     */
    public static void copyFile(File fromFile, File toFile) throws IOException {
        copyFile(new FileInputStream(fromFile), new FileOutputStream(toFile));
    }

    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - FileInputStream for the file to copy from.
     * @param toFile
     *            - FileInputStream for the file to copy to.
     */
    public static void copyFile(FileInputStream fromFile, FileOutputStream toFile) throws IOException {
        FileChannel fromChannel = fromFile.getChannel();
        FileChannel toChannel = toFile.getChannel();

        try {
            fromChannel.transferTo(0, fromChannel.size(), toChannel);
        } finally {
            try {
                if (fromChannel != null) {
                    fromChannel.close();
                }
            } finally {
                if (toChannel != null) {
                    toChannel.close();
                }
            }
        }
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - String containing the path for the file that contains sql
     *            statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(String sqlFile) throws IOException {
        return parseSqlFile(new BufferedReader(new FileReader(sqlFile)));
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - InputStream for the file that contains sql statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(InputStream sqlFile) throws IOException {
        return parseSqlFile(new BufferedReader(new InputStreamReader(sqlFile)));
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - Reader for the file that contains sql statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(Reader sqlFile) throws IOException {
        return parseSqlFile(new BufferedReader(sqlFile));
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - BufferedReader for the file that contains sql statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(BufferedReader sqlFile) throws IOException {
        String line;
        StringBuilder sql = new StringBuilder();
        String multiLineComment = null;

        while ((line = sqlFile.readLine()) != null) {
            line = line.trim();

            // Check for start of multi-line comment
            if (multiLineComment == null) {
                // Check for first multi-line comment type
                if (line.startsWith("/*")) {
                    if (!line.endsWith("}")) {
                        multiLineComment = "/*";
                    }
                // Check for second multi-line comment type
                } else if (line.startsWith("{")) {
                    if (!line.endsWith("}")) {
                        multiLineComment = "{";
                }
                // Append line if line is not empty or a single line comment
                } else if (!line.startsWith("--") && !line.equals("")) {
                    sql.append(line);
                } // Check for matching end comment
            } else if (multiLineComment.equals("/*")) {
                if (line.endsWith("*/")) {
                    multiLineComment = null;
                }
            // Check for matching end comment
            } else if (multiLineComment.equals("{")) {
                if (line.endsWith("}")) {
                    multiLineComment = null;
                }
            }

        }

        sqlFile.close();

        return sql.toString().split(";");
    }

}

Die SQLiteAssetHelper Bibliothek macht diese Aufgabe wirklich einfach.

Es ist einfach als gradle Abhängigkeit hinzufügen (aber ein Glas ist auch für Antennen- / Eclipse-verfügbar) und zusammen mit der Dokumentation kann es unter:
https://github.com/jgilfelt/android-sqlite-asset-helper

. Hinweis: Dieses Projekt wird nicht mehr aufrechterhalten, wie oben Github Link angegeben auf

Wie in der Dokumentation erläutert:

  1. , um die Abhängigkeit Ihres Moduls gradle Build-Datei hinzufügen:

    dependencies {
        compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
    }
    
  2. Kopieren Sie die Datenbank in das Vermögen Verzeichnis, in einem Unterverzeichnis namens assets/databases. Zum Beispiel:
    assets/databases/my_database.db

    (Optional können Sie die Datenbank in einer ZIP-Datei wie assets/databases/my_database.zip komprimieren. Dies ist nicht erforderlich, da die APK als Ganzes komprimiert bereits.)

  3. Erstellen Sie eine Klasse, zum Beispiel:

    public class MyDatabase extends SQLiteAssetHelper {
    
        private static final String DATABASE_NAME = "my_database.db";
        private static final int DATABASE_VERSION = 1;
    
        public MyDatabase(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    }
    

Ich denke, die beste und neueste Art und Weise bis heute SQLiteAssetHelper Klasse verwendet.

Dieses Tutorial perfekt durch Führungen Importieren und Verwenden von externer Datenbank in Android

  

Die Android SQLiteAssetHelper Bibliothek können Sie Ihre SQLite bauen   Datenbank in Ihrem Desktop-Computer, und zu importieren und verwenden Sie es in Ihrem   Android-Anwendung. Lassen Sie uns eine einfache Anwendung erstellen zu demonstrieren   die Anwendung dieser Bibliothek.

     

Schritt 1: : Erstellen Sie eine Datenbank quotes.db Ihre Lieblings SQLite   Datenbankanwendung (DB Browser für SQLite ist ein tragbares Kreuz   Plattform Freeware, die verwendet werden kann zum Erstellen und Bearbeiten SQLite   Datenbanken). Erstellen Sie eine Tabelle ‚zitiert‘ mit einer einzigen Spalte ‚Zitat‘.   Legen Sie einige zufällige Zitate in die Tabelle ‚zitiert.‘

     

Schritt 2: : Die Datenbank in Projekt importiert werden kann entweder direkt als   es ist oder als komprimierte Datei. Die komprimierte Datei wird empfohlen, wenn   Ihre Datenbank ist in der Größe zu groß. Sie können entweder einen ZIP erstellen   Kompression oder eine GZ Kompression.

     

Der Dateiname der komprimierten Datenbankdatei quotes.db.zip werden müssen, wenn Sie   mit ZIP-Komprimierung oder quotes.db.gz werden, wenn Sie GZ verwenden   Kompression.

     

Schritt 3: : Erstellen Sie eine neue Anwendung External Database Demo mit einem   Paketnamen com.javahelps.com.javahelps.externaldatabasedemo.

     

Schritt 4: : Öffnen Sie die build.gradle (Modul: app) Datei und fügen Sie den folgenden   Abhängigkeit.

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

Sobald Sie die build.gradle Datei klicken Sie auf den ‚Jetzt synchronisieren‘ gespeichert   verknüpfen das Projekt zu aktualisieren. Sie können die build.gradle synchronisieren, indem   direkt an der build.gradle Datei klicken und auch Synchronize build.gradle Option auswählen.

     

Schritt 5 :. Direkt an den App-Ordnern klicken und Neugelder Ordner erstellen

     

Schritt 6 . Erstellen Sie einen neuen Ordner 'Datenbanken' im Inneren des Vermögens Ordner

     

Schritt 7 : Kopieren Sie und die quotes.db.zip Datei in der Paste   assets/databases Ordner.

     

Schritt 8 : Erstellen Sie eine neue Klasse 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.
     

Schritt 9 : eine neue Klasse DatabaseAccess erstellen und den Code eingeben, wie gezeigt   unten. Weitere Details zu dieser Klasse ist bei Advanced Android verfügbar   Datenbank-Tutorial.

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,
     

aktualisieren und löschen Sie alle Zeilen in der Datenbank wie gewohnt. Für mehr Details,   folgen Sie diesem Link Erweiterte Android-Datenbank.

     

Alle Datenbank basierten Einstellungen abgeschlossen sind und jetzt müssen wir   erstellen ListView die Anführungszeichen angezeigt werden soll.

     

Schritt 10 :. Fügen Sie einen ListView in Ihrem 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>  
     

Schritt 11 : Finden Sie das Objekt von ListView im onCreate Methode von MainActivity und die Zitate füttern, die gelesen   bilden die Datenbasis.

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);
    }
}
     

Schritt 12 . Speichern Sie alle Änderungen und führen Sie die Anwendung

Zusätzlich zu diesem Artikel Sie SQLiteAssetHelper hier

herunterladen

Meine Lösung weder verwendet Drittanbieter Bibliothek noch zwingen Sie benutzerdefinierte Methoden auf SQLiteOpenHelper Unterklasse zu nennen, die Datenbank über die Schöpfung zu initialisieren. Es kümmert sich auch um Datenbank als auch Upgrades. Alles, was zu Unterklasse SQLiteOpenHelper getan werden muss.

Voraussetzung:

  1. Die Datenbank, die Sie mit der App versenden möchten. Es sollte enthalten: ein 1x1 Tabelle mit dem Namen android_metadata mit einem Attribute locale den Wert en_US auf die Tabellen zusätzlich mit einzigartigen zu Ihrer Anwendung.

Subclassing SQLiteOpenHelper:

  1. Subclass SQLiteOpenHelper.
  2. Erstellen Sie eine private Methode innerhalb der SQLiteOpenHelper Unterklasse. Diese Methode enthält die Logik, Datenbankinhalte aus der Datenbank-Datei im ‚Assets‘ Ordnern auf die Datenbank im Anwendungspaket Kontext erstellt zu kopieren.
  3. außer Kraft setzen onCreate, onUpgrade und onOpen Methoden des SQLiteOpenHelper.

genug gesagt. Hier geht die SQLiteOpenHelper Unterklasse:

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:
        }
    }
}

Schließlich eine Datenbankverbindung zu erhalten, rufen Sie einfach getReadableDatabase() oder getWritableDatabase() auf der SQLiteOpenHelper Unterklasse, und es wird eine db schaffen kümmern, db Inhalt aus der angegebenen Datei in den ‚Assets‘ Ordner kopieren, wenn die Datenbank nicht vorhanden ist .

Kurz gesagt, können Sie die SQLiteOpenHelper Unterklasse verwenden, um die db in den Aktiv Ordnern ausgeliefert zugreifen wie Sie für eine Datenbank verwenden würden, die SQL-Abfragen in der onCreate() Methode initialisiert werden.

Versand die App mit einer Datenbankdatei, in Android Studio 3.0

Versand die App mit einer Datenbank-Datei ist eine gute Idee für mich. Der Vorteil ist, dass Sie nicht über eine komplexe Initialisierung tun müssen, die manchmal viel Zeit kostet, wenn Ihr Datensatz sehr groß ist.

Schritt 1: Vorbereiten Datenbankdatei

Haben Sie Ihre Datenbank-Datei bereit. Es kann entweder eine Db-Datei oder eine .sqlite-Datei sein. Wenn Sie eine .sqlite Datei verwenden, alles, was Sie tun müssen, ist zu Dateierweiterung Namen zu ändern. Die Schritte sind die gleichen.

In diesem Beispiel bereitete ich eine Datei namens testDB.db. Es hat einen Tisch und einige Beispieldaten in ihm so eingeben Bild Beschreibung hier

Schritt 2: Importieren Sie die Datei in Ihr Projekt

Erstellen Sie den Ordner Assets wenn Sie nicht gehabt haben. Dann kopieren und die Datenbank-Datei in diesen Ordner

 image description hier

Schritt 3: Kopieren Sie die Datei in den Ordner Data App

Sie müssen die Datenbankdatei in der App-Datenordner kopieren, um damit weitere Interaktion zu tun. Dies ist eine einmalige Aktion (Initialisierung) die Datenbank-Datei zu kopieren. Wenn Sie diesen Code mehrmals aufrufen, wird die Datenbankdatei im Datenordner von dem einen in Assets Ordner überschrieben. Diese Überschreibung ist nützlich, wenn Sie die Datenbank in Zukunft während des App-Update aktualisiert werden sollen.

Beachten Sie, dass während der App-Update wird diese Datenbankdatei nicht in der App-Daten-Ordner geändert werden. Nur Deinstallation wird es gelöscht werden.

Die Datenbank muss Datei /databases Ordner kopiert werden. Öffnen Sie den Geräte Datei-Explorer. Geben Sie data/data/<YourAppName>/ Lage. Dies ist der oben erwähnte Standarddatenordner des App. Und standardmäßig wird die Datenbankdatei in diesem Verzeichnis in einem anderen Ordner namens Datenbanken sein

 image description hier

Nun ist die Datei kopiert Prozess ziemlich genau wie das, was Java tut. Verwenden Sie den folgenden Code, um das Kopieren und Einfügen zu tun. Dies ist der Beginn Code. Es kann auch (durch Überschreiben), um die Datenbankdatei in Zukunft zu aktualisieren, verwendet werden.

//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
}

Dann den Ordner aktualisieren Sie den Kopiervorgang

, um zu überprüfen

 image description hier

Schritt 4: Erstellen Datenbank geöffnet Helfer

Erstellen Sie eine Unterklasse für SQLiteOpenHelper, mit connect, in der Nähe, Pfad usw. Ich nannte es 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) {
    }
}

Schritt 5: Erstellen Top-Level-Klasse mit der Datenbank

zu interagieren

Dies wird die Klasse, die Ihre Datenbank-Datei lesen und schreiben. Auch gibt es eine Beispielabfrage aus dem Wert in der Datenbank zu drucken.

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

Schritt 6: Test läuft

Sie den Code testen, indem Sie die folgenden Zeilen Code ausgeführt wird.

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

Hit the Run-Button und jubelt!

 image description hier

Im November 2017 veröffentlichte Google die Raum Persistence Bibliothek

Aus der Dokumentation:

  

Die Zimmer Persistenz-Bibliothek stellt eine Abstraktionsschicht über SQLite   fließend Datenbankzugriff zu ermöglichen, während die volle Leistung Nutzbarmachung von   SQLite.

     

Die Bibliothek helfen Sie, einen Cache der Daten Ihrer App auf einem Gerät erstellen   dass läuft Ihre Anwendung. Dieser Cache, die als App-Single dient   Quelle der Wahrheit, ermöglicht es Benutzern, eine konsistente Kopie der Schlüssel zu sehen   Informationen in Ihrer App, unabhängig davon, ob Benutzer eine   Internet-Verbindung.

Die Zimmer Datenbank hat einen Rückruf, wenn die Datenbank zuerst geöffnet oder erstellt wird. Sie können den Callback verwenden, um Ihre Datenbank zu füllen.

Room.databaseBuilder(context.applicationContext,
        DataDatabase::class.java, "Sample.db")
        // prepopulate the database after onCreate was called
        .addCallback(object : Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                super.onCreate(db)
                // moving to a new thread
                ioThread {
                    getInstance(context).dataDao()
                                        .insert(PREPOPULATE_DATA)
                }
            }
        })
        .build()

Code aus dieser Blog-Post .

Von dem, was ich gesehen habe, sollten Sie eine Datenbank sein werden, Versand, die bereits den Tabellen-Setup und Daten hat. Allerdings, wenn Sie (und je nach Art der Anwendung haben Sie) wollen, können Sie „Upgrade-Datenbankoption“ ermöglichen. Dann, was Sie tun, ist die neueste SQLite-Version herunterladen, erhalten Sie die neueste Insert / Create Aussagen einer Text-Datei online gehostet, die Anweisungen ausführen und von der alten db auf den neuen eine Datenübertragung tun.

Schließlich habe ich es !! Ich habe diesen Link zu helfen, Ihre eigene SQLite Datenbank in Android-Anwendungen , aber es hatte etwas zu ändern.

  1. Wenn Sie viele Pakete haben, sollten Sie die Master-Paketnamen setzen sich hier:

    private static String DB_PATH = "data/data/masterPakageName/databases";

  2. änderte ich die Methode, die Kopien der Datenbank von lokalen Ordner Ordner Emulator! Es hatte ein Problem, wenn der Ordner nicht existieren. Also zunächst einmal, soll es den Pfad überprüfen und, wenn er nicht da ist, sollte es den Ordner erstellen.

  3. Im vorherigen Code wurde die copyDatabase Methode nie, wenn die Datenbank nicht existiert genannt und die checkDataBase Methode verursacht Ausnahme. so änderte ich den Code ein wenig.

  4. Wenn Ihre Datenbank keine Dateierweiterung hat, verwenden Sie die Dateinamen nicht mit ein.

funktioniert es schön für mich, ich hoffe, dass es sehr nützlich sein, whould für u zu

    package farhangsarasIntroduction;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

import android.util.Log;


    public class DataBaseHelper extends SQLiteOpenHelper{

    //The Android's default system path of your application database.
    private static String DB_PATH = "data/data/com.example.sample/databases";

    private static String DB_NAME = "farhangsaraDb";

    private SQLiteDatabase myDataBase;

    private final Context myContext;

    /**
      * Constructor
      * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
      * @param context
      */
    public DataBaseHelper(Context context) {

        super(context, DB_NAME, null, 1);
            this.myContext = context;

    }   

    /**
      * Creates a empty database on the system and rewrites it with your own database.
      * */
    public void createDataBase() {

        boolean dbExist;
        try {

             dbExist = checkDataBase();


        } catch (SQLiteException e) {

            e.printStackTrace();
            throw new Error("database dose not exist");

        }

        if(dbExist){
        //do nothing - database already exist
        }else{

            try {

                copyDataBase();


            } catch (IOException e) {

                e.printStackTrace();
                throw new Error("Error copying database");

            }
    //By calling this method and empty database will be created into the default system path
    //of your application so we are gonna be able to overwrite that database with our database.
        this.getReadableDatabase();


    }

    }

    /**
      * Check if the database already exist to avoid re-copying the file each time you open the application.
      * @return true if it exists, false if it doesn't
      */
    private boolean checkDataBase(){

    SQLiteDatabase checkDB = null;

    try{
        String myPath = DB_PATH +"/"+ DB_NAME;

        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }catch(SQLiteException e){

    //database does't exist yet.
        throw new Error("database does't exist yet.");

    }

    if(checkDB != null){

    checkDB.close();

    }

    return checkDB != null ? true : false;
    }

    /**
      * Copies your database from your local assets-folder to the just created empty database in the
      * system folder, from where it can be accessed and handled.
      * This is done by transfering bytestream.
      * */
    private void copyDataBase() throws IOException{



            //copyDataBase();
            //Open your local db as the input stream
            InputStream myInput = myContext.getAssets().open(DB_NAME);

            // Path to the just created empty db
            String outFileName = DB_PATH +"/"+ DB_NAME;
            File databaseFile = new File( DB_PATH);
             // check if databases folder exists, if not create one and its subfolders
            if (!databaseFile.exists()){
                databaseFile.mkdir();
            }

            //Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(outFileName);

            //transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer))>0){
            myOutput.write(buffer, 0, length);
            }

            //Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();



    }



    @Override
    public synchronized void close() {

        if(myDataBase != null)
        myDataBase.close();

        super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }



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

    }

     you to create adapters for your views.

}

Zur Zeit gibt es keine Möglichkeit, eine SQLite-Datenbank vorab erstellen, mit Ihrem apk zu versenden. Das Beste, was Sie tun können, ist die entsprechende SQL als Ressource speichern und sie von Ihrer Anwendung. Ja, dies führt zu einer Duplizierung von Daten (gleiche Information existiert als resrouce und als Datenbank), aber es gibt keinen anderen Weg, gerade jetzt. Der einzige mildernde Faktor ist die apk-Datei komprimiert wird. Meine Erfahrung ist, 908KB komprimiert auf weniger als 268KB.

Der Thread unten hat die beste Diskussion / Lösung, die ich mit gutem Beispielcode gefunden habe.

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

ich meine CREATE gespeicherte Anweisung als String-Ressource mit Context.getString gelesen werden () und lief es mit SQLiteDatabse.execSQL ().

ich die Daten für meine Einsätze in res / raw / inserts.sql gespeichert (Ich habe die SQL-Datei, 7000+ Linien). Unter Verwendung der Technik von der Verbindung I oben eine Schleife eingetreten, um die Datei zu lesen Zeile für Zeile und concactenated die Daten auf „INSERT INTO tbl VALUE“ und hat einen weiteren SQLiteDatabase.execSQL (). Es macht keinen Sinn bei der Rettung 7000 s „INTO Tabl VALUE INSERT“, wenn sie nur auf concactenated werden können.

Es geht um 20 Sekunden auf dem Emulator nimmt, ich weiß nicht, wie lange diese auf einem echten Telefon nehmen würde, aber es passiert nur einmal, wenn der Benutzer zum ersten Mal die Anwendung startet.

Versand der Datenbank innerhalb des apk und kopieren sie dann verdoppelt sich auf /data/data/... die Größe der Datenbank (1 in apk, 1 in data/data/...) und die apk Größe (natürlich) erhöhen. So Ihre Datenbank sollte nicht zu groß sein.

Android bietet bereits eine Version bewusste Ansatz der Datenbankverwaltung. Dieser Ansatz wurde im Rahmen baracus für Android-Anwendungen genutzt.

Es ermöglicht Ihnen, die Datenbank zusammen zu verwalten der gesamte Version Lebenszyklus einer App, beeing die Lage, die sQLite-Datenbank aus einer vorherigen Version auf den aktuellen zu aktualisieren.

Auch ermöglicht es Ihnen, heiß laufen -backups und Heißwiederherstellung der SQLite.

Ich bin nicht 100% sicher, aber eine Hot-Wiederherstellung für ein spezifisches Gerät kann es Sie ermöglichen, eine vorbereitete Datenbank in Ihrer App zu versenden. Aber ich bin nicht sicher über die Datenbank Binärformat, die auf bestimmte Geräte spezifisch sein könnte, Lieferanten oder Gerätegenerationen.

Da das Zeug ist Apache License 2, können Sie einen Teil des Codes wiederzuverwenden, die gefunden werden können auf github

EDIT:

Wenn Sie nur Daten versenden möchten, könnten Sie instanziieren und POJOs bei den Anwendungen persistierenden zum ersten Mal starten. Baracus bekam eine integrierte Unterstützung dazu (Built-in Schlüsselwertspeichern für Konfigurationsinformationen, zum Beispiel „APP_FIRST_RUN“ plus ein After-Kontext-Bootstrap-Haken, um Post-Launch-Operationen auf dem Kontext zu laufen). Dies ermöglicht Ihnen, eng gekoppelt Daten mit Ihrer Anwendung ausgeliefert zu haben; in den meisten Fällen auf meine Anwendungsfälle ausgestattet.

Wenn die erforderlichen Daten nicht zu groß ist (Grenzen Ich weiß es nicht, würde auf eine Menge Dinge abhängen), könnten Sie auch die Daten herunterladen (in XML, JSON, was auch immer) von einer Website / Webapp. Nach dem Empfang, führen Sie die SQL-Anweisungen, um die empfangenen Daten der Erstellung Ihre Tabellen und die Daten einfügen.

Wenn Sie Ihre mobilen app viele Daten enthält, könnte es später einfacher, die Daten in den installierten Anwendungen mit genauen Daten oder Änderungen zu aktualisieren.

Ich schrieb ein Bibliothek diesen Prozess zu vereinfachen.

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

Es wird eine Datenbank aus assets/databases/myDb.db Datei erstellen. Darüber hinaus finden Sie alle jene Funktionalität erhalten:

  • Laden Datenbank aus der Datei
  • Synchronisierte Zugriff auf die Datenbank
  • Verwenden von SQLite-android von requery, Android spezifische Verteilung der neuesten Versionen von SQLite.

Clone es von Github .

Ich verwende ORMLite und unter Code für mich gearbeitet

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) {

    }
}

Bitte beachten Sie, dass der Code extrahiert Datenbankdatei aus einer ZIP-Datei in Vermögenswerte

modifizierte ich die Klasse und die Antworten auf die Frage und schrieb eine Klasse, die die Datenbank über DB_VERSION ermöglicht aktualisieren.

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;
    }
}

eine Klasse verwenden.

In der Aktivitätsklasse, Variablen deklarieren.

private DatabaseHelper mDBHelper;
private SQLiteDatabase mDb;

In der onCreate Methode schreiben Sie den folgenden Code ein.

mDBHelper = new DatabaseHelper(this);

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

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

Wenn Sie eine Datenbank-Datei in den Ordner res hinzufügen / raw dann die folgende Änderung der Klasse verwenden.

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top