1. Nimm jetzt an unserem Uhans - 3. ADVENT - Gewinnspiel teil - Alle Informationen findest Du hier!

SQLite-Datenbank in Emulator kopieren und Verbindung herstellen

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von marcel_at_work, 17.07.2011.

  1. marcel_at_work, 17.07.2011 #1
    marcel_at_work

    marcel_at_work Threadstarter Neuer Benutzer

    Beiträge:
    10
    Erhaltene Danke:
    0
    Registriert seit:
    13.07.2011
    Hallo liebe Gemeinde,

    ich lese mich seit knapp drei Wochen in die Android-Entwicklung ein, aber komme gerade trotz diverser Tutorials und der Android-Grundlagen nicht wirklich weiter.

    Ziel: Ich möchte eine auf der HDD befindliche SQLite-DB in den Emulator kopieren und dort zur Anzeige öffnen.

    Wie man im Emulator eine neue DB erstellen kann, ist mir nun zwar bewußt - in Bezug auf den 'Import' hilft mir dies aber trotzdem irgendwie nicht.

    Meine letzten Versuche bauen auf dem Tutorial von Using your own SQLite database in Android applications | ReignDesign Blog auf:

    Code:
    package de.autoDesk.activity;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import android.content.Context;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteException;
    import android.database.sqlite.SQLiteOpenHelper;
    
    public class DataBaseHelper extends SQLiteOpenHelper{
     
        //The Android's default system path of your application database.
        private static String DB_PATH = "/data/data/de.autoDesk.activity/databases/";
     
        private static String DB_NAME = "autoDesk.sqlite";
     
        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 DataBaseHelper(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) {
     
        }
     
            // Add your public helper methods to access and get content from the database.
           // You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
           // to you to create adapters for your views.
     
    }
    
    ... auf, die Console spuckt mir aber folgendes darauf aus:

    [2011-07-17 21:58:18 - autoDesk] ------------------------------
    [2011-07-17 21:58:18 - autoDesk] Android Launch!
    [2011-07-17 21:58:18 - autoDesk] adb is running normally.
    [2011-07-17 21:58:18 - autoDesk] Performing de.autoDesk.activity.DataBaseHelper activity launch
    [2011-07-17 21:58:18 - autoDesk] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD 'G1'
    [2011-07-17 21:58:20 - autoDesk] Uploading autoDesk.apk onto device 'emulator-5554'
    [2011-07-17 21:58:21 - autoDesk] Installing autoDesk.apk...
    [2011-07-17 21:58:24 - autoDesk] Success!
    [2011-07-17 21:58:24 - autoDesk] Starting activity de.autoDesk.activity.DataBaseHelper on device emulator-5554
    [2011-07-17 21:58:27 - autoDesk] New package not yet registered with the system. Waiting 3 seconds before next attempt.
    [2011-07-17 21:58:30 - autoDesk] Starting activity de.autoDesk.activity.DataBaseHelper on device emulator-5554
    [2011-07-17 21:58:33 - autoDesk] New package not yet registered with the system. Waiting 3 seconds before next attempt.
    [2011-07-17 21:58:36 - autoDesk] Starting activity de.autoDesk.activity.DataBaseHelper on device emulator-5554
    [2011-07-17 21:58:38 - autoDesk] New package not yet registered with the system. Waiting 3 seconds before next attempt.
    [2011-07-17 21:58:41 - autoDesk] Starting activity de.autoDesk.activity.DataBaseHelper on device emulator-5554
    [2011-07-17 21:58:43 - autoDesk] New package not yet registered with the system. Waiting 3 seconds before next attempt.
    [2011-07-17 21:58:46 - autoDesk] Starting activity de.autoDesk.activity.DataBaseHelper on device emulator-5554
    [2011-07-17 21:58:48 - autoDesk] ActivityManager: Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=de.autoDesk.activity/.DataBaseHelper }
    [2011-07-17 21:58:48 - autoDesk] ActivityManager: Error type 3
    [2011-07-17 21:58:48 - autoDesk] ActivityManager: Error: Activity class {de.autoDesk.activity/de.autoDesk.activity.DataBaseHelper} does not exist.

    Ich wäre für jeden Lösungsansatz dankbar.

    Liebe Grüße,

    Marcel
     
  2. marcel_at_work, 18.07.2011 #2
    marcel_at_work

    marcel_at_work Threadstarter Neuer Benutzer

    Beiträge:
    10
    Erhaltene Danke:
    0
    Registriert seit:
    13.07.2011
    Hallöchen,

    hat denn niemand einen Rat?:huh:

    Liebe Grüße
     
  3. Zoopa, 18.07.2011 #3
    Zoopa

    Zoopa Android-Experte

    Beiträge:
    599
    Erhaltene Danke:
    173
    Registriert seit:
    28.07.2010
    Deine Fehlermeldung sieht danach aus, als hättest du deine DataBaseHelper Klasse als Activity im Manifest deklariert, was natürlich nicht geht ;)
    Android versucht so, eine Activity zu laden, findet aber keine und die App crasht deshalb.

    Hast du irgendwo im Projekt eine Activity?
    Wenn ja: Manifest prüfen
    Wenn nein: Du brauchst erstmal eine lauffähige Activity, und darauf musst du dann aufbauen.
     
  4. marcel_at_work, 19.07.2011 #4
    marcel_at_work

    marcel_at_work Threadstarter Neuer Benutzer

    Beiträge:
    10
    Erhaltene Danke:
    0
    Registriert seit:
    13.07.2011
    Hey Zoopa,

    Thx, es scheint jetzt zumindest mal zu laufen - und dies ganz ohne Meldungen.:smile:

    Und wie kann man nun auf die DataBaseHelper-Klasse zugreifen - genauer: createDataBase() nach dem Start der App ausführen, um die DB anzulegen?

    Liebe Grüße
     
  5. Zoopa, 19.07.2011 #5
    Zoopa

    Zoopa Android-Experte

    Beiträge:
    599
    Erhaltene Danke:
    173
    Registriert seit:
    28.07.2010
    du erstellst irgendwo in deiner Activity (z.b. testhalber in der onCreate Methode) ein Objekt deiner DB-Klasse und ruftst dann die Methode daraus auf, etwa so:

    Code:
    DataBaseHelper myDBHelper = new DataBaseHelper(this);
    myDBHelper.createDataBase();
    
    Hinweis: Falls die DB extrem gross sein sollte und das kopieren sehr lange dauern würde, wäre es schlecht, das ganze direkt in der Activity zu machen (dadurch würde der UI-Thread blockiert und Android würde die App nach einigen Sekunden beenden). Dafür solltest du dann einen extra Thread erstellen, der die Arbeit erledigt.
     
    marcel_at_work bedankt sich.
  6. marcel_at_work, 19.07.2011 #6
    marcel_at_work

    marcel_at_work Threadstarter Neuer Benutzer

    Beiträge:
    10
    Erhaltene Danke:
    0
    Registriert seit:
    13.07.2011
    Thx, das war genau das, was ich gesucht habe. :w00t00:

    Liebe Grüße
     
    Zuletzt bearbeitet: 19.07.2011
  7. marcel_at_work, 25.07.2011 #7
    marcel_at_work

    marcel_at_work Threadstarter Neuer Benutzer

    Beiträge:
    10
    Erhaltene Danke:
    0
    Registriert seit:
    13.07.2011
    Hallöchen,

    ich versuche jetzt die ganze Zeit schon, mittels einer ListView eine Datenbank-Abfrage auf dem Display anzuzeigen, aber schaff es einfach nicht - trotz Forum und Tutorial.:scared:
    Meine Dateien sehen jetzt wie folgt aus:

    Code:
    package de.cocktailGuide.activity;
    
    import java.io.IOException;
    
    import android.app.Activity;
    import android.database.SQLException;
    import android.os.Bundle;
    import android.widget.ListView;
    import android.widget.TextView;
    
    public class CocktailGuide extends Activity
    {
        TextView txt;
        ListView list;
        
        // Aufruf bei der ersten Erstellung der Activity
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            setTitle(R.string.title_CocktailOverview); // Titel der View aus den Ressourcen auslesen und in der Titelleiste anzeigen
    
            txt = (TextView) findViewById(R.id.textView1);
            txt.setText("textView1 > ich auch");
            
    //        list = (ListView) findViewById(R.id.listView1);
            
    //        ArrayAdapter<CharSequence>  adapter = ArrayAdapter.createFromResource(this,  R.array.stauUrsachen,
    //                android.R.layout.simple_spinner_item);
    //        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    //        s1.setAdapter(adapter);
            
            
            DataBaseHelper db = new DataBaseHelper(this);
            try
            {
                db.createDataBase();
            }
            catch (IOException ioe)
            {
                 throw new Error("Fehler: Datenbank konnte nicht erstellt werden.");
             }
             try
             {
                 db.openDataBase();
             }
             catch(SQLException sqle)
             {
                 throw sqle;
             }
        }
    }
    
    Code:
    package de.cocktailGuide.activity;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import android.content.Context;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteException;
    import android.database.sqlite.SQLiteOpenHelper;
    
    public class DataBaseHelper extends SQLiteOpenHelper
    {
        private static String DB_PATH = "/data/data/de.cocktailGuide.activity/databases/";
        private static String DB_NAME = "cocktails.sqlite";
        private static final int DB_VERSION  =  1;
        private SQLiteDatabase db;
        private final Context oContext;
    
        // Konstruktor
        public DataBaseHelper(Context context)
        {
            super(context,DB_NAME, null, DB_VERSION);
            this.oContext = context;
        }
    
        // Anlegung einer leeren Datenbank...
        public void createDataBase() throws IOException
        {
            if(checkDataBase()) // Überprüfung auf Existenz der Datenbank im System-Ordner
            {
                // ... wenn TRUE, Operation beenden
            }
            else
            {
                // ... wenn FALSE,...
                this.getReadableDatabase();
    
                try
                {
                    copyDataBase(); // ... neu angelegte Datenbank mit der aus den Assets importierten überschreiben
                }
                catch (IOException e)
                {
                    throw new Error("Error copying database");
                }
            }
        }
    
        private boolean checkDataBase()
        {
            SQLiteDatabase oCheckDB = null;
    
            try
            {
                String sFilePath = DB_PATH + DB_NAME;
                oCheckDB = SQLiteDatabase.openDatabase(sFilePath, null, SQLiteDatabase.OPEN_READONLY);
            }
            catch(SQLiteException e)
            {
                // ...
            }
    
            if(oCheckDB != null)
            {
                oCheckDB.close();
            }
            return oCheckDB != null ? true : false;
        }
    
        private void copyDataBase() throws IOException
        {
            // lokale Datenbank als Input-Stream öffnen
            InputStream oInput = oContext.getAssets().open(DB_NAME);
            
            // gerade erstellte (leere) Datenbank als Output-Stream öffnen
            String sFilePath = DB_PATH + DB_NAME;
            OutputStream oOutput = new FileOutputStream(sFilePath);
    
            // Byte-Transfer von Input- nach Output-Stream
            byte[] buffer = new byte[1024];
            int length;
            while ((length = oInput.read(buffer))>0)
            {
                oOutput.write(buffer, 0, length);
            }
            oOutput.flush();
            oOutput.close();
            oInput.close();
        }
    
        public void openDataBase() throws SQLException
        {
            String sFilePath = DB_PATH + DB_NAME;
            db = SQLiteDatabase.openDatabase(sFilePath, null, SQLiteDatabase.OPEN_READONLY);
        }
    
        @Override
        public synchronized void close()
        {
                if(db != null)
                    db.close();
                super.close();
        }
    
        @Override
        public void onCreate(SQLiteDatabase db)
        {
    
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
    
        }
    }
    
    Code:
    package de.cocktailGuide.activity;
    
    import android.app.ListActivity;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.os.Bundle;
    import android.widget.SimpleCursorAdapter;
    
    public class CocktailsView extends ListActivity
    {
        SQLiteDatabase db = null;
        
        public void onCreate(Bundle icicle)
        {
            super.onCreate(icicle);
    
            Cursor mcCocktails = db.query(false, "cocktails", new String[]{"cocktails.TITLE"}, null, null, null, null, null, null);
            startManagingCursor(mcCocktails);
            
            SimpleCursorAdapter oAdapter = new SimpleCursorAdapter(this,
                    android.R.layout.simple_list_item_1,
                    mcCocktails,
                    new String[]{"cocktails.TITLE"},
                    new int[]{android.R.id.list});
            
            setListAdapter(oAdapter);
        }
    }
    
    Jemand einen Rat?

    Liebe Grüße
     

Diese Seite empfehlen