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

标签 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 View 并在文件资源管理器中选择我的包。我找到了“数据库”文件夹。我的数据库在 Assets 文件夹中,即;在这里找到“我的数据库”。但是当我拉文件并在 sqlite 浏览器中打开它时,它只显示 android_metadata 表但不显示我数据库中的其他表。我也无法执行任何查询。如何访问和查询数据库?就像在 DataBaseHelper 类中执行“Select”语句并显示结果一样。我希望清楚我的问题。我有一个复制到 Assets 文件夹的数据库和一个将此数据库复制到默认路径的代码。代码是否正确?如果不是,那么我应该更正什么?我需要执行查询 n 怎么办??

最佳答案

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

我用这个来复制数据库

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

关于android - 如何访问和查询复制到assets文件夹的数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18941404/

相关文章:

android - 在 android 中使用 Glide 预取图像

c# - 在我的自定义适配器上抛出异常

php - 如何让我的点击计数器每天、每周和每月进行计数?

mysql - Storm 直接从 MySQL 喷出?

database - 从 SQLite 数据库读取未提交的更改(脏读)

database - 使用 boolean 逻辑创建数据库 View

java - Android/Java抽象类继承问题

android - 使用 Android Retrofit 2 Httpok3 的空响应主体

python - 无法在 sqlite3 python 中对关闭的游标进行操作

sql - 简化UNION查询以使用单个SELECT