Copie la base de datos de la carpeta de activos en un dispositivo sin raíz

Estoy tratando de copiar la base de datos de la carpeta de activos al 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.

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

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(); } 
  /** * 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; } 

No estoy seguro, pero esto funciona en todos los dispositivos en los que he probado. Robé este método (desde algún lugar aquí) y lo hice genérico para realizar copias de seguridad y restaurar:

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

Luego, simplemente lo respaldo llamando:

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

Donde getDatabasePath() y getDatabaseBackupPath() son solo valores de cadena

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

Esto funciona para Kotlin.

 assets.open("sqlite_db_in_assets.db") .copyTo(getDatabasePath("sqlite_db_in_device.db").outputStream())