2015-04-23 78 views
1

我有一個應用程序需要訪問資產文件夾數據庫來獲取應用程序啓動時的數據,所以我從資產動作中做了一些複製數據,但在上一版中,用戶說無法打開應用程序,因此有些用戶可以。Android複製數據庫目錄問題?

我可以知道,如果我需要將數據庫從assets文件夾複製到用戶設備,我應該使用哪個數據庫目錄路徑來存儲複製的數據庫?或者在我的代碼中缺少一些重要的東西?

像現在這樣,我只是在做這個設備上:

createDirectory:

public boolean createDirectory() { 
    if(Environment.getExternalStorageState().contains(Environment.MEDIA_MOUNTED)) 
    { 
     String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath()+GlobalConfig.CONFIG_DATA_DIR; 
     if(isNeedDL(rootPath)) { 
      File myDir = new File(rootPath); 
      return myDir.mkdirs(); 
     } 
    } 

    return false; 
} 

和數據庫目錄,其中GlobalConfig.CONFIG_DATA_DIR = 「/數據/」

path = Environment.getExternalStorageDirectory().getAbsolutePath()+GlobalConfig.CONFIG_DATA_DIR; 

和SQLiteOpenHelper類:檢查數據庫是否退出,執行復制操作。

private NOLDatabaseHelper(Context context, String path) { 
    super(context, path + DB_NAME_OUTDBNAME, null, DB_VERSION); 
    this.context = context; 
} 

public void createDatabase() { 

    if(!isDatabaseExited()) { 
     Log.v(GlobalConfig.TAG, "NO database"); 
     getReadableDatabase(); 
     copyDataBaseFromAsset(); 
    } else { 
     Log.v(GlobalConfig.TAG, "Has database"); 
    } 
} 

public static boolean isDatabaseExited() { 
    SQLiteDatabase checkDB = null; 
    try { 
     checkDB = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME_OUTDBNAME, null, 
       SQLiteDatabase.OPEN_READONLY); 
     checkDB.close(); 

     Log.v(GlobalConfig.TAG,"check? "+DB_PATH + DB_NAME_OUTDBNAME+" checkDB:"+checkDB); 
    } catch (SQLiteException e) {} 

    return checkDB != null ? true : false; 
} 

謝謝!

這裏是複製功能:

// to fix database is locked issue 
private synchronized void copyDataBaseFromAsset() 
{ 
    int length     = -1; 
    byte[] buffer    = new byte[1024]; 
    AssetManager am    = context.getAssets(); 

    try 
    { 
     InputStream assetsDB = am.open(DB_NAME_INDBNAME); 
     String outFileName  = DB_PATH + DB_NAME_OUTDBNAME; 
     OutputStream dbOut  = new FileOutputStream(outFileName); 

     while ((length = assetsDB.read(buffer)) > 0) { 
      dbOut.write(buffer, 0, length); 
     } 

     dbOut.flush(); 
     dbOut.close(); 
     assetsDB.close(); 

    } catch(Exception e) { 
     Log.e(GlobalConfig.TAG, "copyDataBaseFromAsset error, is say: "+e.toString()); 
    } 
} 
+0

我在帖子上添加了方法copyDataBaseFromAsset,非常感謝〜 –

回答

0
下面

是複製數據庫從資產文件夾中的數據目錄中的工作代碼:

public class DatabaseHelper extends SQLiteOpenHelper { 
// varaible declaration 
public static String TAG = "DatabaseHelper"; 
private static String DB_NAME = "DMDatabase.sqlite";//file name in assets 
private SQLiteDatabase sqliteDatabase; 
private final Context myContext; 
private String DatabasePath; 

public DatabaseHelper(Context context) { 
    super(context, DB_NAME, null, 1); 
    this.myContext = context; 
    DatabasePath = "/data/data/" + myContext.getPackageName() 
      + "/databases/"; 
} 

/** 
* Method to create the database inside application 
* 
* @throws IOException 
*/ 
public void createDatabase() throws IOException { 
    try { 

     // check if the database exists 
     boolean dbExist = checkDatabase(); 
     if (!dbExist) { 
      // database is not present copy databse 
      this.getReadableDatabase(); 
      try { 
       copyDatabse(); 
      } catch (IOException e) { 
       // TODO: handle exception 
       // String ex = e.getMessage(); 
       e.printStackTrace(); 
      } 
     } 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

/** 
* 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 { 
     checkDB = null; 
     try { 
      File file = new File(DatabasePath + DB_NAME); 
      if (file.exists()) { 
       checkDB = SQLiteDatabase.openDatabase(DatabasePath 
         + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); 
      } else { 
       return false; 
      } 
     } catch (SQLException e) { 
      Log.d("DB Exception", ""); 
     } 
     if (checkDB != null) { 
      checkDB.close(); 
     } 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    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 tranfering bytestream. 
* */ 
private void copyDatabse() throws IOException { 
    try { 
     // Open your local db as the input stream 
     InputStream myInput = myContext.getAssets().open(DB_NAME); 
     // Path to the just created empty db 
     String outFileName = DatabasePath + 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 * 2]; 
     int length; 

     while ((length = myInput.read(buffer)) > 0) { 
      try { 
       myOutput.write(buffer, 0, length); 
      } catch (Exception e) { 
      } 
     } 
     myOutput.flush(); 
     myOutput.close(); 
     myInput.close(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 



@Override 
public void onCreate(SQLiteDatabase db) { 
    // TODO Auto-generated method stub 
    createDatabase(); 
} 

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

} 

/** 
* Other Methods to insert,delete, update,select in Database 
*/ 

} 

我希望能對你有所幫助。

但不建議從數據目錄中的資產複製數據庫的過程。一旦創建了數據庫,onCreate方法將被調用,您應該在其中使用查詢來創建表並將默認數據插入到數據庫中。