如何访问和查询复制到assets文件夹的数据库?

时间:2013-09-22 07:27:19

标签: android database sqlite ddms

我已经阅读了一些教程,其中将预先存在的数据库复制到assets文件夹,并编写用于将此数据库复制到应用程序数据库的默认系统路径的代码。

package com.example.c1;

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

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

public class DataBaseHelper extends SQLiteOpenHelper {

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

        private static String DB_NAME = "MyDatabase";

        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() 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
            String myPath = DB_PATH + DB_NAME;
            myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

            }

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

            }



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

}

我使用此代码将数据库从assets文件夹复制到默认路径。

package com.example.c1;

import java.io.IOException;
import com.example.c1.DataBaseHelper;
import android.os.Bundle;
import android.app.Activity;
import android.database.SQLException;
import android.view.Menu;
import android.widget.TextView;

public class C1 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.c1);

        DataBaseHelper myDbHelper = new DataBaseHelper(this);


         try {

         myDbHelper.createDataBase();

         } catch (IOException ioe) {

         throw new Error("Unable to create database");

         }

         try {

         myDbHelper.openDataBase();

         }catch(SQLException sqle){

         throw sqle;

         }


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.c1, menu);
        return true;
    }

}

运行它,模拟器说c1已停止。我点击了DDMS视图,在文件浏览器中我选择了我的包。我找到了“数据库”文件夹。我的数据库在assets文件夹中; “MyDatabase”可在此处找到。但是,当我拉出文件并在sqlite浏览器中打开它时,它只显示android_metadata表,但不显示我的数据库中的其他表。我也无法执行任何查询。如何访问和查询数据库?比如在DataBaseHelper类中执行“Select”语句并显示它的结果。我希望我的问题清楚。我有一个数据库复制到assets文件夹和一个代码将此数据库复制到默认路径。代码是否正确?如果不是那么我应该做出哪些修正?我需要执行查询n怎么做?

1 个答案:

答案 0 :(得分:1)

您需要将数据库文件复制到应用程序目录文件夹,然后使用此文件打开数据库

我用它来复制数据库

private void copyDataBase()
{
    Log.i("Database", "New database is being copied to device!");
    byte[] buffer = new byte[1024];
    OutputStream myOutput = null;
    int length;
    // Open your local db as the input stream
    InputStream myInput = null;
    try
    {
        myInput = myContext.getAssets().open(DB_NAME);
        // transfer bytes from the inputfile to the
        // outputfile
        myOutput = new FileOutputStream(DB_PATH + DB_NAME);
        while((length = myInput.read(buffer)) > 0)
        {
            myOutput.write(buffer, 0, length);
        }
        myOutput.close();
        myOutput.flush();
        myInput.close();
        Log.i("Database", "New database has been copied to device!");
        cmn.mailDetails();

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

使用此

打开
protected Boolean openDatabase()
{
    if(isDatabaseExist(false))
    {
        // Open the database
        String myPath = DB_PATH + DB_NAME;
        try
        {
            Log.i("Database", "Trying to Open Database!");
            if(myDataBase != null)
            {
                if(!myDataBase.isOpen())
                {
                    Log.i("Database", "Database is closed now opening it!");
                    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

                }
                else
                {
                    Log.i("Database", "Database is already Open!");
                }
                Log.i("Database", "Database is Opened successfully in OPEN_READWRITE  Mode !");
                return true;

            }
            else
            {
                myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
                Log.i("Database", "Database is Opened successfully in OPEN_READWRITE  Mode !");
                return true;
            }

        }
        catch(Exception e)
        {
            Log.e("Database", "Some error occured while opening Database Error:" + e.getMessage());
            myDataBase = null;
            return false;
        }

    }
    else
    {
        copyDataBase();
    }
    return false;
}