android - samsung - La base de datos no se copia correctamente en OnePlus Two
oneplus 2 duos (3)
Estoy creando una aplicación para Android y estoy usando la base de datos sqlite en ella. para eso he colocado un archivo sqlite en la carpeta de activos del proyecto y estoy copiando este archivo en el teléfono mientras mi primera ejecución de la aplicación utiliza el código a continuación.
private void copyDataBase() throws IOException {
new File(DB_PATH).mkdirs();
InputStream myInput = appContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
Pero estoy recibiendo estos errores.
09-21 18:03:56.841: E/SQLiteLog(7850): (1) no such table: tbl_player
pero esta tabla existe en el archivo de activos. así que busqué el archivo de la base de datos del teléfono usando este método.
public static void exportDB(String databaseName, Context context) {
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath = "//data//" + context.getPackageName()
+ "//databases//" + databaseName + "";
String backupDBPath = "sensor_game.db";
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();
}
}
} catch (Exception e) {
}
}
y encontré que no hay tabla en el archivo de base de datos recuperado.
Nota: este problema ocurre solo en OnePlus Two
y funciona bien en Nexus 4
, Htc 820
, Moto E
, Galxy S3
y Galaxy Quottro
Después de largos intentos y búsquedas, me obligué a asumir que debería haber un error en la fabricación de OP2, ya que funciona bien en todos los demás dispositivos.
y cambié mi enfoque para crear la base de datos utilizando la consulta en lugar de copiar el archivo de base de datos de los activos. como el siguiente código
import java.io.File;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MySQLiteHelper extends SQLiteOpenHelper implements DBConstants {
private static MySQLiteHelper mInstance = null;
private SQLiteDatabase myDataBase;
private static String DB_PATH = "";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
try {
if (checkDataBase())
openDataBase();
else
myDataBase = this.getReadableDatabase();
} catch (Exception e) {
}
}
public static MySQLiteHelper instance(Context context) {
File outFile = context.getDatabasePath(DATABASE_NAME);
DB_PATH = outFile.getPath();
if (mInstance == null) {
mInstance = new MySQLiteHelper(context);
}
return mInstance;
}
private void openDataBase() throws Exception {
try {
myDataBase = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLException e) {
// TODO: handle exception
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
checkDB = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
/** database does''t exist yet. */
} catch (Exception e) {
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.v("log_tag", "onCreate");
myDataBase = db;
// creating a sample table
String CREATE_DEVICE_TABLE = "CREATE TABLE " + DEVICE + " ("
+ KEY_DEVICEID + " TEXT, " + KEY_OPERATOR + " TEXT, "
+ KEY_DEVICENAME + " TEXT, " + KEY_DEVICETOTALMEMORY
+ " INTEGER, " + KEY_SCREENWIDTH + " INTEGER, "
+ KEY_SCREENHEIGHT + " INTEGER, " + KEY_OPERATINGSYSTEM
+ " TEXT)";
db.execSQL(CREATE_DEVICE_TABLE);
// other tables also can be created from here.
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DEVICE);
// Create tables again (as per requirement)
this.onCreate(db);
}
public Cursor rawQuery(String qry) {
return myDataBase.rawQuery(qry, null);
}
public long insert(String tableName, ContentValues cv) {
return myDataBase.insert(tableName, null, cv);
}
public void insertWithOnConflict(String tableName, ContentValues cv,
int flag) {
myDataBase.insertWithOnConflict(tableName, null, cv, flag);
}
public long update(String tableName, ContentValues cv, String whereClose) {
return myDataBase.update(tableName, cv, whereClose, null);
}
public int deleteData(String table_name, String whereClause) {
return (int) myDataBase.delete(table_name, whereClause, null);
}
}
Y funcionó para mí
¡Gracias!
He encontrado solución para esto, he usado la siguiente función:
public void createDb() {
boolean dbExist = checkDataBase();
if (dbExist) {
// do nothing - database already exist
} else {
// call close() for properly copy database file
this.getReadableDatabase().close();
try {
copyDataBase();
} catch (IOException e) {
e.printStackTrace();
throw new Error("Error copying database");
}
}
}
Según esta publicación, debemos llamar a close()
y también puede enviar la base de datos a dos dispositivos Oneplus.
La ruta de la base de datos puede ser diferente en diferentes dispositivos. Context.getDatabasePath(String)
usar Context.getDatabasePath(String)
para obtener la ruta de la base de datos.
p.ej
File backupDB = context.getDatabasePath(backupDBPath);