SQLite-Datenbank in Emulator kopieren und Verbindung herstellen

M

marcel_at_work

Neues Mitglied
0
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
 
Hallöchen,

hat denn niemand einen Rat?:huh:

Liebe Grüße
 
ActivityManager: Error: Activity class {de.autoDesk.activity/de.autoDesk.activity.DataBaseHelper} does not exist

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.
 
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
 
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.
 
  • Danke
Reaktionen: marcel_at_work
Thx, das war genau das, was ich gesucht habe. :scared:

Liebe Grüße
 
Zuletzt bearbeitet:
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
 

Ähnliche Themen

S
Antworten
33
Aufrufe
2.676
Sempervivum
S
R
Antworten
6
Aufrufe
1.016
swa00
swa00
S
Antworten
4
Aufrufe
995
Sempervivum
S
Zurück
Oben Unten