android数据库,从文件中读取

时间:2012-01-08 22:59:57

标签: android database sqlite

我是eclipse和android编程的新手,我的数据库连接有问题。好吧,我找到了许多链接,我发布了我的2个课程。如果有人能找到错误。我拥有的数据库是用sqlite制作的,它有android_metadata和问题表。当我在模拟器中运行时,当我打开关于表单时,它会有一些消息“DrymVyzion的应用程序测验测试(进程dv.qtest.dvyzual)意外停止。请再试一次。” 在eclipse那是错误:

01-08 22:50:42.292: E/AndroidRuntime(1059): Uncaught handler: thread main exiting due to uncaught exception
01-08 22:50:42.312: E/AndroidRuntime(1059): java.lang.RuntimeException: Unable to start activity ComponentInfo{dv.qtest.dvyzual/dv.qtest.dvyzual.About}: android.database.sqlite.SQLiteException: no such table: questions: , while compiling: SELECT _id, question, qone, qtwo, qthree, qanswer FROM questions
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.app.ActivityThread.access$2100(ActivityThread.java:116)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.os.Looper.loop(Looper.java:123)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.app.ActivityThread.main(ActivityThread.java:4203)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at java.lang.reflect.Method.invokeNative(Native Method)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at java.lang.reflect.Method.invoke(Method.java:521)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at dalvik.system.NativeStart.main(Native Method)
01-08 22:50:42.312: E/AndroidRuntime(1059): Caused by: android.database.sqlite.SQLiteException: no such table: questions: , while compiling: SELECT _id, question, qone, qtwo, qthree, qanswer FROM questions
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteProgram.native_compile(Native Method)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteProgram.compile(SQLiteProgram.java:110)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1118)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1006)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:964)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1041)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at dv.qtest.dvyzual.About.getEvents(About.java:46)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at dv.qtest.dvyzual.About.onCreate(About.java:22)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
01-08 22:50:42.312: E/AndroidRuntime(1059):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)

以下是我的两个课程:

quizData.java

package dv.qtest.dvyzual;

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;

/** Helper to the database, manages versions and creation */
public class quizData extends SQLiteOpenHelper {
    private static final String DB_PATH = "/data/data/dv.qtest.dvyzual/databases/";
    private static final String DB_NAME = "q.db";
    private static final int DATABASE_VERSION = 1;
    private SQLiteDatabase myDataBase; 
    private final Context myContext;


    // Table name
    public static final String TABLE = "questions";

    // Columns
    public static final String qid = "_id";
    public static final String question = "question";
    public static final String qone = "qone";
    public static final String qtwo = "qtwo";
    public static final String qthree = "qthree";
    public static final String qanswer = "qanswer";

    public quizData(Context context) {
        super(context, DB_NAME, null, DATABASE_VERSION);
        this.myContext = context;
    }

    public void createDataBase() throws IOException{

        boolean dbExist = checkDataBase();

        if(dbExist){

        }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 {
                this.close(); // testing
                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) {

    }

}

About.java

package dv.qtest.dvyzual;


import java.io.IOException;

import android.app.Activity;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.TextView;

public class About extends Activity {
     /** Called when the activity is first created. */
     private quizData eventsData = new quizData(About.this);

     @Override
     public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.about);
        Cursor cursor = getEvents();
        showEvents(cursor);

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

    try {
        eventsData.openDataBase();
    }catch(SQLException sqle){
        throw sqle;
    }

     }

      @Override
      public void onDestroy() {
        eventsData.close();
      }

      private Cursor getEvents() {
            SQLiteDatabase db = eventsData.getReadableDatabase();
            Cursor cursor = db.query("questions", new String[]{"_id","question","qone", "qtwo", "qthree", "qanswer"}, null, null, null, null, null);
            startManagingCursor(cursor);
            return cursor;
      }      

      private void showEvents(Cursor cursor) {
            StringBuilder ret = new StringBuilder("Saved Events:\n\n");
            while (cursor.moveToNext()) {
              long id = cursor.getLong(0);
              String q = cursor.getString(1);
              String q1 = cursor.getString(2);
              ret.append(id + ": " + q + ": " + q1 + "\n");
            }

            TextView tv = new TextView(this);
            tv.setText(ret);
            setContentView(tv);
          }

     }

请帮助,如果有人能找到我做错了什么,我正在尝试那么多个小时! 顺便说一下,它适用于数据库,而不是来自没有DB路径的文件。所以也许问题是我没有设置db helper correcty?有什么想法吗?

1 个答案:

答案 0 :(得分:0)

在“关于”活动中,您在致电getEvents()之前呼叫eventsData.createDataBase()。这将尝试在数据库存在之前访问它。我想如果你颠倒onCreate中的通话顺序,它可能会起作用(除了其他问题):

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.about);

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

    try {
        eventsData.openDataBase();
    } catch(SQLException sqle){
        throw sqle;
    }
    Cursor cursor = getEvents();
    showEvents(cursor);
}