簡體   English   中英

Sqlite從android中的資產文件夾中獲取?

[英]Sqlite get from assets folder in android?

它工作正常

這是從資產文件夾訪問外部數據庫的代碼。 在 android 我們可以使用 SQLite 數據庫瀏覽器創建 sqlite 數據庫。 現在的問題是如何在源代碼中訪問這個數據庫。 答案很簡單。 將數據庫存儲在項目文件夾中的資產文件夾中。請在下面查看該答案。

請創建資產文件夾->“您的”表示數據庫名稱

1) DatabaseHelper.class

public class DatabaseHelper extends SQLiteOpenHelper{

    //The Android's default system path of your application database.
    String DB_PATH =null;

    private static String DB_NAME = "your";
    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;
        DB_PATH="/data/data/"+context.getPackageName()+"/"+"databases/";
    }   

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

        boolean dbExist = checkDataBase();

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

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

            try {
                copyDataBase();

            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }

    }

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

        }

        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{

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

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

    public void openDataBase() throws SQLException{

        //Open the database
        try {
            String myPath = DB_PATH + DB_NAME;
            myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY+SQLiteDatabase.NO_LOCALIZED_COLLATORS);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }     

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

    //return cursor
    public Cursor query(String table,String[] columns, String selection,String[] selectionArgs,String groupBy,String having,String orderBy){
        return myDataBase.query("cities", null, null, null, null, null, null);
    }
}

2) CopyDbActivity.class

public class CopyDbActivity extends Activity {
    /** Called when the activity is first created. */
    Cursor c=null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ((Button)findViewById(R.id.button01)).setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {

                 DatabaseHelper myDbHelper = new DatabaseHelper(CopyDbActivity.this);
                 try {
                    myDbHelper.createDataBase();

            } catch (IOException ioe) {
                throw new Error("Unable to create database");
            }

            try {
                myDbHelper.openDataBase();

            }catch(SQLException sqle){
                throw sqle;
            }
            Toast.makeText(CopyDbActivity.this, "Success", Toast.LENGTH_SHORT).show();

            c=myDbHelper.query("cities", null, null, null, null,null, null);
            if(c.moveToFirst())
            {
                do {
                    /*Toast.makeText(CopyDbActivity.this,
                            "_id: " + c.getString(0) + "\n" +
                            "E_NAME: " + c.getString(1) + "\n" +
                            "E_AGE: " + c.getString(2) + "\n" +
                            "E_DEPT:  " + c.getString(3),
                            Toast.LENGTH_LONG).show();*/
               } while (c.moveToNext());
           }

            }
        });}
}

3) XML 文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<Button android:id="@+id/button01"
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"
     android:text="Copy Database">
        </Button>

</LinearLayout>

用這個

 private static String DB_NAME = "your.db";

或者

 private static String DB_NAME = "your.sqlite";

代替

private static String DB_NAME = "your";
public class DatabaseOpenHelper extends OpenHelper {

    private Context context;

    private SQLiteDatabase sqliteDatabase;

    private static String DB_PATH;

    private static String DB_NAME;

    public DatabaseOpenHelper(Context context, String name, CursorFactory factory) {
        super(context, name, factory);
        this.context = context;
        this.DB_NAME = name;
        this.DB_PATH = context.getString(R.string.DB_PATH);
        try {
            createDataBase();
        } catch (Exception ioe) {
            throw new Error("Unable to create database");
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

    /** Open Database for Use */
    public void openDatabase() {
        String databasePath = DB_PATH + DB_NAME;
        sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
                (SQLiteDatabase.OPEN_READWRITE));
    }

    /** Close Database after use */
    @Override
    public synchronized void close() {
        if ((sqliteDatabase != null) && sqliteDatabase.isOpen()) {
            sqliteDatabase.close();
        }
        super.close();
    }

    /** Get database instance for use */
    public SQLiteDatabase getSqliteDatabase() {
        return sqliteDatabase;
    }

    /** Create new database if not present */
    public void createDataBase() {
        SQLiteDatabase sqliteDatabase = null;

        if (databaseExists()) {
            /* Check for Upgrade */
        } else {
            /* Database does not exists create blank database */
            sqliteDatabase = this.getReadableDatabase();
            sqliteDatabase.close();

            copyDataBase();
        }
    }

    /** Check Database if it exists */
    private boolean databaseExists() {
        SQLiteDatabase sqliteDatabase = null;
        try {
            String databasePath = DB_PATH + DB_NAME;
            sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            e.printStackTrace();
        }

        if (sqliteDatabase != null) {
            sqliteDatabase.close();
        }
        return sqliteDatabase != null ? true : false;
    }

    /**
     * Copy existing database file in system
     */
    public void copyDataBase() {

        int length;
        byte[] buffer = new byte[1024];
        String databasePath = DB_PATH + DB_NAME;

        try {
            InputStream databaseInputFile = this.context.getAssets().open(DB_NAME+".sqlite");
            OutputStream databaseOutputFile = new FileOutputStream(databasePath);

            while ((length = databaseInputFile.read(buffer)) > 0) {
                databaseOutputFile.write(buffer, 0, length);
                databaseOutputFile.flush();
            }
            databaseInputFile.close();
            databaseOutputFile.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

我建議使用我的庫https://github.com/mavstuff/sqlite_android ,它能夠從資產中讀取 sqlite 數據庫而無需復制

Releases 中有一個 *.AAR 文件,您可以在項目中使用。

當然數據庫可以在只讀模式下使用,因為沒有辦法寫回資產。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM