Dodávat aplikace s databází

hlasů
870

Pokud vaše aplikace vyžaduje databázi a je dodáván s vestavěným dat, co je nejlepší způsob, jak loď této žádosti? Měl bych:

  1. Precreate databáze SQLite a patří to v .apk?

  2. Patří SQL příkazů s aplikací a nechte jej vytvořit databázi a vložit data při prvním použití?

Nevýhody vidím, jsou:

  1. Možné SQLite verze nesoulad může způsobit problémy, a já v současné době nevím, kde je umístěna databáze by mělo jít a jak se k nim dostat.

  2. To může trvat opravdu dlouho vytvořit a naplnit databázi na zařízení.

Nějaké návrhy? Ukazatele na dokumentaci týkající se případné problémy by bylo velmi ocenil.

Položena 04/02/2009 v 21:11
zdroj uživatelem
V jiných jazycích...                            


16 odpovědí

hlasů
440

Právě jsem našel způsob, jak to udělat v ReignDesign blogu v článku nazvaném Použití vlastní SQLite databáze v aplikacích pro Android . V podstatě precreate databázi, dát ji do svého seznamu majetku v APK a při prvním použití kopii „/ data / data / YOUR_PACKAGE / databází /“ adresáře.

Odpovězeno 06/03/2009 v 20:23
zdroj uživatelem

hlasů
193

Existují dvě možnosti pro vytváření a aktualizaci databází.

Jedním z nich je vytvoření databáze externě, umístěte jej do složky majetku projektu a zkopírujte celou databázi odtamtud. Je to mnohem rychlejší, pokud databáze obsahuje mnoho tabulek a dalších komponentů. Upgrady jsou spuštěny změnou číslo verze databáze v adresáři / hodnoty / soubor strings.xml res. Inovace by pak být dosaženo tím, že vytvoří novou databázi externě, nahrazovat staré databáze do složky aktiva s novou databází, ukládání staré databáze do interního úložiště pod jiným jménem, kopírování novou databázi z majetku složky do vnitřní paměti, přenášet všechny dat ze staré databáze (který byl přejmenován dříve) do nové databáze a nakonec odstraněním staré databáze. Můžete si vytvořit databázi původně pomocí SQLite Manager, prohlížeče Firefox spouštět vaše prohlášení vytváření SQL.

Druhou možností je vytvořit databázi interně ze souboru SQL. To není tak rychlé, ale zpoždění by pravděpodobně neznatelné pro uživatele v případě, že databáze obsahuje pouze několik tabulek. Upgrady jsou spuštěny změnou číslo verze databáze v adresáři / hodnoty / soubor strings.xml res. Inovace by pak být provedena zpracováním upgrade SQL soubor. Údaje v databázi zůstane nezměněna kromě případů, kdy jeho obal je odstraněn, například smazat tabulku.

Níže uvedený příklad ukazuje, jak lze použít buď metodu.

Zde je ukázkový soubor create_database.sql. Je třeba umístit do složky majetku projektu pro vnitřní metodou nebo zkopírovány do SQL „Execute‘ z SQLite Manager vytvořit databázi pro externí metodu. (Poznámka:. Všimněte si, že komentář k tabulce požadovaných Android)

--Android requires a table named 'android_metadata' with a 'locale' column
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US');
INSERT IGNORE  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"; 

Zde je ukázkový soubor update_database.sql. Je třeba umístit do složky majetku projektu pro vnitřní metodou nebo zkopírovány do SQL „Execute‘ z SQLite Manager vytvořit databázi pro externí metody. (Poznámka: Všimněte si, že všechny tři typy SQL připomínky budou ignorovány podle sQL parseru, který je obsažen v tomto příkladu).

--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 IGNORE  INTO "picnic_table" VALUES ('paper');

Zde je vstup do do spisu /res/values/strings.xml na číslo verze databáze.

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

Zde je činnost, která přistupuje k databázi a poté ji využívá. ( Poznámka: Možná budete chtít spustit kód databáze v samostatném vlákně, pokud používá mnoho zdrojů. )

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

    }
}

Zde je databáze pomocník třídy, kde je vytvořen nebo je-li to nutné aktualizovat databázi. (Poznámka: Android vyžaduje vytvořit třídu, která rozšiřuje SQLiteOpenHelper s cílem pracovat s SQLite databáze.)

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.
     */

}

Zde je třída FileHelper která obsahuje metody pro kopírování souborů z bytového streamu a analýza sql souborů.

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

}
Odpovězeno 26/01/2011 v 22:22
zdroj uživatelem

hlasů
124

Knihovna SQLiteAssetHelper činí tento úkol opravdu jednoduchý.

Je snadné přidat jako gradle závislost (ale Jar je k dispozici také pro Ant / Eclipse), a spolu s dokumentací lze nalézt na adrese:
https://github.com/jgilfelt/android-sqlite-asset-helper

Jak je vysvětleno v dokumentaci:

  1. Přidat závislost na gradle sestavení souboru vašeho modulu:

    dependencies {
        compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
    }
    
  2. Zkopírovat databázi do adresáře aktiv, do podadresáře s názvem assets/databases. Například:
    assets/databases/my_database.db

    (Případně můžete komprimovat databáze v zip souboru, jako je assets/databases/my_database.zip. To není potřeba, protože APK je komprimován jako celek již).

  3. Vytvořte třídu, například:

    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);
        }
    }
    
Odpovězeno 03/08/2012 v 22:08
zdroj uživatelem

hlasů
23

Myslím, že nejlepší a nejnovější způsob, jak dodnes používá SQLiteAssetHelpertřídu.

Tento výukový program vás dokonale přes import a použití externí databáze v Androidu

Android SQLiteAssetHelperknihovna umožňuje vytvořit si SQLite databázi ve svém stolním počítači, a importovat a používat jej ve své aplikaci pro Android. Pojďme vytvořit jednoduchou aplikaci k prokázání používání této knihovny.

Krok 1 : Vytvoření databáze quotes.db pomocí oblíbených aplikací SQLite databáze (DB Browser pro SQLite je přenosná multiplatformní freeware, který může být použit k vytvoření databáze a upravovat SQLite). Vytvořit tabulku ‚cituje‘ s jedním sloupcem ‚citát‘. Vložte nějaké náhodné citáty do tabulky ‚cituje‘.

Krok 2 : Databázi lze importovat do projektu, a to buď přímo, jak je, nebo jako komprimovaného souboru. Komprimovaný soubor se doporučuje, je-li vaše databáze je příliš velké. Můžete vytvořit buď ZIP kompresi nebo GZkompresi.

Název souboru z komprimovaného souboru db musí být quotes.db.zip, pokud používáte kompresi ZIP nebo quotes.db.gz, pokud používáte kompresi GZ.

Krok 3 : Vytvoření nové aplikace External Database Demos názvem balíčku com.javahelps.com.javahelps.externaldatabasedemo.

Krok 4 : Otevřete build.gradle: soubor (Module APP) a přidejte následující závislost.

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

Poté, co jste uložili build.gradlesoubor, klikněte na odkaz na ‚Synchronizovat‘ aktualizovat projekt. Můžete synchronizovat build.gradlepomocí kliknutí pravým tlačítkem myši na build.gradlesoubor a vybráním Synchronize build.gradlevolby stejně.

Krok 5 : Klikněte pravým tlačítkem myši na složku aplikace a vytvořit novou složku aktiv.

Krok 6 : Vytvoření nové složky ‚databáze‘ uvnitř složky majetku.

Krok 7 : Zkopírujte a vložte quotes.db.zipsoubor uvnitř assets/databasessložky.

Krok 8 : Vytvoření nové třídyDatabaseOpenHelper

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.

Krok 9 : Vytvořte novou třídu DatabaseAccessa zadejte kód, jak je uvedeno níže. Další podrobnosti o této třídě je k dispozici na Android Advanced Database 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,

aktualizovat a odstranit všechny řádky v databázi jako obvykle. Pro více informací, tento odkaz Database Advanced Android.

Všechny setupy databázové související jsou dokončeny a nyní musíme vytvořit ListViewpro zobrazení nabídky.

Krok 10 : Přidání ListViewve vašem 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>  

Krok 11 : Najděte objekt ListViewv onCreatemetodě MainActivitya krmit citace, které se čtou tvoří databázi.

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

Krok 12 : Uložte všechny změny a spustit aplikaci.

Kromě tohoto článku si můžete stáhnout SQLiteAssetHelper zde

Odpovězeno 21/01/2016 v 08:01
zdroj uživatelem

hlasů
11

Mé řešení ani využívá jakoukoli knihovnu třetí strany, ani vás nutí zavolat vlastní metody na SQLiteOpenHelperpodtřídy inicializovat databázi na tvorbu. To se také stará o vylepšení databázových stejně. Vše, co je třeba udělat, je na podtřídy SQLiteOpenHelper.

Předpoklad:

  1. Databáze, které si přejete, aby loď s aplikací. Měl by obsahovat 1x1 tabulku s názvem android_metadatas atributem locale, který má hodnotu en_USkromě tabulek specifických pro aplikaci.

podtříd SQLiteOpenHelper:

  1. Podtřídy SQLiteOpenHelper.
  2. Vytvořit privatemetodu v rámci SQLiteOpenHelperpodtřídy. Tato metoda obsahuje logiku kopírovat obsah databáze z databázového souboru ve složce ‚majetek‘ do databáze vytvořené v rámci balíku aplikací.
  3. Potlačit onCreate, onUpgrade a onOpen metody SQLiteOpenHelper.

Dost řekl. Zde jde i SQLiteOpenHelperpodtřídy:

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

A konečně, aby se připojení k databázi, stačí zavolat getReadableDatabase()nebo getWritableDatabase()na SQLiteOpenHelperpodtřídy, a to se postará o vytvoření db, kopírování obsahu db ze zadaného souboru ve složce ‚aktiva‘, pokud neexistuje databáze.

Stručně řečeno, můžete použít SQLiteOpenHelperpodtřídy pro přístup k db dodáno ve složce aktiv, stejně jako byste použili k databázi, která je ve výchozím stavu pomocí SQL dotazů v onCreate()metodě.

Odpovězeno 26/03/2015 v 14:56
zdroj uživatelem

hlasů
7

Lodní aplikace s souboru databáze, v Android Studio 3.0

Lodní aplikace s souboru databáze je dobrý nápad pro mě. Výhodou je, že nemusíte dělat složité inicializace, které někdy stojí spoustu času, pokud vaše množina dat je obrovský.

Krok 1: Příprava souboru databáze

Vyjádřete svůj databázový soubor připraven. Může to být buď soubor db nebo .sqlite soubor. Používáte-li .sqlite soubor, vše, co potřebujete udělat, je změnit názvy příponu souboru. Tyto kroky jsou stejné.

V tomto příkladu jsem připravil soubor nazvaný testDB.db. To má jednu tabulku a ukázkových dat v něm takhle zadejte popis obrázku zde

Krok 2: Import souboru do projektu

Vytvoření složky majetku, pokud jste měl jeden. Potom zkopírujte a vložte soubor databáze do této složky

zadejte popis obrázku zde

Krok 3: Zkopírujte soubor do složky dat o aplikaci

Musíte zkopírovat soubor databáze do datové složky dané aplikace, aby se do další interakci s ním. Jedná se akce jeden čas (inicializace) pro zkopírování souboru databáze. Voláte-li tento kód vícekrát, bude databázový soubor ve složce dat přepsán ten v složky majetku. Toto přepsání proces je užitečný, když chcete aktualizovat databázi v budoucnu při aktualizaci aplikace.

Všimněte si, že při aktualizaci aplikace tento soubor databáze nebude měnit v datové složky dané aplikace. Pouze odinstalovat jej odstranit.

Soubor databáze je třeba zkopírovat do /databasessložky. Otevřít soubor Device Explorer. Zadejte data/data/<YourAppName>/umístění. To je výchozí datový adresář této aplikace je uvedeno výše. A ve výchozím nastavení je soubor databáze bude místo v jiné složce s názvem databází v tomto adresáři

zadejte popis obrázku zde

Nyní je proces kopírování souborů je skoro stejně jako to, co Java dělá. Použijte následující kód dělat kopírovací pasty. Jedná se o zahájení kód. To může být také použita k aktualizaci (přepsáním) soubor databáze v budoucnu.

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

Pak aktualizujte složku ověřit proces kopírování

zadejte popis obrázku zde

Krok 4: Vytvoření databáze otevřené pomocník

Vytvořit podtřídy pro SQLiteOpenHelper, s connect, úzkým, cesty, atd. Pojmenoval jsem jiDatabaseOpenHelper

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

Krok 5: Vytvoření špičku úrovně interakce s databází

To bude třída, která čtení a zápis soubor databáze. Také tam je ukázkový dotaz vytisknout hodnotu v databázi.

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

Krok 6: Test běží

Testovací kód spuštěním následující řádky kódu.

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

Stiskněte tlačítko run a fandit!

zadejte popis obrázku zde

Odpovězeno 07/11/2017 v 20:23
zdroj uživatelem

hlasů
5

V listopadu 2017 Google uvolnil pokoje Persistence Library

Z dokumentace:

Knihovna Room persistence poskytuje abstraktní vrstvu nad SQLite umožnit plynulý přístup do databáze a zároveň využití plné síle SQLite.

Knihovna vám pomůže vytvořit cache data aplikace na zařízení, které je spuštěn vaši aplikaci. Tato vyrovnávací paměť, která slouží jako jediný zdroj své aplikace pravdy, umožňuje uživatelům prohlížet konzistentní kopie klíčových informací v rámci aplikace, bez ohledu na to, zda mají uživatelé připojení k internetu.

Databáze Room má zpětné volání, je-li databáze poprvé vytvořena nebo otevřeny. Můžete použít vytvořit zpětné volání k naplnění databáze.

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

Kód z tohoto blogu .

Odpovězeno 28/11/2017 v 17:21
zdroj uživatelem

hlasů
5

Nakonec jsem to udělal !! Použil jsem tento odkaz pomoc s použitím vlastní SQLite databáze v aplikacích pro Android , ale musel změnit trochu.

  1. Pokud máte mnoho balíků byste měli dát název master balíčku zde:

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

  2. Změnil jsem způsob, který kopíruje databáze z lokální složky na emulátoru složky! Mělo to nějaký problém, kdy neexistovalo, že složka. Takže v první řadě, měla by kontrolovat cestu, a pokud to tam není, měl by vytvořit složku.

  3. V předchozím kódu je copyDatabasemetoda nebyla nikdy volána, když neexistovala databáze a checkDataBasezpůsob způsobil výjimku. tak jsem změnil kód trochu.

  4. Pokud databáze neobsahuje příponu souboru, nepoužívejte název souboru s jedním.

funguje to příjemné pro mě, doufám, že to whould být užitečné pro u příliš

    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.

}
Odpovězeno 14/02/2014 v 10:03
zdroj uživatelem

hlasů
5

Z toho, co jsem viděl, měli byste být lodní databázi, která již obsahuje nastavení tabulky a data. Nicméně, pokud chcete (a v závislosti na typu aplikace máte), můžete povolit „upgrade databáze možnost“. Potom, co udělat, je stáhnout nejnovější verze sqlite, získat nejnovější Vložit / Create prohlášení textového souboru hostované online, spouštět příkazy a provést přenos dat ze starého db na novou.

Odpovězeno 04/02/2009 v 21:14
zdroj uživatelem

hlasů
4

Lodní databázi uvnitř APK a pak kopírovat do /data/data/...zdvojnásobí velikost databáze (1 v APK, 1 v data/data/...), a zvýší velikost APK (samozřejmě). Takže vaše databáze by neměla být příliš velká.

Odpovězeno 12/08/2012 v 21:28
zdroj uživatelem

hlasů
4

V současné době neexistuje žádný způsob, jak precreate databázi SQLite lodním s APK. Nejlepší, co můžete udělat, je uložit na příslušnou SQL jako zdroje a spustit je z aplikace. Ano, to vede ke zdvojování dat (stejné informace existuje jako resrouce a jako databáze), ale není tam žádný jiný způsob, jak právě teď. Jediným zmírňování faktorem je soubor APK je komprimován. Moje zkušenost je, 908 KB komprimuje na méně než 268KB.

Nit má pod nejlepší diskusní / řešení, Zjistil jsem, že s dobrým ukázkový kód.

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

I uloženy my CREATE jako zdroj řetězec, který bude číst Context.getString () a běžel s SQLiteDatabse.execSQL ().

I uložena data pro mé vložek v RES / RAW / inserts.sql (Vytvořil jsem soubor SQL 7000+ linky). Za použití techniky z odkazu výše jsem vstoupil smyčku, číst soubor řádek po řádku a concactenated data na „INSERT INTO ignorovat tbl hodnoty“ a udělal další SQLiteDatabase.execSQL (). Nemá smysl ukládání 7000 „INSERT INTO ignorovat tbl hodnota“ S kdy mohou být jen concactenated dál.

To trvá asi dvacet sekund na emulátoru, nevím, jak dlouho bude trvat na konkrétním telefonu, ale to stane jen jednou, když uživatel poprvé spustí aplikaci.

Odpovězeno 05/02/2009 v 00:32
zdroj uživatelem

hlasů
3

Android již poskytuje přístup verze vědomi o správu databází. Tento přístup byl hybnou silou v rámci Baracus pro aplikace Android.

To umožňuje spravovat databázi podél celého životního cyklu verze app, bytí moci aktualizovat databáze SQLite z jakékoliv předchozí verze na aktuální.

Také, to vám umožní spustit hot-zálohování a teplé oživení SQLite.

Nejsem si 100% jistý, ale hot-zotavení pro specifické zařízení může umožnit, aby loď připravenou databázi v aplikaci. Ale nejsem si jistý databáze binárním formátu, které by mohly být specifické pro určité zařízení, prodejců nebo generací zařízení.

Vzhledem k tomu, materiál je Apache Licence 2, bez obav znovu použít jakoukoliv část kódu, který lze nalézt na GitHub

UPRAVIT :

Chcete-li pouze k odeslání dat, můžete zvážit spouštění a přetrvávající objektů POJO v aplikacích prvním spuštění. Baracus dostal vestavěnou podporu pro toto (Vestavěný klíčů hodnoty konfiguračních infos, například „APP_FIRST_RUN“ plus po-context-bootstrap háček, aby běžel po spuštění operace na kontextu). To vám umožní mít pevně spojené údaje dodané s aplikací; ve většině případů vybaveny mých případů použití.

Odpovězeno 28/10/2014 v 06:41
zdroj uživatelem

hlasů
3

V případě, že požadované údaje nejsou příliš velké (limity Nevím, bude záviset na mnoha věcech), můžete také stahovat data (ve formátu XML, JSON, cokoliv) z webové stránky / webapp. Po obdržení, spouštět SQL příkazy pomocí přijatá data vytváření tabulek a vkládání dat.

Pokud váš mobilní aplikace obsahuje velké množství dat, může to být snazší později aktualizovat data v nainstalovaných aplikací s přesnějších údajů nebo změny.

Odpovězeno 21/12/2009 v 11:12
zdroj uživatelem

hlasů
2

Já používám ORMLite a pod kód pracoval pro 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) {

    }
}

Upozorňujeme, že kód extrahuje soubor databáze ze souboru zip aktiv

Odpovězeno 12/07/2017 v 06:27
zdroj uživatelem

hlasů
2

Napsal jsem knihovnu , aby tento proces zjednodušit.

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

To vytvoří databázi ze assets/databases/myDb.dbsouboru. Kromě toho budete mít všechny tyto funkce:

  • Zatížení databáze ze souboru
  • Synchronizovaný přístup k databázi
  • Používání sqlite-androida by REQUERY, Android Konkrétní rozdělení nejnovější verze SQLite.

Naklonovat ji z GitHub .

Odpovězeno 10/07/2016 v 05:41
zdroj uživatelem

hlasů
1

Upravil jsem třídu a odpovědi na otázku, a napsal třídu, která umožňuje aktualizace databáze prostřednictvím DB_VERSION.

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

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

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

Použití třídy.

Ve třídě aktivity, deklarovat proměnné.

private DatabaseHelper mDBHelper;
private SQLiteDatabase mDb;

V onCreate způsobu, napište následující kód.

mDBHelper = new DatabaseHelper(this);

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

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

Přidáte-li databázový soubor do složky res / suroviny použijte následující úpravy třídy.

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

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

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

Odpovězeno 12/04/2017 v 17:14
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more