Autore Topic: importare database esterno  (Letto 3900 volte)

Offline cnicola90

  • Nuovo arrivato
  • *
  • Post: 32
    • Mostra profilo
  • Sistema operativo:
    Windows 7
importare database esterno
« il: 18 Luglio 2012, 13:22:54 CEST »
Salve ragazzi, ho creato un database esterno, vorrei convertirlo in database SQLite per iportarlo in android..mi serve solo leggere le informazioni del database, non mi serve ne crearlo da capo ne inserire dati..come posso fare? Ho letto il tutorial per la creazione del database da zero, ma io il db l'ho gia creato mi serve solo importarlo in android

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:importare database esterno
« Risposta #1 il: 18 Luglio 2012, 13:35:37 CEST »
Prova a guardare se questo tutorial fa al caso tuo.

Using your own SQLite database in Android applications | ReignDesign
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline cnicola90

  • Nuovo arrivato
  • *
  • Post: 32
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:importare database esterno
« Risposta #2 il: 24 Luglio 2012, 11:29:07 CEST »
Ok ho seguito la guida e funziona..il problema è che quando aggiorno il database dall'esterno, ricopio il nuovo db nella cartella assets ma l'app mi legge sempre il vecchio database..in pratica devo fare un aggiornamento a mano, cioè ricopiare il nuovo db anche nella cartella data/data/mioPackage/databases tramite file explorer..c'è un modo per ricopiarlo in automatico?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:importare database esterno
« Risposta #3 il: 24 Luglio 2012, 12:20:36 CEST »
ricopio il nuovo db nella cartella assets
??? Quella che chiami cartella è una directory read-only, è impossibile scrivere al run-time, si trova solo nel pacchetto .apk ed è immutabile.
adb logcat | tee /tmp/logcat | grep TAG

Offline cnicola90

  • Nuovo arrivato
  • *
  • Post: 32
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:importare database esterno
« Risposta #4 il: 24 Luglio 2012, 12:42:40 CEST »
allora mi spiego meglio..io da eclipse copio il database nella directory assets; quando faccio partire l'app con l'avd il mio database che stava nella cartella assets viene copiato nella cartella data/data/[mioPackage]/databases, ed è qui che poi si trova il mio database fisicamente..però se in fase di sviluppo sovrascrivo il database che sta in assets non viene sovrascritto quello nella cartella databases..capito qual è il mio problema?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:importare database esterno
« Risposta #5 il: 24 Luglio 2012, 13:29:38 CEST »
Il database viene copiato dalla directory assets del file .apk solo la prima volta che viene eseguito il programma quando nessun database è presente. Se cambi il database nel progetto di Android e ri-lanci il programma non viene ricopiato perché il database esiste.

Il costruttore della classe "SQLiteOpenHelper" ha il parametro "version", il quale indica la versione del database. Se aggiorni il database devi incrementare il numero di versione del database. Devi implementare il metodo "onUpgrade" della classe "SQLiteOpenHelper" per aggiornare il database in base alla vecchia e alla nuova versione, devi decidere se ricopiare il database distruggendo quello vecchio o fare un aggiornamento più mirato con i soli cambiamenti tra le due versioni. La prima volta che lanci il programma verrà aggiornato il database con la nuova versione.

Se non incrementi la versione del database, il database non verrà mai aggiornato col codice scritto in "onUpgrade" anche se cambi il file nel progetto di Android.
adb logcat | tee /tmp/logcat | grep TAG

Offline cnicola90

  • Nuovo arrivato
  • *
  • Post: 32
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:importare database esterno
« Risposta #6 il: 24 Luglio 2012, 15:41:48 CEST »
ok e se per aggiornare il database lo scarico da un server e lo copio direttamente nella cartella data/data/[mioPackage]/database senza cambiarne il nome il vecchio database viene automaticamente sovrascritto giusto?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:importare database esterno
« Risposta #7 il: 24 Luglio 2012, 16:02:57 CEST »
Prima di fare quello che hai scritto, devi per forza chiudere il database se è aperto, bloccare qualsiasi accesso al database fino al temine della operazioni di aggiornamento.
adb logcat | tee /tmp/logcat | grep TAG

Offline cnicola90

  • Nuovo arrivato
  • *
  • Post: 32
    • Mostra profilo
  • Sistema operativo:
    Windows 7
Re:importare database esterno
« Risposta #8 il: 24 Luglio 2012, 16:08:46 CEST »
sisi il database lo chiudo alla fine di ogni operazione ;)

Offline Vins

  • Nuovo arrivato
  • *
  • Post: 2
    • Mostra profilo
  • Sistema operativo:
    Mac OS X 10.8
Re:importare database esterno
« Risposta #9 il: 22 Agosto 2014, 23:43:56 CEST »
Salve,
sarei interessato anche io a questo argomento.

Sto cercando disperatamente di far caricare alla mia app un file sqlite esterno ed ho proceduto in questo modo:

1) Creato il db con sqlite studio e salvato
2) Copiato il file .db in una directory "assets" creata nel mio progetto e sorella di build, libs, src, ecc..
3) Ho creato un helper in questo modo:

Codice: [Seleziona]
public class DatabaseHelper extends SQLiteOpenHelper
{
    private static String DATABASE_PATH;
    private static final String DATABASE_NAME = "inutility.db";
    private static final int DATABASE_VERSION = 33;
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    private static DatabaseHelper instance;
    public static synchronized DatabaseHelper getHelper(Context context)
    {
        if (instance == null)
            instance = new DatabaseHelper(context);

        return instance;
    }

    // Costruttore
    public DatabaseHelper(Context context)
    {


        super(context, DATABASE_NAME, null, DATABASE_VERSION);

        if(android.os.Build.VERSION.SDK_INT >= 4.2){
            DATABASE_PATH = context.getApplicationInfo().dataDir + "/databases/";
        } else {
            DATABASE_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        }
        //DATABASE_PATH = context.getApplicationInfo().dataDir + "/databases/";
        myContext = context;
        Log.i("dbhelper", "helper instanziato");
        try {
            createDataBase();
        }
        catch(Exception excp)
        {
            Log.e("Ecc onCreate.createDb", excp.getMessage());
        }
        try{
            openDataBase();
        }
        catch(Exception excp)
        {
            Log.e("Ecc onCreate.openDb", excp.getMessage());
        }
    }

    // Questo metodo viene chiamato durante la creazione del database
    @Override
    public void onCreate(SQLiteDatabase database)
    {
        try {
            createDataBase();
        }
        catch(Exception excp)
        {
            Log.e("Ecc onCreate.createDb", excp.getMessage());
        }
        try{
            openDataBase();
        }
        catch(Exception excp)
        {
            Log.e("Ecc onCreate.openDb", excp.getMessage());
        }
    }

    // Questo metodo viene chiamato durante l'upgrade del database, ad esempio quando viene incrementato il numero di versione
    @Override
    public void onUpgrade( SQLiteDatabase database, int oldVersion, int newVersion ) {

        //myContext.deleteDatabase(DATABASE_NAME);

        //database.execSQL("select 'drop table ' || name || ';' from sqlite_master where type = 'table';");


        if(android.os.Build.VERSION.SDK_INT >= 4.2){
            DATABASE_PATH = myContext.getApplicationInfo().dataDir + "/databases/";
        } else {
            DATABASE_PATH = "/data/data/" + myContext.getPackageName() + "/databases/";
        }
        Log.i("DB upgrade", "Upgrade ok");
        File fileDb = new File(DATABASE_PATH + DATABASE_NAME);
        if(fileDb.exists())
            fileDb.delete();
        onCreate(database);
    }

    @Override
    public synchronized void close() {

        if(myDataBase != null)
            myDataBase.close();

        super.close();

    }

    /**
     * Creates a empty database on the system and rewrites it with your own database.
     * */
    public void createDataBase() throws IOException{

        boolean dbExist = checkDataBase();

        if(dbExist){
            //do nothing - database already exist
            Log.i("DB Esiste", "Non copio nulla");
        }else{

            //By calling this method and empty database will be created into the default system path
            //of your application so we are gonna be able to overwrite that database with our database.
            this.getWritableDatabase();

            try {

                copyDataBase();

            } catch (IOException e) {
                Log.i("dbhelper", "errore copia db " + e.getMessage());
                throw new Error("Error copying database");

            }
        }

    }

    /**
     * Check if the database already exist to avoid re-copying the file each time you open the application.
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase(){

        SQLiteDatabase checkDB = null;

        try{
            String myPath = DATABASE_PATH + DATABASE_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
            Log.i("check DB", "Il db esiste");
        }catch(SQLiteException e){

            //database does't exist yet.
            Log.i("check DB", "Il db non esiste ancora");
        }

        if(checkDB != null){

            checkDB.close();

        }

        return checkDB != null ? true : false;
    }

    /**
     * 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() throws IOException{
        //Open your local db as the input stream
        try {
            InputStream myInput = myContext.getAssets().open(DATABASE_NAME);
            Log.i("copyDB", myInput.toString());
            // Path to the just created empty db
            String outFileName = DATABASE_PATH + DATABASE_NAME;
            Log.i("outFileName", DATABASE_PATH + DATABASE_NAME);
            //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();
        }
        catch(Exception excp)
        {
            Log.i("CopyDataBase err", excp.getMessage());
        }
    }

    public void openDataBase() throws SQLException{

        //Open the database
        String myPath = DATABASE_PATH + DATABASE_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
        Log.i("dbhelper", "db aperto ");
    }
}

e l'adapter:

public class DatabaseAdapter
{
    @SuppressWarnings("unused")
    private static final String LOG_TAG = DatabaseAdapter.class.getSimpleName();

    private Context context;
    private SQLiteDatabase database;
    private DatabaseHelper dbHelper;
    private String error;
    private Cursor privateCursor;
    public ArrayList<Hashtable> Rows;
    public String[] ColumnNames;
    private Hashtable<String, String> Row;

    public DatabaseAdapter(Context context) {
        this.context = context;
    }

    private DatabaseAdapter open() throws SQLException {
        dbHelper = new DatabaseHelper(context);
        try {
            database = dbHelper.getWritableDatabase();
        }catch(Exception excp){Log.e("DB Adapter", "Fallito a ricavare un db");}
        return this;
    }
.....
}



Purtroppo non mi fa fare nulla, mi dice sempre che è non riesce a leggere il file: data/data/[mioPackage]/databases/inutility.db perchè in lock...

qualche idea?

La parte da cui fallisce tutto è questa:

Codice: [Seleziona]
08-22 22:31:30.669    3039-3039/it.vinsystem.inutility E/SQLiteLog﹕ (14) cannot open file at line 29423 of [a611fa96c4]
08-22 22:31:30.669    3039-3039/it.vinsystem.inutility E/SQLiteLog﹕ (14) os_unix.c:29423: (2) open(/data/data/it.vinsystem.inutility/databases/inutility.db) -
08-22 22:31:30.676    3039-3039/it.vinsystem.inutility E/SQLiteDatabase﹕ Failed to open database '/data/data/it.vinsystem.inutility/databases/inutility.db'.
    android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
« Ultima modifica: 23 Agosto 2014, 04:33:22 CEST da Vins »