在资产文件夹自己的数据库在Android的Eclipse项目 [英] Own Database in Assets Folder on Android Eclipse Project

查看:242
本文介绍了在资产文件夹自己的数据库在Android的Eclipse项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Andr​​oid应用程序的一个大问题。我制定了第一次与SQLite数据库的Andr​​oid应用程序,但我有我并不能解决问题。

我有名字saldb.sqlite对Eclipse项目的资产文件夹我的SQLite数据库

我有以下类来管理与Singletone模式数据库:

 包sal.app.logic;    进口java.io.FileOutputStream中;
    进口java.io.IOException异常;
    进口的java.io.InputStream;
    进口java.io.OutputStream中;    进口android.content.Context;
    进口android.database.Cursor;
    进口android.database.SQLException;
    进口android.database.sqlite.SQLiteDatabase;
    进口android.database.sqlite.SQLiteException;
    进口android.database.sqlite.SQLiteOpenHelper;    公共类的DatabaseManager扩展SQLiteOpenHelper {    私有静态的DatabaseManager dbManagerInstance = NULL;
    私人语境salContext;
    私人SQLiteDatabase salDatabase;
    私人静态字符串DB_PATH =/data/data/sal.app/databases/;
    私人静态字符串DB_NAME =saldb.sqlite;
    私人的DatabaseManager(上下文C)
    {
        超(C,DB_NAME,空,1);
        //this.salContext = C;
    }    公共静态的DatabaseManager getSalDatabase(上下文C)
    {
        如果(dbManagerInstance == NULL)
        {
            dbManagerInstance =新的DatabaseManager(C);
        }        返回dbManagerInstance;
    }    公共无效的CreateDatabase()抛出IOException        布尔dbExist = checkDataBase();        如果(dbExist){
            //什么也不做 - 已存在于数据库
        }其他{            //通过调用此方法与空的数据库将被创建到默认的系统路径
            //你的应用程序,所以我们要能够覆盖该数据库与我们的数据库。
            this.getReadableDatabase();            尝试{                copyDataBase();            }赶上(IOException异常五){                抛出新的错误(错误复制数据库);            }
        }    }    私人布尔checkDataBase()
    {        SQLiteDatabase CHECKDB = NULL;        尝试{
            字符串mypath中= DB_PATH + DB_NAME;
            CHECKDB = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY);        }赶上(SQLiteException E){            //数据库开不存在。        }        如果(CHECKDB!= NULL){            checkDB.close();        }        返回CHECKDB!= NULL?真假;
    }    私人无效copyDataBase()抛出IOException        //打开本地数据库的输入流
        InputStream的myInput = salContext.getAssets()开(DB_NAME)。        //路径刚刚创建的空分贝
        //字符串outFileName = DB_PATH + DB_NAME;        字符串outFileName =/data/data/sal.app/databases/saldb.sqlite;
        //打开空分贝的输出流
        的OutputStream myOutput =新的FileOutputStream(outFileName);        //传递从inputfile中字节到OUTPUTFILE
        字节[]缓冲区=新的字节[1024];
        INT长;
        而((长度= myInput.read(缓冲液))大于0){
            myOutput.write(缓冲液,0,长度);
        }        //关闭流
        myOutput.flush();
        myOutput.close();
        myInput.close();    }    公共无效的openDatabase()抛出的SQLException {        //打开数据库
        字符串mypath中= DB_PATH + DB_NAME;
        salDatabase = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READWRITE);    }    @覆盖
    公共同步无效的close(){            如果(salDatabase!= NULL)
                salDatabase.close();            super.close();    }    @覆盖
    公共无效的onCreate(SQLiteDatabase DB){        //db.execSQL(\"Insert质疑(_id,水平,文本,idTopic)值(1,1,'ASA',0));
    }    @覆盖
    公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){    }        //添加您的公开辅助方法访问并从数据库中获取的内容。
       //你可以做返回游标返回myDataBase.query(....),因此这将会是很容易
       //你创建你的意见适配器。    公众质疑getOneQuestion()
    {
        // Versioni的列表,查询文本搜索结果                问寻求=新问题();                尝试
                {
                    //打开数据库查询
                    的openDatabase();                    //salDatabase.execSQL(\"Insert质疑(_id,水平,文本,idTopic)值(1,1,'ASA',0));                    //光标指针= salDatabase.rawQuery(选择文本,idTopic,从问题level其中level = 2,NULL);                    光标光标= salDatabase.rawQuery(选择的问题*,NULL);
                    / *光标光标= salDatabase.query(问题                            新的String [] {文本,idTopic,级别},
                            电平= 2,
                            空值 ,
                            空值,
                            空值,
                            RANDOM()LIMIT 1); * /                    //光标C = db.rawQuery(选择,NULL); * /                //映射的所有行数据对象
                    如果(cursor.moveToFirst())
                    {
                        的System.out.println(cursor.getString(2));
                        做
                        {
                            光标光标2 = salDatabase.rawQuery(SELECT * FROM WHERE主题_id = 0,NULL);
                            cursor2.moveToFirst();
                            主题T =新主题(cursor2.getString(1));
                           追求=新课题(cursor.getString(2),T(INT)cursor.getShort(1));                           打破;
                        }而(cursor.moveToNext());                    }
                    //关闭游标
                    cursor.close();
                }
                赶上(异常前)
                {
                    的System.out.println(DatabaseHelper.search() - :前+ ex.getClass()+,+ ex.getMessage());
                }
                //
                返回任务;    }    / *公众的ArrayList<应答和GT; getAnswersOfQuestion(Questin Q)
    {    } * /}

但是,在我第一次运行我的应用程序都已经释放了以下误差修改:

23 05-29:55:45.684:D / DDM堆(221):GOT功能列表请求
05-29 23:55:46.295:D / dalvikvm(221):GC释放519对象/在109ms 45792字节
05-29 23:55:46.544:E /数据库(221):sqlite3_open_v2(/数据/数据​​/ sal.app /数据库/ saldb.sqlite,&安培;手柄,1,NULL)失败。

23 05-29:55:46.594:D / AndroidRuntime(221):关闭VM
05-29 23:55:46.604:W / dalvikvm(221):主题ID = 3:螺纹未捕获的异常(组= 0x4001b188)

退出

23 05-29:55:46.604:E / AndroidRuntime(221):未捕获的处理程序:螺纹主力退出,由于未捕获的异常

在我的主要活动即时通讯做这样的:

 公共类SALActivity延伸活动{    按钮后退;
    按钮choiceA;
    静态INT选择= 0;
    的DatabaseManager分贝;
    //按钮choiceB;
    //按钮choiceC;
    //按钮choiceD;
    / **当第一次创建活动调用。 * /
    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){        super.requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);        的setContentView(R.layout.gamemenu);
        // DB =新的DatabaseManager(本);
        DB = DataBaseManager.getSalDatabase(本​​);
        尝试{
            db.createDataBase();
        }赶上(IOException异常五){
            // TODO自动生成catch块
            e.printStackTrace();
        }
        //db=DataBaseManager.getSalDatabase(this);        问题Q = db.getOneQuestion();        //回来=(按钮)findViewById(R.id.gaveup_button);
        choiceA =(按钮)findViewById(R.id.choice_a_button);
        choiceA.setTextColor(为0xffffffff);
        //choiceA.setText(\"A:Académica);
        choiceA.setText(q.getQuestionText());        choiceA.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图v){
            }
        });        //choiceA.setText(10);
        // choiceB =(按钮)findViewById(R.id.choice_b_button);
        // choiceC =(按钮)findViewById(R.id.choice_c_button);
        // choiceD =(按钮)findViewById(R.id.choice_d_button);        //意向V =新意图(这一点,SALActivity.class);        //this.startActivity(v);
    }
}

在我运行应用程序中的第二次,不要出现错误,数据库是在正确的路径,但只有表android_metadata

我也可以说,如果我把正确的数据库上/data/data/sal.app/databases/整个程序只是工作...
该错误是在co​​pyDatabase。


解决方案

这是我的工作code复制数据库。

 私有静态字符串DB_PATH =/data/data/com.demo.databaseDemo/databases/;
 私人静态字符串DB_NAME =myDatabase.db;
 私人无效copyDataBase()抛出IOException            //打开本地数据库的输入流
            InputStream的myInput = _myContext.getAssets()开(DB_NAME)。            //路径刚刚创建的空分贝
            字符串outFileName = DB_PATH + DB_NAME;            //打开空分贝的输出流
            的OutputStream myOutput =新的FileOutputStream(outFileName);            //传递从inputfile中字节到OUTPUTFILE
            字节[]缓冲区=新的字节[1024];
            INT长;
            而((长度= myInput.read(缓冲液))大于0){
                myOutput.write(缓冲液,0,长度);
            }            //关闭流
            myOutput.flush();
            myOutput.close();
            myInput.close();        } // copyDataBase的end()方法

I have a big problem in my android application. I'm develop for the first time an android application with a sqlite database but i have problems that i cant solve.

I have my sqlite database on assets folder of eclipse project with name saldb.sqlite

I have the following class to manage Database with Singletone pattern:

package sal.app.logic;

    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 DataBaseManager extends SQLiteOpenHelper{

    private static DataBaseManager dbManagerInstance = null;
    private Context salContext;
    private  SQLiteDatabase salDatabase;
    private static  String DB_PATH = "/data/data/sal.app/databases/";
    private static String DB_NAME = "saldb.sqlite";


    private DataBaseManager(Context c)
    {
        super(c, DB_NAME, null, 1);
        //this.salContext = c;
    }

    public static DataBaseManager getSalDatabase(Context c)
    {
        if (dbManagerInstance == null)
        {
            dbManagerInstance = new DataBaseManager(c);
        }

        return dbManagerInstance;
    }

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

            }
        }

    }



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

    private void copyDataBase() throws IOException{

        //Open your local db as the input stream
        InputStream myInput = salContext.getAssets().open(DB_NAME);

        // Path to the just created empty db
        //String outFileName = DB_PATH + DB_NAME;

        String outFileName = "/data/data/sal.app/databases/saldb.sqlite";
        //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;
        salDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

    }

    @Override
    public synchronized void close() {

            if(salDatabase != null)
                salDatabase.close();

            super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        //db.execSQL("Insert Into Question(_id,level,text,idTopic) Values (1,1,'asa',0)");
    }

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

    public Question getOneQuestion()
    {
        //list of Versioni, search result with query text

                Question quest = new Question();

                try
                {
                    //open database to query
                    openDataBase();

                    //salDatabase.execSQL("Insert Into Question(_id,level,text,idTopic) Values (1,1,'asa',0)");

                    //Cursor cursor = salDatabase.rawQuery("SELECT text, idTopic, level from Question WHERE level=2", null);

                    Cursor cursor = salDatabase.rawQuery("SELECT * from Question", null);


                    /*Cursor cursor = salDatabase.query("Question",

                            new String[] { "text","idTopic","level"},
                            "level=2",
                            null ,
                            null,
                            null,
                            "RANDOM() LIMIT 1");*/

                    //Cursor c = db.rawQuery(select, null); */

                //mapped all rows to data object


                    if (cursor.moveToFirst())       
                    {
                        System.out.println(cursor.getString(2));
                        do
                        {
                            Cursor cursor2 = salDatabase.rawQuery("SELECT * from Topic WHERE _id=0", null);
                            cursor2.moveToFirst();
                            Topic t = new Topic(cursor2.getString(1));
                           quest = new Question(cursor.getString(2),t,(int)cursor.getShort(1));

                           break;
                        } while (cursor.moveToNext());

                    }   
                    //close cursor      
                    cursor.close();     
                }
                catch(Exception ex)
                {
                    System.out.println("DatabaseHelper.search()- : ex " + ex.getClass() +", "+ ex.getMessage());
                }
                //  
                return quest;

    }

    /*public ArrayList<Answer> getAnswersOfQuestion(Questin q)
    {

    }*/

}

But in first time that i run my application i have de following erros:

05-29 23:55:45.684: D/ddm-heap(221): Got feature list request 05-29 23:55:46.295: D/dalvikvm(221): GC freed 519 objects / 45792 bytes in 109ms 05-29 23:55:46.544: E/Database(221): sqlite3_open_v2("/data/data/sal.app/databases/saldb.sqlite", &handle, 1, NULL) failed

05-29 23:55:46.594: D/AndroidRuntime(221): Shutting down VM 05-29 23:55:46.604: W/dalvikvm(221): threadid=3: thread exiting with uncaught exception (group=0x4001b188)

05-29 23:55:46.604: E/AndroidRuntime(221): Uncaught handler: thread main exiting due to uncaught exception

in my main Activity im doing this:

public class SALActivity extends Activity {

    Button back;
    Button choiceA;
    static int choice = 0;
    DataBaseManager db;
    //Button choiceB;
    //Button choiceC;
    //Button choiceD;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);

        setContentView(R.layout.gamemenu);
        //db= new DataBaseManager(this);
        db=DataBaseManager.getSalDatabase(this);
        try {
            db.createDataBase();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //db=DataBaseManager.getSalDatabase(this);

        Question q = db.getOneQuestion();

        //back = (Button) findViewById(R.id.gaveup_button);
        choiceA = (Button) findViewById(R.id.choice_a_button);
        choiceA.setTextColor(0xffffffff);
        //choiceA.setText("A: Académica");
        choiceA.setText(q.getQuestionText());

        choiceA.setOnClickListener(new View.OnClickListener() {


            public void onClick(View v) {


            }
        });

        //choiceA.setText(10);
        //choiceB = (Button) findViewById(R.id.choice_b_button);
        //choiceC = (Button) findViewById(R.id.choice_c_button);
        //choiceD = (Button) findViewById(R.id.choice_d_button);

        //Intent v = new Intent(this, SALActivity.class);

        //this.startActivity(v);
    }
}

In the second time that i run app, error dont occur, database are in the correct path but only have the table android_metadata

I also could say that if i put the correct dataBase on /data/data/sal.app/databases/ the entire program just works... The error is in the copyDatabase.

解决方案

This is my working code to copy database.

private static String DB_PATH = "/data/data/com.demo.databaseDemo/databases/";
 private static String DB_NAME = "myDatabase.db";   
 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();

        }//end of copyDataBase() method

这篇关于在资产文件夹自己的数据库在Android的Eclipse项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆