Autore Topic: Leggere dati da database importato  (Letto 392 volte)

Offline Solaire

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy SII
Leggere dati da database importato
« il: 15 Maggio 2014, 19:58:35 CEST »
0
Salve a tutti.

E' ormai da due giorni che cerco di risolvere questo problema, quindi vi chiederei di essere pazienti se è già stato discusso, ma veramente non riesco a venirne a capo  :-\

Cercando su internet ho trovato del codice che mi permette di importare nella mia app un database creato con "SQLite database browser", dopo aver copiato il file del database nella cartella "Assets" dell'applicazione.

Questo database, contiene una tabella con tre colonne, una per le domande, una per le risposte e una per le spiegazioni delle risposte (è un'app Quiz, dove si risponde vero o falso).

Quello che vorrei fare, è prendere una domanda a caso dal database e visualizzarla nell'apposita activity, e poi chiaramente fare lo stesso con le spiegazioni, ma quello sarà una conseguenza.

Come faccio a fare ciò? Ovvero, come faccio a leggere dei dati dal mio database?

Ho provato già ad arrangiarmi, ma purtroppo quando dovrebbe comparire l'activity che mi mostra la domanda, l'app crasha.

Vi posto il codice della GameActivity(dove dovrebbe comparire la domanda, il codice incriminato) e della classe DataBase (dove è importato il database e dove è presente il metodo getDomanda, con il quale dovrei leggere la domanda random dal database).

Grazie mille a chiunque potrà aiutarmi!


LogCat:

05-15 20:29:12.962: D/dalvikvm(5825): GC_FOR_ALLOC freed 338K, 18% free 6853K/8263K, paused 30ms, total 30ms
05-15 20:29:13.027: I/dalvikvm-heap(5825): Grow heap (frag case) to 18.957MB for 11796752-byte allocation
05-15 20:29:13.122: D/dalvikvm(5825): GC_CONCURRENT freed 34K, 8% free 18339K/19847K, paused 11ms+31ms, total 91ms
05-15 20:29:13.627: D/dalvikvm(5825): GC_FOR_ALLOC freed 31K, 8% free 18307K/19847K, paused 22ms, total 22ms
05-15 20:29:13.687: I/dalvikvm-heap(5825): Grow heap (frag case) to 44.205MB for 26542672-byte allocation
05-15 20:29:13.712: D/dalvikvm(5825): GC_CONCURRENT freed <1K, 4% free 44228K/45831K, paused 3ms+3ms, total 25ms
05-15 20:29:14.297: I/themeservice(5825): service connected
05-15 20:29:14.297: I/themeservice(5825): saving icon for /data/data/com.example.quizone_2/cache/com.example.quizone_2.png
05-15 20:29:14.407: D/libEGL(5825): loaded /system/lib/egl/libEGL_mali.so
05-15 20:29:14.472: D/libEGL(5825): loaded /system/lib/egl/libGLESv1_CM_mali.so
05-15 20:29:14.477: D/libEGL(5825): loaded /system/lib/egl/libGLESv2_mali.so
05-15 20:29:14.482: D/(5825): Device driver API match
05-15 20:29:14.482: D/(5825): Device driver API version: 10
05-15 20:29:14.482: D/(5825): User space API version: 10
05-15 20:29:14.482: D/(5825): mali: REVISION=Linux-r2p4-02rel0 BUILD_DATE=Thu Oct 25 08:43:05 KST 2012
05-15 20:29:14.532: D/OpenGLRenderer(5825): Enabling debug mode 0
05-15 20:29:15.527: I/themeservice(5825): unbinding service
05-15 20:29:17.317: D/dalvikvm(5825): GC_FOR_ALLOC freed 11821K, 29% free 33646K/46919K, paused 19ms, total 19ms
05-15 20:29:17.377: D/dalvikvm(5825): GC_FOR_ALLOC freed 499K, 26% free 34749K/46919K, paused 17ms, total 17ms
05-15 20:29:17.427: D/dalvikvm(5825): GC_FOR_ALLOC freed 493K, 24% free 35856K/46919K, paused 18ms, total 18ms
05-15 20:29:19.007: I/Choreographer(5825): Skipped 76 frames!  The application may be doing too much work on its main thread.
05-15 20:29:20.027: E/SpannableStringBuilder(5825): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
05-15 20:29:31.932: E/SQLiteLog(5825): (1) no such table: Quiz
05-15 20:29:31.932: D/AndroidRuntime(5825): Shutting down VM
05-15 20:29:31.932: W/dalvikvm(5825): threadid=1: thread exiting with uncaught exception (group=0x410fb2a0)
05-15 20:29:31.947: E/AndroidRuntime(5825): FATAL EXCEPTION: main
05-15 20:29:31.947: E/AndroidRuntime(5825): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.quizone_2/com.example.quizone_2.GameActivity}: android.database.sqlite.SQLiteException: no such table: Quiz (code 1): , while compiling: SELECT domande FROM Quiz WHERE _id = 4
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.ActivityThread.access$700(ActivityThread.java:140)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.os.Looper.loop(Looper.java:137)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.ActivityThread.main(ActivityThread.java:4921)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at java.lang.reflect.Method.invokeNative(Native Method)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at java.lang.reflect.Method.invoke(Method.java:511)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at dalvik.system.NativeStart.main(Native Method)
05-15 20:29:31.947: E/AndroidRuntime(5825): Caused by: android.database.sqlite.SQLiteException: no such table: Quiz (code 1): , while compiling: SELECT domande FROM Quiz WHERE _id = 4
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1013)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:624)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at com.example.quizone_2.DataBase.getDomanda(DataBase.java:154)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at com.example.quizone_2.GameActivity.onCreate(GameActivity.java:30)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.Activity.performCreate(Activity.java:5206)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
05-15 20:29:31.947: E/AndroidRuntime(5825):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
05-15 20:29:31.947: E/AndroidRuntime(5825):    ... 11 more
05-15 20:29:34.237: I/Process(5825): Sending signal. PID: 5825 SIG: 9


GameActivity (solo onCreate):

Codice (Java): [Seleziona]
public class GameActivity extends ActionBarActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_game);

                if (savedInstanceState == null) {
                        getSupportFragmentManager().beginTransaction()
                                        .add(R.id.container, new PlaceholderFragment()).commit();
                }
               
                long n = Math.round((Math.random()*4)+1);
               
                DataBase data = new DataBase(GameActivity.this);
               data.openDataBase();
                String domandona = data.getDomanda(n); //this is the method to query
               data.close();
               
                TextView question = (TextView)findViewById(R.id.domanda);
                question.setText(domandona);
        }


DataBase class

Codice (Java): [Seleziona]
public class DataBase extends SQLiteOpenHelper{
         
    //The Android's default system path of your application database.
    private static String DB_PATH = "/data/data/com.example.quizone_2/databases/";
 
    private static String DB_NAME = "QuizOne_DB";
 
    private SQLiteDatabase myDataBase;
 
    private final Context myContext;
 
    /**
     * Constructor
     * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
     * @param context
     */

    public DataBase(Context context) {
 
        super(context, DB_NAME, null, 1);
        this.myContext = context;
    }  
 
  /**
     * 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
        }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.getReadableDatabase();
 
                try {
 
                        copyDataBase();
 
                } catch (IOException e) {
 
                        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 = DB_PATH + DB_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;
    }
 
    /**
     * 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
        InputStream myInput = myContext.getAssets().open(DB_NAME);
 
        // Path to the just created empty db
        String outFileName = DB_PATH + DB_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();
 
    }
 
    public void openDataBase() throws SQLException{
 
        //Open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
 
    }
 
    @Override
        public synchronized void close() {
 
            if(myDataBase != null)
                    myDataBase.close();
 
            super.close();
 
        }
 
        @Override
        public void onCreate(SQLiteDatabase db) {
 
        }
 
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 
        }

        public String getDomanda(long number){
                String n = Long.toString(number);
               
            SQLiteDatabase db = this.getReadableDatabase();
            Cursor cursor = db.rawQuery("SELECT domande FROM Quiz WHERE _id = " + n, null);

            String domanda;
            // Check if you have a valid result and move to the first row to read it
            if(cursor.moveToFirst())
                domanda = cursor.getString(0);
            // Prevent a crash if there is no data for this name
            else
                domanda = "NULL";

            cursor.close();
            db.close();
            return domanda;
  }
}
« Ultima modifica: 15 Maggio 2014, 20:30:29 CEST da Solaire »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Leggere dati da database importato
« Risposta #1 il: 15 Maggio 2014, 20:19:30 CEST »
0
Prima di mettersi a leggere il codice, dovresti postare il LogCat del crash (il logcat è dove è scritta la causa del crash).
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Solaire

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy SII
Re:Leggere dati da database importato
« Risposta #2 il: 15 Maggio 2014, 20:30:58 CEST »
0
Prima di mettersi a leggere il codice, dovresti postare il LogCat del crash (il logcat è dove è scritta la causa del crash).

Grazie per la segnalazione, ho aggiornato il post  :-)

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Leggere dati da database importato
« Risposta #3 il: 15 Maggio 2014, 20:45:37 CEST »
0
Se vedi bene il LogCat, c'è scritto che non trova la tabella che hai indicato. Può essere dovuto al nome errato come al fallimento della copia.

Citazione
05-15 20:29:31.947: E/AndroidRuntime(5825): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.quizone_2/com.example.quizone_2.GameActivity}: android.database.sqlite.SQLiteException: no such table: Quiz (code 1): , while compiling: SELECT domande FROM Quiz WHERE _id = 4
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Solaire

  • Nuovo arrivato
  • *
  • Post: 4
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy SII
Re:Leggere dati da database importato
« Risposta #4 il: 15 Maggio 2014, 21:25:56 CEST »
0
Se vedi bene il LogCat, c'è scritto che non trova la tabella che hai indicato. Può essere dovuto al nome errato come al fallimento della copia.

Vero, non l'avevo notato, grazie mille!
Comunque il nome della tabella è corretta, quindi quell'errore dev'essere la conseguenza di qualcos'altro penso.
Il problema è che la classe del Database l'ho praticamente copiata e incollata da un sito, perchè non avevo idea di come fare ad importare un database esterno, quindi non saprei se possa esserci magari un errore nel caricamento del database.

C'è un test che posso fare per capirlo?

FIXED: Risolto il problema, tutta questione di codice errato
« Ultima modifica: 16 Maggio 2014, 12:08:55 CEST da Solaire »