2012-05-24 3 views
14

자산 폴더에서 DB로 DB를 복사하려고합니다. 이 코드는 에뮬레이터와 루팅 된 장치에서 잘 작동합니다. 난 그냥 그것이 unrooted 장치에 어떤 문제를 만들거나 똑같이 작동합니다 알고 싶습니다.루팅되지 않은 장치의 자산 폴더에서 데이터베이스 복사

private void StoreDatabase() { 
    File DbFile = new File(
      "data/data/packagename/DBname.sqlite"); 
    if (DbFile.exists()) { 
     System.out.println("file already exist ,No need to Create"); 
    } else { 
     try { 
      DbFile.createNewFile(); 
      System.out.println("File Created successfully"); 
      InputStream is = this.getAssets().open("DBname.sqlite"); 
      FileOutputStream fos = new FileOutputStream(DbFile); 
      byte[] buffer = new byte[1024]; 
      int length = 0; 
      while ((length = is.read(buffer)) > 0) { 
       fos.write(buffer, 0, length); 
      } 
      System.out.println("File succesfully placed on sdcard"); 
      // Close the streams 
      fos.flush(); 
      fos.close(); 
      is.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

} 
+1

예 당신의 코드가 루팅 해제 장치에서 완벽하게 작동도 : –

답변

13

이것은 모든 장치와 에뮬레이터에서 확실하게 작동합니다. 루트가 필요 없습니다.

/** 
* 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(String dbname) throws IOException { 
    // Open your local db as the input stream 
    InputStream myInput = myContext.getAssets().open(dbname); 
    // Path to the just created empty db 
    File outFileName = myContext.getDatabasePath(dbname); 
    // 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(); 
} 
+0

내 코드도 잘 작동하고 있습니다. 그냥 루핑되지 않은 장치에 문제가 발생했는지 알고 싶습니까? –

+0

아니요. 위의 코드는 잘 작동 할 것입니다. –

+13

** 절대로 하얼빈 코드 **. 'outFileName' 값은 많은 안드로이드 환경 (예 : 보조 계정)에서 잘못 될 것입니다. getDatabasePath()를 사용하여 데이터베이스 파일의 경로를 파생시킵니다. – CommonsWare

1

잘 모르겠지만 테스트 한 모든 장치에서 작동합니다. 내가 (여기 어딘가에에서)이 방법을 훔친과 제네릭 모두 백업 및 복원을 위해 만든 : 그럼

public static void movedb(File srcdb, File destdb) 
{ 
    try 
    { 
     if (Environment.getExternalStorageDirectory().canWrite()) 
     {     
      if (srcdb.exists()) 
      { 
       FileChannel src = new FileInputStream(srcdb).getChannel(); 
       FileChannel dst = new FileOutputStream(destdb).getChannel(); 
       dst.transferFrom(src, 0, src.size()); 
       src.close(); 
       dst.close();      
      } 
      else 
      { 
       //ERROR: "Database file references are incorrect"      
      } 
     } 
     else 
     { 
      //ERROR: "Cannot write to file" 
     } 
    } 
    catch (Exception e) 
    { 
     //ERROR: e.getMessage() 
    } 
} 

난 그냥 호출하여 백업 :

movedb(this, getDatabasePath(getDbName()), new File(Environment.getExternalStorageDirectory(), getDatabaseBackupPath())); 

getDatabasePath()getDatabaseBackupPath() 그냥 문자열입니다 값

+0

내 코드도 그냥 알고 싶어 벌금이 루팅 해제 장치에 문제를 만드는 것입니다 작업? –

2
/** 
* Copy database file from assets folder inside the apk to the system database path. 
* @param context Context 
* @param databaseName Database file name inside assets folder 
* @param overwrite True to rewrite on the database if exists 
* @return True if the database have copied successfully or if the database already exists without overwrite, false otherwise. 
*/ 
private boolean copyDatabaseFromAssets(Context context, String databaseName , boolean overwrite) { 

    File outputFile = context.getDatabasePath(databaseName); 
    if (outputFile.exists() && !overwrite) { 
     return true; 
    } 

    outputFile = context.getDatabasePath(databaseName + ".temp"); 
    outputFile.getParentFile().mkdirs(); 

    try { 
     InputStream inputStream = context.getAssets().open(databaseName); 
     OutputStream outputStream = new FileOutputStream(outputFile); 


     // transfer bytes from the input stream into the output stream 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = inputStream.read(buffer)) > 0) { 
      outputStream.write(buffer, 0, length); 
     } 

     // Close the streams 
     outputStream.flush(); 
     outputStream.close(); 
     inputStream.close(); 

     outputFile.renameTo(context.getDatabasePath(databaseName)); 

    } catch (IOException e) { 
     if (outputFile.exists()) { 
      outputFile.delete(); 
     } 
     return false; 
    } 

    return true; 
} 
+0

컨텍스트 개체의 getDatabasePath() 메서드와 outputFile.getParentFile(). mkdirs() 코드의 조합이 내 문제를 해결했기 때문에 +1을주었습니다. 다른 예제에서 보여주는 하드 코딩 된 디렉토리 경로. –

0
private void copyDataBase(Context context) throws IOException { 

    //Log.i(TAG, "Opening Asset..."); 
    // Open your local db as the input stream 
    InputStream myInput = context.getAssets().open(DBHelper.DATABASE_NAME); 

    // Log.i(TAG, "Getting db path..."); 
    // Path to the just created empty db 
    File dbFile = getDatabasePath(DBHelper.DATABASE_NAME); 

    if (!dbFile.exists()) { 
     SQLiteDatabase checkDB = context.openOrCreateDatabase(DBHelper.DATABASE_NAME, context.MODE_PRIVATE, null); 
     if (checkDB != null) { 
      checkDB.close(); 
     } 
    } 

    //Log.i(TAG, "Getting output stream..."); 
    // Open the empty db as the output stream 
    OutputStream myOutput = new FileOutputStream(dbFile); 

    // Log.i(TAG, "Writing data..."); 
    // 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(); 
}