3

내 안드로이드 앱에 백업/복원 시스템을 구현하고 있습니다.SQLite DB 파일 복원

자동 백업은 2 분마다 발생합니다. 내 응용 프로그램을 제거한 다음 다시 설치 한 후 내 sd 카드에서 db 백업 파일을 복원하려고합니다. 복원이 잘이다, 다시 열리면 다음 사용자가 다시 내 응용 프로그램을 설치 할 때마다 사용자가 응용 프로그램을 닫으면
는,이 예외를 찾을 수없는 파일,하지만 및 :

백업 작동하지만, 문제는 여기에 있습니다. 어쨌든, 응용 프로그램을 처음 시작할 때 복원 문제가 발생합니다.

복원은 처음 시작할 때 수행되어야합니다.

참고 : backupExists 함수는 true를 반환합니다.

@Override 
public void onCreate(final Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if(backUpExists()){ 

     restoreDB(); 
     } 
} 
    private boolean backUpExists() 
    { 
    try{ 
     File sd = Environment.getExternalStorageDirectory(); 
     if (sd.canRead()){ 
      String backupDBPath = "myDB"; 
      File backupedDB = new File(sd, backupDBPath); 
      if(backupedDB.exists()){ 
       return true; 
      } 
     } 
    } catch(Exception ex) { 
     Toast.makeText(getBaseContext(), ex.toString(), Toast.LENGTH_LONG).show(); 
    } 
     return false; 
    } 
    private void restoreDB() 
    { 
    try{ 
     File sd = Environment.getExternalStorageDirectory(); 
     File data = Environment.getDataDirectory(); 

     if (sd.canWrite()) { 
      String restroredDBPath = "//data//myPackage//databases//myDB"; 
      String backupDBPath = "myDB"; 
      File restoredDB = new File(data, restroredDBPath); 
      File backupedDB = new File(sd, backupDBPath); 
       FileChannel src = new FileInputStream(backupedDB).getChannel(); 
       FileChannel dst = new FileOutputStream(restoredDB).getChannel(); 
       dst.transferFrom(src, 0, src.size()); 
       src.close(); 
       dst.close(); 
       Toast.makeText(getBaseContext(), restoredDB.toString(), Toast.LENGTH_LONG).show(); 

     } 
    } catch (Exception e) { 

     Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show(); 
    } 
    } 

는 역 추적은

09-09 22:49:50.931: I/Database(23206): sqlite returned: error code = 26, msg = statement aborts at 14: [SELECT COUNT(*) FROM Photos WHERE AlbumId=0] file is encrypted or is not a database 
09-09 22:49:50.931: D/AndroidRuntime(23206): Shutting down VM 
09-09 22:49:50.931: W/dalvikvm(23206): threadid=1: thread exiting with uncaught exception (group=0x4151c700) 
09-09 22:49:50.931: E/AndroidRuntime(23206): FATAL EXCEPTION: main 
09-09 22:49:50.931: E/AndroidRuntime(23206): net.sqlcipher.database.SQLiteException: file is encrypted or is not a database 
09-09 22:49:50.931: E/AndroidRuntime(23206): at  net.sqlcipher.database.SQLiteQuery.native_fill_window(Native Method) 
09-09 22:49:50.931: E/AndroidRuntime(23206): at net.sqlcipher.database.SQLiteQuery.fillWindow(SQLiteQuery.java:73) 
09-09 22:49:50.931: E/AndroidRuntime(23206): at net.sqlcipher.database.SQLiteCursor.fillWindow(SQLiteCursor.java:290) 
[snipped] 
+0

이있을 것이다 어디 정확히 예외가 발생합니까? 적절한 스택 트레이스를 얻으려면'try' /'catch'를 제거하십시오. –

+0

복원 된 DB를 사용하여 쿼리를 시도 할 때 "파일이 암호화되었거나 데이터베이스가 아닙니다."예외가 발생했습니다. 다음은 전체 스택 추적입니다. http://pastebin.com/j4tQU26K – idish

+0

@CL. 태그를 잊어 버린 경우 :) – idish

답변

14

당신을 도움이 코드를 사용하시기 바랍니다 ... 나는이 방법을 동일하게 수행 한 백업

try { 
    File sd = Environment.getExternalStorageDirectory(); 
    File data = Environment.getDataDirectory(); 

    if (sd.canWrite()) { 
     String currentDBPath = "//data/package name/databases/database_name"; 
     String backupDBPath = "database_name"; 
     File currentDB = new File(data, currentDBPath); 
     File backupDB = new File(sd, backupDBPath); 

     if (currentDB.exists()) { 
      FileChannel src = new FileInputStream(currentDB).getChannel(); 
      FileChannel dst = new FileOutputStream(backupDB).getChannel(); 
      dst.transferFrom(src, 0, src.size()); 
      src.close(); 
      dst.close(); 
      Toast.makeText(getApplicationContext(), "Backup is successful to SD card", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} catch (Exception e) { 
} 
를 들어

조건 경우 U되는 FileChannel 내부에 볼 수

try { 
    File sd = Environment.getExternalStorageDirectory(); 
    File data = Environment.getDataDirectory(); 

    if (sd.canWrite()) { 
    String currentDBPath = "//data/package name/databases/database_name"; 
     String backupDBPath = "database_name"; 
     File currentDB = new File(data, currentDBPath); 
     File backupDB = new File(sd, backupDBPath); 

     if (currentDB.exists()) { 
      FileChannel src = new FileInputStream(backupDB).getChannel(); 
      FileChannel dst = new FileOutputStream(currentDB).getChannel(); 
      dst.transferFrom(src, 0, src.size()); 
      src.close(); 
      dst.close(); 
      Toast.makeText(getApplicationContext(), "Database Restored successfully", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} catch (Exception e) { 
} 

둘 사이에 약간의 dfference를 복원.

+0

당신의 대답은 내 문제를 해결하지 못했지만 복원 작업 전에 실제로 일어난 일을 다시 한 번 살펴 보았습니다. 나는 새로운 DB 함수를 사용하고 있다는 것을 알았습니다. 그래서 모든 문제가 발생했습니다. 고맙습니다. – idish

0

필자가 생각한 문제는 기존의 db 파일을 읽는 것입니다. 당신은 실제로 그것을 읽고 있지 않습니다. 코드는 앱이 설치 될 때마다 새로운 코드를 생성하는 것입니다. 당신은 ... 당신이 당신의 getExternalEvironment 함수를 읽기 위해 참조하는 DB 파일의 정확한 이름을 지정

+0

흠, 문제는 이미 해결되었습니다. 해결책은 지정된 코드가 아니었지만 또 다른 문제가있었습니다.위의 답변에서 주석을보십시오, 감사합니다 :) – idish

3
try 
{ 
    String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); 
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/CALC/Backup"; 
    //final 
    String inFileName = path+"/Calc_backup :"+date; 
    File dbFile = new File(inFileName); 
    FileInputStream fis = new FileInputStream(dbFile); 


    /*File dir = new File(path); 
    if(!dir.exists()) 
     dir.mkdirs();*/ 
    //Toast.makeText(getActivity(), "directory created @"+dir.getPath(), 2).show(); 

    // String outFileName = Environment.getExternalStorageDirectory()+"Calac/hems.txt"; 

    //String outFileName = path+"/"+date; 
    String outFileName = "/data/data/com.special.ResideMenuDemo/databases/Calq"; 

    // Open the empty db as the output stream 
    OutputStream output = new FileOutputStream(outFileName); 

    // Transfer bytes from the inputfile to the outputfile 
    byte[] buffer = new byte[1024]; 
    int length; 

    while ((length = fis.read(buffer))>0) 
    { 
     output.write(buffer, 0, length); 
    } 

    Toast.makeText(getActivity(), "Restore Successfully", 2).show(); 
    // Close the streams 
    output.flush(); 
    output.close(); 
    fis.close(); 

} 
catch(Exception e) 
{ 
    e.printStackTrace(); 
}