2011-02-08 40 views
1

我正在使用一些代碼將現有的SQLite數據庫從我的資產文件夾複製到我的/ data/data/package文件夾中。 我已經寫了代碼,並在android模擬器上測試它,它工作正常。如果我嘗試並將其安裝在我的設備上(HTC Desire),我會得到'SQLiteException:無法打開數據庫文件'無法在設備上打開數據庫文件(HTC Desire)

我一直在這個問題上停留了3天,無法找出問題所在。 我不知道數據庫是否因爲沒有創建,或者如果缺少清單文件中的某些數據庫權限而無法打開。 這是我的DataBaseHelper代碼:

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.SQLiteOpenHelper; 
import android.os.Environment; 
import android.util.Log; 

public class DataBaseHelper extends SQLiteOpenHelper{ 
    //private static String DB_PATH = "/data/data/com.drager/databases/"; 
    private static String DB_PATH = Environment.getDataDirectory()+"/data/com.drager/databases/"; 
    final static String DB_NAME = "myDBName"; 
    private SQLiteDatabase myDataBase=null; 
    private final Context myContext; 
    private DataBaseHelper myDbHelper; 
    private static String TAG ="MyActivity"; 

    public DataBaseHelper(Context context){ 
     super(context, DB_NAME, null, 1); 
     this.myContext = context; 

    } 

    public DataBaseHelper createDataBase() throws IOException{ 
     boolean dbExist =checkDataBase(); 
     //SQLiteDatabase db_read =null; 
     Log.i(TAG,"############value of dbExist"+dbExist+"##########"); 
     //if (dbExist){ 
      //db must exist 
     //} 
     //else{ 
     //myDbHelper = new DataBaseHelper(myContext); 
     //myDataBase = myDbHelper.getReadableDatabase(); 
     //myDataBase.close(); 
     //this.getReadableDatabase(); 
      //db_read.close(); 

     // try { 
       copyDataBase(); 
     // } catch (IOException e) { 
     //  throw new Error("error copying database"); 
     // } 
    // } 
     return this; 

    } 

    public Cursor executeStatement(){ 
     Log.i(TAG,"in execute statement"); 
     Cursor cursor=null; 

     cursor=myDataBase.rawQuery("SELECT _ID, title, value "+ 
        "FROM constants ORDER BY title", 
        null); 
     return cursor; 
    } 

    public String getTextViewItem(){ 

     Cursor cursor=null; 

     String str=""; 
     //store query results in cursor 
     cursor=myDataBase.rawQuery("SELECT description FROM product_details" , 
        null); 
     cursor.moveToNext(); 
     //cast cursor content from the index of 'description Column as a string 
     str =cursor.getString(cursor.getColumnIndex("description")); 

     return str; 
    } 

    public void copyDataBase() throws IOException{ 
     // open db as input stream 
     InputStream myInput = myContext.getAssets().open(DB_NAME); 

     //path to newly created db 
     String outFileName =DB_PATH + DB_NAME; 

     //open empty db as 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); 
     } 

     myOutPut.flush(); 
     myOutPut.close(); 
     myInput.close(); 


    } 

    private boolean checkDataBase() { 
     SQLiteDatabase checkDB = null; 

     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 
     /* 
     if (checkDB != null){ 
      checkDB.close(); 
     }*/ 
     return checkDB !=null ? true : false; 
    } 

    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) { 
     // TODO Auto-generated method stub 

    } 

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

    } 

} 

這是我的清單文件

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.drager" 
android:versionCode="1" 
android:versionName="1.0"> 
<application android:icon="@drawable/icon" android:label="@string/ 

app_name" android:debuggable="true"> 
    <activity android:name=".Drager" 
      android:label="Drager"> 
<intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
</intent-filter> 
</activity> 

這是logcat的

02-09 09:09:15.883: ERROR/AndroidRuntime(8313): 
java.lang.RuntimeException: Unable to start activity 
ComponentInfo{com.drager/com.drager.Drager}: 
android.database.sqlite.SQLiteException: unable to open database file 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 
2787) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 
2803) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.app.ActivityThread.access$2300(ActivityThread.java:135) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.os.Handler.dispatchMessage(Handler.java:99) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.os.Looper.loop(Looper.java:144) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.app.ActivityThread.main(ActivityThread.java:4937) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
java.lang.reflect.Method.invokeNative(Native Method) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
java.lang.reflect.Method.invoke(Method.java:521) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
com.android.internal.os.ZygoteInit 
$MethodAndArgsCaller.run(ZygoteInit.java:868) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
dalvik.system.NativeStart.main(Native Method) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313): Caused by: 
android.database.sqlite.SQLiteException: unable to open database file 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.database.sqlite.SQLiteDatabase.dbopen(Native Method) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java: 
1902) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java: 
884) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
com.drager.DataBaseHelper.checkDataBase(DataBaseHelper.java:108) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
com.drager.DataBaseHelper.createDataBase(DataBaseHelper.java:32) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
com.drager.Drager.onCreate(Drager.java:46) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java: 
1069) 
02-09 09:09:15.883: ERROR/AndroidRuntime(8313):  at 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 
2751) 

預先感謝您

+0

DO [任何](http://stackoverflow.com/questions/3563728/random-exception-android-database-sqlite-sqliteexception-unable-to-open-database)的](HTTP:/ /stackoverflow.com/questions/3421360/android-sqlite-exception-how-to-fix)[這些](http://stackoverflow.com/questions/4187631/unable-to-open-database-file-when-using -sqliteopenhelper-with-instrumentation-c)匹配你的情況? – drudge 2011-02-08 20:27:13

回答

0

感謝IDX,你一個非常漂亮的男人,或女人! 我嘗試了你的建議,帶着一點兒擺弄,我知道了,嘗試/捕獲似乎是關鍵。 這是我的修改代碼,希望它能幫助別人。

public class DataBaseHelper extends SQLiteOpenHelper{ 
    //private static String DB_PATH = "/data/data/com.drager/databases/"; 
    private static String DB_PATH = Environment.getDataDirectory()+"/data/com.drager/databases/"; 
    final static String DB_NAME = "myDBName"; 
    private SQLiteDatabase myDataBase=null; 
    private final Context myContext; 
    private DataBaseHelper myDbHelper; 
    private static String TAG ="MyActivity"; 

    public DataBaseHelper(Context context){ 
     super(context, DB_NAME, null, 1); 
     this.myContext = context; 

    } 

    public DataBaseHelper createDataBase() throws IOException{ 
     boolean dbExist =checkDataBase(); 
     //SQLiteDatabase db_read =null; 
     Log.i(TAG,"############value of dbExist"+dbExist+"##########"); 
     if (dbExist){ 
      //db must exist 
     } 
     else{ 
     myDbHelper = new DataBaseHelper(myContext); 
     myDataBase = myDbHelper.getReadableDatabase(); 
     myDataBase.close(); 
     //this.getReadableDatabase(); 
      //db_read.close(); 

      try { 
       copyDataBase(); 
      } catch (IOException e) { 
       throw new Error("error copying database"); 
      } 
     } 
     return this; 

    } 

    public Cursor executeStatement(){ 
     Log.i(TAG,"in execute statement"); 
     Cursor cursor=null; 

     cursor=myDataBase.rawQuery("SELECT _ID, title, value "+ 
        "FROM constants ORDER BY title", 
        null); 
     return cursor; 
    } 

    public String getTextViewItem(){ 

     Cursor cursor=null; 

     String str="fffff"; 
     //store query results in cursor 
     cursor=myDataBase.rawQuery("SELECT description FROM product_details" , 
        null); 
     Log.i(TAG,"################in gettextview, value of cursor ="+cursor); 
     cursor.moveToNext(); 

     //cast cursor content from the index of 'description Column as a string 
     str =cursor.getString(cursor.getColumnIndex("description")); 

     return str; 
    } 

    public void copyDataBase() throws IOException{ 
     // open db as input stream 
     InputStream myInput; 
     //open empty db as output stream 
     OutputStream myOutPut; 
     try { 
      myInput = myContext.getAssets().open(DB_NAME); 

      //path to newly created db 
      String outFileName =DB_PATH + DB_NAME; 

      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); 
      } 
      myOutPut.flush(); 
      myOutPut.close(); 
      myInput.close(); 
      } 
     catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 




    } 

    private boolean checkDataBase() { 
     SQLiteDatabase checkDB = null; 

     String myPath = DB_PATH + DB_NAME; 

     try { 
      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 
     } catch (SQLException e) { 

      e.printStackTrace(); 
      return false; 
     } 

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

    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) { 
     // TODO Auto-generated method stub 

    } 

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

    } 

}