Ciao ragazzi,
vorrei creare un applicazione che utilizzi un db sqlite esistente (già popolato), senza necessità di crearne uno da zero.
Non ho nessun problema ad utilizzare dall'applicazione il file del db esistente copiandolo 'a mano' in /data/data/package/databases/nomedb, il db è accessibile e riesco a completare qualsiasi query sui dati esistenti.
La struttura dell'app è molto semplice, ho utilizzato una classe SQLiteAdapter per l'accesso al db:
codice:
package mia.applicazione.test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public class SQLiteAdapter {
public static String DB_PATH = "/data/data/mia.applicazione.test/databases/";
public static final String MYDATABASE_NAME = "sqliteAndroid.sqlite";
public static final String MYDATABASE_TABLE = "ImportFileChiamata";
public static final int MYDATABASE_VERSION = 1;
public static final String KEY_CONTENT = "CodiceChiamata";
private SQLiteHelper sqLiteHelper;
private SQLiteDatabase sqLiteDatabase;
private Context context;
public SQLiteAdapter(Context c){
context = c;
}
public SQLiteAdapter openToRead() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getReadableDatabase();
return this;
}
public SQLiteAdapter openToWrite() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
return this;
}
public void close(){
sqLiteHelper.close();
}
public long insert(String content){
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_CONTENT, content);
return sqLiteDatabase.insert(MYDATABASE_TABLE, null, contentValues);
}
public int deleteAll(){
return sqLiteDatabase.delete(MYDATABASE_TABLE, null, null);
}
public String queueAll(){
String[] columns = new String[]{KEY_CONTENT};
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, columns,
null, null, null, null, null);
String result = "";
int index_CONTENT = cursor.getColumnIndex(KEY_CONTENT);
for(cursor.moveToFirst(); !(cursor.isAfterLast()); cursor.moveToNext()){
result = result + cursor.getString(index_CONTENT) + "\n";
}
return result;
}
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
//db.execSQL(SCRIPT_CREATE_DATABASE);
try {
if (checkDataBase()) {
}
else
{
copyDatabase();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void copyDatabase() throws IOException {
InputStream assetsDB = context.getAssets().open("dbtest.sqlite");
OutputStream dbOut = new FileOutputStream("/data/data/mia.applicazione.test/databases/sqliteAndroid.sqlite");
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer))>0){
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
assetsDB.close();
}
public boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + MYDATABASE_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database does't exist yet.
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
}
}
e questa invece è l'activity che, attualmente, ha soltanto un pulsante per eseguire una prova di SELECT su una tabella esistente, memorizza il risultato della query in un array di stringhe e visualizza il contenuto dell'array in un TextView sul Layout principale:
codice:
package mia.applicazione.test;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class Applicazione1Activity extends Activity {
/** Called when the activity is first created. */
private SQLiteAdapter miodb;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Context context = getApplicationContext();
miodb = new SQLiteAdapter(this);
Button mioPulsante1 = (Button) findViewById(R.id.button1);
final TextView mioTextView1 = (TextView) findViewById(R.id.textView1);
mioPulsante1.setOnClickListener(new OnClickListener() {
public void onClick(View v){
//istruzioni pulsante
miodb.openToRead();
String contenutoletto = miodb.queueAll();
miodb.close();
mioTextView1.setText(contenutoletto);
}
});
}
}
Di concetto vorrei sfruttare il metodo OnCreate, della classe SQLiteAdapter, per poter eseguire la copia del database preesistente (che nel package, in Eclipse, inserisco sotto 'Assets') nel path predefinito /data/data/miopacchetto/databases, con un piccolo controllo che se già esiste non deve farlo (qualora si disinstalli e si reinstalli l'apk).
Il problema è la copia del file sqlite già esistente. Nel senso che la copia del file avviene regolarmente, solo che se faccio pull del file destinazione copiato in /data/data/... ottengo un database vuoto, compresivo solo della tabella android_metadata. In pratica durante la copia il db si 'svuota' di tutte le tabelle preesitenti.
Cosa potrebbe causare questo effetto? Avete qualche suggerimento/intuizione?