iT邦幫忙

DAY 16
2

以「寶寶聯絡簿」為例,適合 Android 初學者的學習筆記系列 第 16

寶寶生活記錄 App (Day16 如何從 assets 資料夾讀取一個已經存在的資料庫)

  • 分享至 

  • xImage
  •  

這幾天我們討論數個跟資料庫存取相關的 Android 類別,包含了 SQLiteOpenHelper, SQLiteDatabase, Cursor 等,然而關於資料庫還有許多可介紹的,例如筆者多年前曾寫過一篇文章介紹如何從 assets 資料夾讀取一個已經存在的資料庫,並將之寫入 /data/data/<package name>/databases 裡,鐵人賽參賽至今的確是略感疲憊了,今天先暫時用舊文章代替。然而還是有一點需要說明,若使用 ADT Bundle (Eclipse),assets 資料夾位於 Project 的根目錄下,若使用 Android Studio,您必須在 /app/src/main 自行建立 assets 資料夾 [1]。

有一些應用程式會需要讀取已經建立好的資料庫,例如一個試題測驗應用程式,裡面的試題可能已經於電腦上,使用任何的 SQLite 資料庫產生工具,產生一個資料庫檔案(例如:questions.db),我們會希望我們的應用程式能夠直接讀取這個檔案,而不是在應用程式第一次執行時,利用程式去做 INSERT 的動作,下面將示範如何實作出這樣的功能。

第一個步驟是產生 SQLite 資料庫檔案,產生資料庫檔案的工具很多,其中一個是到 SQLite 的官方網站[1]下載,以 Windows 作業系統為例,網站有提供一個已經編譯好的命令列工具 sqlite3.exe,首先進入 Windows 所提供的『命令提示字元』,進入放置 sqlite3.exe 的資料夾後就可以執行它,執行時後面加個檔案名稱當參數,下面是一個範例:

C:\>sqlite3 questions.db

SQLite version 3.7.8 2011-09-19 14:49:19

Enter ".help" for instructions

Enter SQL statements terminated with a ";"

sqlite> create table questions(_question, _type, _answer);

sqlite> insert into questions values("1+1", "Math", "2");

sqlite> .exit

在上面的範例中,我們做了兩件事,首先建立一個表格,接著再插入一筆資料到表格內,我們可以再次執行 sqlite3,來驗證資料是否有正確被寫入:

C:\>sqlite3 questions.db

SQLite version 3.7.8 2011-09-19 14:49:19

Enter ".help" for instructions

Enter SQL statements terminated with a ";"

sqlite> select * from questions;

1+1|Math|2

除然而為了讓資料庫能夠正常地被 Android 所讀取,有兩點必須注意:

表格必須有一個名為『_id』的欄位,且 type 要設成『INTEGER PRIMARY KEY』。

必須建立一個名為『android_metadata』的表格,表格中要建立一個名為『locale』的欄位,經筆者的測試,我們不需要新增任何記錄。

產生好 questions.db 後我們就可以把這個檔案放到 assets 資料夾,接著就是要進行程式的撰寫:

package lincyu.demo.database_from_outside; 
 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
 
import android.content.Context; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper;
 
class DatabaseHelper extends SQLiteOpenHelper { 
 
    private static String DB_PATH = "/data/data/" + 
        "lincyu.demo.database_from_outside" + "/databases/"; 
    private static String DB_NAME = "questions.db";
 
    private final Context mCtx; 
 
    public DatabaseHelper(Context context) { 
        super(context, DB_NAME, null, 1); 24 this.mCtx = context; 
    } 
    
    public boolean createDatabase() { 
        boolean dbExist = checkDatabase(); 
        this.getReadableDatabase(); 
        if (dbExist == false) { 
            if (copyDatabase() == false) { 
                return false; 
            } 
        } 
        return true; 
    } 
 
    private boolean checkDatabase() { 
        SQLiteDatabase checkDB = null; 
        String dbpath = DB_PATH + DB_NAME; 
        try { 
            checkDB = SQLiteDatabase.openDatabase(dbpath,
                null, SQLiteDatabase.OPEN_READONLY); 
        } catch (SQLiteException e) { 
            return false; 
        } 
        if (checkDB != null) { 
            checkDB.close(); 
            return true; 
        } 
        return false; 
    } 
 
    private boolean copyDatabase() { 
        try { 
            InputStream input = mCtx.getAssets().open(DB_NAME); 
            this.getReadableDatabase(); 
            String outFileName = DB_PATH + DB_NAME; 
            OutputStream output = 
            new FileOutputStream(outFileName); 
            byte [] buffer = new byte[1024];
            int length; 
            while ((length = input.read(buffer)) > 0) { 
                output.write(buffer, 0, length); 
            } 
            output.flush(); 
            output.close(); 
            input.close(); 
        } catch (Exception e) { 
            return false; 
        } 
        return true; 
    } 
 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
    } 
 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldV, int newV) { 
    } 
} 

從程式碼我們不能發現,其實就只是單純的讀寫檔案,然而必須一提的是,要存取 assets 資料夾必須利用 Context 類別的 getAssets 方法來存取,getAssets 會回傳一個 AssetManager 物件,再呼叫其 open,就可讀取 assets 資料夾下的檔案。

參考資料

[1] Where to place Assets folder in Android Studio - Stack Overflow, http://stackoverflow.com/questions/18302603/where-to-place-assets-folder-in-android-studio


上一篇
寶寶生活記錄 App (Day15 Database 3)
下一篇
寶寶生活記錄 App (Day17 App自己專屬的儲存資料夾)
系列文
以「寶寶聯絡簿」為例,適合 Android 初學者的學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言