2012-05-24 17 views
14

Estoy intentando copiar la base de datos de la carpeta de activos en el dispositivo. Este código funciona bien en emulador y dispositivo rooteado. Solo quiero saber si crea algún problema en un dispositivo sin raíz o funcionará igual.Copiar la base de datos de la carpeta de activos en un dispositivo sin raíz

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

Si el fragmento de código funciona perfectamente en dispositivos sin raíces también :) –

Respuesta

13

Esto funcionará con seguridad en todos los dispositivos y emuladores, sin necesidad de rootear.

/** 
* 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

Mi código también está funcionando bien, solo quiero saber si crea algún problema en un dispositivo sin raíz. –

+0

No estoy seguro. el código anterior funcionará bien y el tuyo también. –

+13

** NUNCA HARDCODE PATHS **. El valor 'outFileName' será incorrecto en muchos entornos Android, como las cuentas secundarias. Use 'getDatabasePath()' para derivar la ruta para un archivo de base de datos. – CommonsWare

1

No estoy seguro, pero esto funciona en todos los dispositivos que he probado. Robé este método (de aquí en alguna parte) y lo hice genérica tanto para realizar copias de seguridad y restauración:

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() 
    } 
} 

Entonces sólo una copia de seguridad llamando al:

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

Dónde getDatabasePath() y getDatabaseBackupPath() son sólo cuerdas valores

+0

Mi código es también trabajaba muy bien Sólo quiero saber es que crea ningún problema en el dispositivo sin raíces? –

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

Di un +1 porque la combinación del método getDatabasePath() del objeto de contexto y el archivo outputFile.getParentFile(). mkdirs() de su código resolvió mi problema en el que la copia de la base de datos estaba fallando cuando usé el ruta de directorio codificada que otros ejemplos muestran. –

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(); 
} 
Cuestiones relacionadas