2017-01-03 45 views
0

我正在使用SQLiteOpenHelper編寫所有的查詢等等。當我在內部編寫和讀取數據庫時,一切工作正常,但如果我想保存數據庫到我的手機上的文件夾,我得到以下幾點:未知的錯誤(代碼14):當在android外部編寫時無法打開數據庫

01-03 07:12:24.786 16097-16097/com.myApp.app E/SQLiteLog: (14) cannot open file at line 31278 of [2ef4f3a5b1] 
01-03 07:12:24.786 16097-16097/com.myApp.app E/SQLiteLog: (14) os_unix.c:31278: (2) open(/storage/emulated/0/myApp/db/app) - 
01-03 07:12:24.787 16097-16097/com.myApp.app E/SQLiteDatabase: Failed to open database '/storage/emulated/0/myApp/db/app'. 
    android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database 
    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method) 
    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:207) 
    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:191) 
    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463) 
    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185) 
    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177) 
    at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806) 
    at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791) 
    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694) 
    at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:571) 
    at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:269) 
    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223) 
    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163) 
    at com.myApp.db.DbMain.getCountValueForMainMenu(DbMain.java:576) 
    at com.myApp.app.Beginner.openApp(Beginner.java:672) 
    at com.myApp.app.Beginner.checkfilepermission(Beginner.java:341) 
    at com.myApp.app.Beginner.onCreate(Beginner.java:332) 
    at android.app.Activity.performCreate(Activity.java:6251) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
    at android.app.ActivityThread.-wrap11(ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

DBhelper類文件

public DbMain(Context context) 
    { 
     // code to create database in internal storage 
     //super(context, DATABASE_NAME, null, DATABASE_VERSION); 

     //code to create database in External SD card 
     super(context, Environment.getExternalStorageDirectory() 
       + File.separator + "/myApp/db/" 
       + File.separator 
       + DATABASE_NAME, null, DATABASE_VERSION); 
    } 

@Override 
    public void onCreate(SQLiteDatabase db) 
    { 
     //1 
     String CREATE_TABLE_MENU = "CREATE TABLE IF NOT EXISTS " + TABLE_MENU_LOCAL +"(" 
       +KEY_MENUID_LOCAL + " TEXT," 
       +KEY_MENUNAME_LOCAL + " TEXT," 
       +KEY_ISCHILD_LOCAL + " TEXT," 
       +KEY_CATEGORYURL_LOCAL + " TEXT," 
       +KEY_IMAGEID_LOCAL + " TEXT," 
       +KEY_MENUNAME_DESCRIPTION_LOCAL + " TEXT" 
       + ")"; 

     db.execSQL(CREATE_TABLE_MENU); 
    } 

    //to get totalcount 
public int getCountValueForMainMenu() 
    { 
     SQLiteDatabase db = this.getWritableDatabase(); 
     int count = 0; 
     Cursor cursor = db.rawQuery("SELECT COUNT (*) FROM " + TABLE_MENU_LOCAL, null); 

     if(null != cursor) 
     { 
      if(cursor.moveToFirst() && 0 < cursor.getCount()) 
      { 
       count = cursor.getInt(0); 
      } 

      cursor.close(); 
     } 

     return count; 
    } 

一切都很好,當調用相同的方法等內部創建數據庫時。

什麼可能是錯的?

謝謝!

+0

你可以分享你喜歡錶創建dbhelper類的完整代碼中調用這個..等等? – rogerwar

+0

當然。問題用db更新。 –

+0

你也可以分享你從哪裏調用這個sqlite類和方法嗎? – rogerwar

回答

2

檢查這些點

1.READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE在AndroidManifest.xml中

2.External存儲目錄中定義的created.If沒有,DB助手的調用構造函數之前創建存儲目錄

嘗試dbHelper的這段代碼

public class DbHelper extends SQLiteOpenHelper { 

private static final String TABLE_MENU_LOCAL = "menu"; 
private static final String KEY_MENUID_LOCAL ="menuid" ; 
private static final String KEY_MENUNAME_LOCAL ="menuname" ; 
private static final String KEY_ISCHILD_LOCAL ="ischild" ; 
private static final String KEY_CATEGORYURL_LOCAL ="categoryurl" ; 
private static final String KEY_IMAGEID_LOCAL ="imageid" ; 
private static final String KEY_MENUNAME_DESCRIPTION_LOCAL ="description" ; 

private static String DATABASE_NAME="dbtest.db"; 
private static int DATABASE_VERSION=1; 

public DbHelper(Context context) 
{ 
    // code to create database in internal storage 
    //super(context, DATABASE_NAME, null, DATABASE_VERSION); 

    //code to create database in External SD card 


    super(context, Environment.getExternalStorageDirectory() 
      + File.separator + "/myapp/db/" 
      + File.separator 
      + DATABASE_NAME, null, DATABASE_VERSION); 

    } 

@Override 
public void onCreate(SQLiteDatabase db) { 
    //1 
    String CREATE_TABLE_MENU = "CREATE TABLE IF NOT EXISTS " + TABLE_MENU_LOCAL +"(" 
      +KEY_MENUID_LOCAL + " TEXT," 
      +KEY_MENUNAME_LOCAL + " TEXT," 
      +KEY_ISCHILD_LOCAL + " TEXT," 
      +KEY_CATEGORYURL_LOCAL + " TEXT," 
      +KEY_IMAGEID_LOCAL + " TEXT," 
      +KEY_MENUNAME_DESCRIPTION_LOCAL + " TEXT" 
      + ")"; 

    db.execSQL(CREATE_TABLE_MENU); 
} 

@Override 
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { 

} 

public void insertValues(){ 
    SQLiteDatabase db=this.getWritableDatabase(); 

    for(int count=0;count<5;count++) { 
     ContentValues insertValues = new ContentValues(); 
     insertValues.put(KEY_MENUID_LOCAL, "1"); 
     insertValues.put(KEY_MENUNAME_LOCAL, "Food1"); 
     insertValues.put(KEY_ISCHILD_LOCAL, "No"); 
     insertValues.put(KEY_CATEGORYURL_LOCAL, "Demo"); 
     insertValues.put(KEY_IMAGEID_LOCAL, "imageid"); 
     insertValues.put(KEY_MENUNAME_DESCRIPTION_LOCAL, "Description"); 
     db.insert(TABLE_MENU_LOCAL, null, insertValues); 
    } 
} 

//to get totalcount 
public int getCountValueForMainMenu() 
{ 
    SQLiteDatabase db = this.getWritableDatabase(); 
    int count = 0; 
    Cursor cursor = db.rawQuery("SELECT COUNT (*) FROM " + TABLE_MENU_LOCAL, null); 

    if(null != cursor) 
    { 
     if(cursor.moveToFirst() && 0 < cursor.getCount()) 
     { 
      count = cursor.getInt(0); 
     } 

     cursor.close(); 
    } 

    return count; 
} 

}

,並從您的活動或任何類似這樣的

String storage_folder = "/myapp/db"; 

    File f = new File(Environment.getExternalStorageDirectory(), storage_folder); 
    if (!f.exists()) { 
     f.mkdirs(); 
    } 
    DbHelper lDbHeper=new DbHelper(MainActivity.this); 
    lDbHeper.insertValues(); 
    int count=lDbHeper.getCountValueForMainMenu(); 

    Log.i("Count is:",""+count); 

讓我知道它可以幫助你或不

+0

我會檢查並回復你。 –

+0

嘿!這是mkdir問題。我創建它,它開始工作正常。非常感謝。 –

+0

@Sanjana Nair:很高興爲您效勞。快樂的編碼 – rogerwar

0

確保你有你的清單中聲明寫權限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

如果你的目標API 23或更高版本,您還需要request the permission at runtime

+0

我在清單中給出了WRITE和READ –

+0

您定位了哪些API?如果它高於22,那麼你還需要在運行時請求權限,因爲'WRITE_EXTERNAL_STORAGE'處於「危險」類別。 – gMale

+0

另外,您不需要聲明讀取權限。寫入需要讀取。所以你只需要申報一個或另一個。 – gMale

相關問題