android 폴더 데이터베이스로 응용 프로그램 제공




adb run as (13)

애플리케이션에 데이터베이스가 필요하며 데이터가 내장되어있는 경우 해당 애플리케이션을 제공하는 가장 좋은 방법은 무엇입니까? 해야할까요?

  1. SQLite 데이터베이스를 미리 작성하여 .apk 포함 시키십시오.

  2. 응용 프로그램에 SQL 명령을 포함시키고 데이터베이스를 만들고 처음 사용할 때 데이터를 삽입합니까?

내가 볼 수있는 단점은 다음과 같습니다.

  1. 가능한 SQLite 버전 불일치로 인해 문제가 발생할 수 있으며 현재 데이터베이스가 어디로 가야하고 어떻게 액세스해야하는지 모릅니다.

  2. 장치에서 데이터베이스를 작성하고 채우는 데 정말로 오랜 시간이 걸릴 수 있습니다.

어떤 제안? 모든 문제에 관한 문서의 포인터는 크게 감사하겠습니다.


ORMLite를 사용하고 있으며 아래 코드가 저에게 효과적입니다.

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

    }
}

코드는 애셋의 zip 파일에서 데이터베이스 파일을 추출합니다.


필요한 데이터가 너무 크지 않은 경우 (많이 알지 못하거나 많은 것에 의존 할 수 있음) 웹 사이트 / 웹 애플리케이션에서 XML, JSON 등의 데이터를 다운로드 할 수 있습니다. 수신 한 후 수신 된 데이터를 사용하여 SQL 문을 실행하여 테이블을 작성하고 데이터를 삽입하십시오.

모바일 앱에 많은 양의 데이터가있는 경우 나중에 설치된 앱의 데이터를 더 정확한 데이터 또는 변경 사항으로 업데이트하는 것이 더 쉬울 수도 있습니다.


2017 년 11 월, Google은 Room Persistence Library

문서에서 :

Room 퍼시스턴스 라이브러리는 SQLite의 추상화 레이어를 제공하여 SQLite의 모든 기능을 활용하면서 유창한 데이터베이스 액세스를 허용합니다.

라이브러리를 사용하면 앱을 실행하는 기기에서 앱의 데이터 캐시를 만들 수 있습니다. 이 캐시는 앱의 단일 소스로 사용되며 사용자가 인터넷에 연결되어 있는지 여부에 관계없이 앱에서 키 정보의 일관된 사본을 볼 수 있습니다.

방 데이터베이스는 데이터베이스를 처음 만들거나 열 때 콜백합니다. create callback을 사용하여 데이터베이스를 채울 수 있습니다.

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

블로그 게시물의 코드 .


내가 본 것에서는 이미 테이블 설정 및 데이터가있는 데이터베이스를 제공해야합니다. 그러나 원하는 경우 (그리고 응용 프로그램의 유형에 따라) "데이터베이스 업그레이드 옵션"을 허용 할 수 있습니다. 그런 다음 최신 sqlite 버전을 다운로드하고, 온라인으로 호스팅되는 텍스트 파일의 최신 Insert / Create 문을 가져 와서 명령문을 실행하고 이전 db에서 새로운 db로 데이터 전송을 수행합니다.


나는 이 과정을 단순화하기 위해 library 을 썼다 .

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

assets/databases/myDb.db파일 로부터 dataBase를 생성 합니다. 또한 모든 기능을 사용할 수 있습니다.

  • 파일에서 데이터베이스로드
  • 데이터베이스에 대한 동기화 된 액세스
  • 다시 쿼리로 sqlite-android 를 사용 하면 최신 SQLite 버전의 Android 전용 배포.

library 에서 그것을 복제하십시오 .


Android는 이미 버전 관리 방식의 데이터베이스 관리 방식을 제공합니다. 이 접근법은 안드로이드 어플리케이션 용 BARACUS 프레임 워크에서 활용되었습니다.

그것은 이전 버전에서 현재 버전으로 sqlite 데이터베이스를 업데이트 할 수 있기 때문에 앱의 전체 버전 라이프 사이클을 따라 데이터베이스를 관리 할 수있게합니다.

또한 SQLite의 핫 백업 및 핫 복구를 실행할 수 있습니다.

100 % 확신 할 수는 없지만 특정 장치에 대한 최신 복구 기능을 사용하면 준비된 데이터베이스를 응용 프로그램에서 제공 할 수 있습니다. 그러나 특정 장치, 공급 업체 또는 장치 세대에 특정한 데이터베이스 이진 형식에 대해서는 확신 할 수 없습니다.

그 물건이 Apache License 2이기 때문에 github에서 찾을 수있는 코드의 일부를 자유롭게 재사용 할 수 있습니다.

편집하다 :

데이터 만 전달하려는 경우 먼저 응용 프로그램에서 POJO를 인스턴스화하고 지속하는 것이 좋습니다. BARACUS는 내장 된 키 값 저장소 (예 : "APP_FIRST_RUN"및 컨텍스트에서 실행 후 작업을 실행하기위한 컨텍스트 부트 스트랩 후크)와 같은 구성 정보 용 내장 키 값 저장소를 제공합니다. 이를 통해 앱과 밀접하게 결합 된 데이터를 제공 할 수 있습니다. 대부분의 경우 이것이 내 사용 사례에 적합합니다.


마침내 나는 그것을했다!! 나는이 링크 도움말을 안드로이드 애플리케이션에서 자신의 SQLite 데이터베이스를 사용 했지만 약간 변경해야했다.

  1. 패키지가 많은 경우 여기에 마스터 패키지 이름을 입력해야합니다.

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

  2. 로컬 폴더에서 에뮬레이터 폴더로 데이터베이스를 복사하는 방법을 변경했습니다! 폴더가 존재하지 않을 때 문제가 발생했습니다. 먼저 경로를 확인하고 거기에 없으면 폴더를 만들어야합니다.

  3. 이전 코드에서는 copyDatabase데이터베이스가 존재하지 않아 checkDataBase메서드가 예외를 발생 시킬 때 메서드가 호출되지 않았습니다 . 그래서 코드를 조금 변경했습니다.

  4. 데이터베이스에 파일 확장자가 없으면 파일 이름에 파일 확장명을 사용하지 마십시오.

그것은 나를 위해 좋은 작품, 나는 그것도 whl 유용 할 희망 Logged

    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.

}

방금 Android 애플리케이션에서 SQLite 데이터베이스를 사용 하는 기사에서 ReignDesign blog 에서이 작업을 수행 할 수있는 방법을 찾았습니다. 기본적으로 데이터베이스를 사전 작성하고 apk의 자산 디렉토리에 넣은 다음 /data/data/YOUR_PACKAGE/databases/ 디렉토리에 copy를 먼저 사용하십시오.


Android Studio 3.0에서 데이터베이스 파일로 앱 전송

데이터베이스 파일로 앱을 운송하는 것이 좋습니다. 장점은 복잡한 초기화를 수행 할 필요가 없으며 데이터 세트가 큰 경우 시간이 오래 걸리는 경우가 있습니다.

1 단계 : 데이터베이스 파일 준비

데이터베이스 파일을 준비하십시오. .db 파일 또는 .sqlite 파일이 될 수 있습니다. .sqlite 파일을 사용하는 경우 파일 확장명을 변경하기 만하면됩니다. 단계는 동일합니다.

이 예제에서는 testDB.db라는 파일을 준비했습니다. 그것은 하나의 테이블과 이것의 샘플 데이터를 가지고 있습니다.

2 단계 : 프로젝트로 파일 가져 오기

자산 폴더가 없으면 자산 폴더를 만듭니다. 그런 다음 데이터베이스 파일을 복사하여이 폴더에 붙여 넣습니다.

3 단계 : 파일을 앱의 데이터 폴더에 복사합니다.

더 이상의 상호 작용을 수행하려면 데이터베이스 파일을 앱의 데이터 폴더에 복사해야합니다. 이것은 데이터베이스 파일을 복사하기위한 일회성 작업 (초기화)입니다. 이 코드를 여러 번 호출하면 데이터 폴더의 데이터베이스 파일이 자산 폴더에있는 파일로 덮어 쓰게됩니다. 이 덮어 쓰기 프로세스는 나중에 앱을 업데이트하는 동안 데이터베이스를 업데이트하려는 경우에 유용합니다.

앱 업데이트 중이 데이터베이스 파일은 앱의 데이터 폴더에서 변경되지 않습니다. 제거 만이 삭제합니다.

데이터베이스 파일을 /databases폴더에 복사해야 합니다. 장치 파일 탐색기를 엽니 다. data/data/<YourAppName>/위치를 입력하십시오 . 위에서 언급 한 앱의 기본 데이터 폴더입니다. 그리고 기본적으로 데이터베이스 파일은이 디렉토리의 databases 폴더에 저장됩니다.

이제 복사 파일 프로세스는 Java가 수행하는 것과 거의 같습니다. 복사 붙여 넣기를 수행하려면 다음 코드를 사용하십시오. 이것은 시작 코드입니다. 나중에 데이터베이스 파일을 갱신 (겹쳐 쓰기)하는 데 사용할 수도 있습니다.

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

그런 다음 폴더를 새로 고침하여 복사 프로세스를 확인하십시오.

4 단계 : 데이터베이스 열기 도우미 만들기

SQLiteOpenHelper연결, 닫기, 경로 등 으로 하위 클래스를 만듭니다 . 이름을 지정했습니다.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) {
    }
}

5 단계 : 데이터베이스와 상호 작용할 최상위 클래스 만들기

이 클래스는 데이터베이스 파일을 읽고 쓰는 클래스입니다. 또한 데이터베이스의 값을 인쇄하는 샘플 쿼리가 있습니다.

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

6 단계 : 테스트 실행

다음 코드 줄을 실행하여 코드를 테스트하십시오.

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

실행 버튼을 치고 응원해라!


내 솔루션도 타사 라이브러리를 사용하지 않으며 SQLiteOpenHelper 하위 클래스에서 사용자 정의 메서드를 호출하여 생성시 데이터베이스를 초기화하도록 강요하지도 않습니다. 또한 데이터베이스 업그레이드도 처리합니다. 이 모든 작업을 수행하려면 SQLiteOpenHelper 를 하위 클래스 화 SQLiteOpenHelper 합니다.

선수 과목 :

  1. 앱과 함께 제공하려는 데이터베이스입니다. 앱에 고유 한 테이블 외에도 값이 en_US 인 속성 locale 이있는 android_metadata 라는 1x1 테이블 이 있어야합니다 .

SQLiteOpenHelper 서브 클래 SQLiteOpenHelper :

  1. SQLiteOpenHelper 서브 클래스 SQLiteOpenHelper .
  2. SQLiteOpenHelper 하위 클래스 내에 private 메서드를 만듭니다. 이 메소드에는 데이터베이스 내용을 'assets'폴더에있는 데이터베이스 파일에서 응용 프로그램 패키지 컨텍스트로 작성된 데이터베이스로 복사하는 논리가 들어 있습니다.
  3. onUpgrade onCreate , onUpgrade onOpen 메서드를 SQLiteOpenHelper 합니다.

충분했다. 다음은 SQLiteOpenHelper 하위 클래스입니다.

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

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

    private boolean createDb = false, upgradeDb = false;

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

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

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

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

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

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

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

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

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

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

마지막으로, 데이터베이스 연결을 얻으려면 SQLiteOpenHelper 하위 클래스에서 getReadableDatabase() 또는 getWritableDatabase() 를 호출하면됩니다. 데이터베이스를 만들지 않으면 'assets'폴더의 지정된 파일에서 db 내용을 복사합니다. 있다.

간단히 말해 SQLiteOpenHelper 하위 클래스를 사용하여 onCreate() 메서드에서 SQL 쿼리를 사용하여 초기화 된 데이터베이스에 사용할 때와 마찬가지로 assets 폴더에있는 db에 액세스 할 수 있습니다.


apk 내부의 데이터베이스를 배송 한 다음 데이터베이스 /data/data/...의 크기를 두 배로 data/data/...늘리면 (apk 1, 1 in ) apk 크기가 증가합니다 (당연히). 따라서 데이터베이스가 너무 커야합니다.


오늘과 SQLiteAssetHelper 클래스를 사용하는 가장 좋은 방법은 같아요.

이 튜토리얼 은 Android에서 외부 데이터베이스 가져 오기 및 사용 하기를 완벽하게 안내합니다.

Android SQLiteAssetHelper 라이브러리를 사용하면 데스크탑 컴퓨터에서 SQLite 데이터베이스를 빌드하고 Android 애플리케이션에서 가져 와서 사용할 수 있습니다. 이 라이브러리의 응용 프로그램을 보여주기 위해 간단한 응용 프로그램을 만듭니다.

1 단계 : 선호하는 SQLite 데이터베이스 응용 프로그램을 사용하여 quotes.db 데이터베이스를 만듭니다 (SQLite 용 DB 브라우저는 이식 가능한 크로스 플랫폼 프리웨어로 SQLite 데이터베이스를 만들고 편집하는 데 사용할 수 있습니다). 단일 열 'quote'로 'quotes'테이블을 생성하십시오. 테이블 '따옴표'에 임의의 따옴표를 삽입하십시오.

2 단계 : 데이터베이스를 그대로 프로젝트에 직접 또는 압축 파일로 가져올 수 있습니다. 데이터베이스 크기가 너무 큰 경우 압축 된 파일을 사용하는 것이 좋습니다. ZIP 압축 또는 GZ 압축을 만들 수 있습니다.

GZ 압축을 사용하는 경우 ZIP 압축 또는 quotes.db.gz 사용하는 경우 압축 된 db 파일의 파일 이름은 quotes.db.zip 이어야합니다.

3 단계 : 패키지 이름이 com.javahelps.com.javahelps.externaldatabasedemo 새로운 어플리케이션 External Database Demo com.javahelps.com.javahelps.externaldatabasedemo .

4 단계 : build.gradle (Module : app) 파일을 열고 다음 종속성을 추가합니다.

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

build.gradle 파일을 저장하고 나면 '지금 동기화'링크를 클릭하여 프로젝트를 업데이트하십시오. build.gradle 파일을 마우스 오른쪽 단추로 클릭하고 build.gradle Synchronize build.gradle 옵션을 선택하여 Synchronize build.gradleSynchronize build.gradle 수 있습니다.

5 단계 : 앱 폴더를 마우스 오른쪽 버튼으로 클릭하고 새 저작물 폴더를 만듭니다.

6 단계 : assets 폴더 내에 'databases'폴더를 새로 만듭니다.

7 단계 : quotes.db.zip 파일을 복사하여 assets/databases 폴더에 붙여 넣습니다.

8 단계 : 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.

9 단계 : DatabaseAccess 클래스를 새로 만들고 아래와 같이 코드를 입력하십시오. 이 클래스에 대한 자세한 내용은 고급 Android Database 튜토리얼을 참조하십시오.

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,

평소와 같이 데이터베이스의 모든 행을 업데이트하고 삭제하십시오. 자세한 내용은 고급 Android 데이터베이스 링크를 참조하십시오.

모든 데이터베이스 관련 설정이 완료되었으므로 따옴표를 표시하기 위해 ListView 를 만들어야합니다.

10 단계 : activity_main.xml ListView 를 추가합니다.

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

11 단계 : MainActivityonCreate 메소드에서 ListView 의 객체를 찾고 데이터베이스에서 읽은 인용문을 입력하십시오.

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

12 단계 : 모든 변경 사항을 저장하고 응용 프로그램을 실행합니다.

이 기사 외에도 SQLiteAssetHelper 를 다운로드 할 수 here


클래스와 질문에 대한 답변을 수정하고 DB_VERSION을 통해 데이터베이스를 업데이트 할 수있는 클래스를 작성했습니다.

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

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

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

        copyDataBase();

        this.getReadableDatabase();
    }

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

            copyDataBase();

            mNeedUpdate = false;
        }
    }

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

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

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

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

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

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

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

수업 사용하기.

활동 클래스에서 변수를 선언하십시오.

private DatabaseHelper mDBHelper;
private SQLiteDatabase mDb;

onCreate 메소드에서 다음 코드를 작성하십시오.

mDBHelper = new DatabaseHelper(this);

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

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

res / raw 폴더에 데이터베이스 파일을 추가하면 다음과 같은 클래스 수정이 사용됩니다.

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





android-database