2010-08-23 6 views
13

Próbuję wdrożyć aplikację z istniejącą bazą danych SQLite.Co to jest pełna klasa Pomocnika przeglądarki systemu Android dla istniejącej bazy danych SQLite?

Przeczytałem i usiłowałem zaimplementować kilka przykładów w Internecie, ale odkryłem, że zawsze brakuje jakiegoś kodu i albo nie kompilują się, albo nie działają zgodnie z reklamą.

Czy ktoś ma pełną klasę Pomocnika dla systemu Android w celu wdrożenia istniejącej bazy danych SQLite w systemie Android?

+0

Próbowałem przy użyciu kodu, ale to utknie w tej części: ActivityManager: Rozpoczęcie: Intent {act = android.intent.action.MAIN cat = [android.intent.category.LAUNCHER] cmp = com.mdegges/.MicheleActivity. Plik data/data/com.mdegges/database nigdy nie zostanie utworzony. – mdegges

+0

@mdegges Nie jestem pewien, co się tam dzieje. Z innych pytań wygląda na to, że utknąłeś również w części LAUNCHER. Czy jesteś w stanie wykonać test na cześć świata przed włączeniem kodu db? –

+0

Tak, udało mi się ukończyć wiele tuts (w tym cześć świat) na stronie dev. To dziwne, że żaden z przewodników, które wypróbowałem, nie zadziałał. Baza danych znajduje się w moim folderze zasobów, zmieniłem DB_PATH na prawidłowy folder wyjściowy i zmieniłem nazwę bazy danych na moją db (z rozszerzeniem i bez niego), ale brak szczęścia! – mdegges

Odpowiedz

27

Oto, co wymyśliłem, mam nadzieję, że pomoże to innym, którzy mieli problemy.

package com.MyPackage; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.util.UUID; 

import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.util.Log; 

public class AnyDBAdapter { 

    private static final String TAG = "AnyDBAdapter"; 
    private DatabaseHelper mDbHelper; 
    private static SQLiteDatabase mDb; 

    //make sure this matches the 
    //package com.MyPackage; 
    //at the top of this file 
    private static String DB_PATH = "/data/data/com.MyPackage/databases/"; 

    //make sure this matches your database name in your assets folder 
    // my database file does not have an extension on it 
    // if yours does 
    // add the extention 
    private static final String DATABASE_NAME = "data"; 

    //Im using an sqlite3 database, I have no clue if this makes a difference or not 
    private static final int DATABASE_VERSION = 3; 

    private final Context adapterContext; 

    public AnyDBAdapter(Context context) { 
     this.adapterContext = context; 
    } 

    public AnyDBAdapter open() throws SQLException { 
     mDbHelper = new DatabaseHelper(adapterContext); 

     try { 
      mDbHelper.createDataBase(); 
     } catch (IOException ioe) { 
      throw new Error("Unable to create database"); 
     } 

     try { 
      mDbHelper.openDataBase(); 
     } catch (SQLException sqle) { 
      throw sqle; 
     } 
     return this; 
    } 
    //Usage from outside 
    // AnyDBAdapter dba = new AnyDBAdapter(contextObject); //in my case contextObject is a Map 
    // dba.open(); 
    // Cursor c = dba.ExampleSelect("Rawr!"); 
    // contextObject.startManagingCursor(c); 
    // String s1 = "", s2 = ""; 
    // if(c.moveToFirst()) 
    // do { 
    // s1 = c.getString(0); 
    // s2 = c.getString(1); 
    // } while (c.moveToNext()); 
    // dba.close(); 
    public Cursor ExampleSelect(string myVariable) 
    { 
     String query = "SELECT locale, ? FROM android_metadata"; 
     return mDb.rawQuery(query, new String[]{myVariable}); 
    } 

    //Usage 
    // AnyDBAdatper dba = new AnyDBAdapter(contextObjecT); 
    // dba.open(); 
    // dba.ExampleCommand("en-CA", "en-GB"); 
    // dba.close(); 
    public void ExampleCommand(String myVariable1, String myVariable2) 
    { 
     String command = "INSERT INTO android_metadata (locale) SELECT ? UNION ALL SELECT ?"; 
     mDb.execSQL(command, new String[]{ myVariable1, myVariable2}); 
    } 

    public void close() { 
     mDbHelper.close(); 
    } 

    private static class DatabaseHelper extends SQLiteOpenHelper { 

     Context helperContext; 

     DatabaseHelper(Context context) { 
      super(context, DATABASE_NAME, null, DATABASE_VERSION); 
      helperContext = context; 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      Log.w(TAG, "Upgrading database!!!!!"); 
      //db.execSQL(""); 
      onCreate(db); 
     } 

     public void createDataBase() throws IOException { 
      boolean dbExist = checkDataBase(); 
      if (dbExist) { 
      } else { 

       //make sure your database has this table already created in it 
       //this does not actually work here 
       /* 
       * db.execSQL("CREATE TABLE IF NOT EXISTS \"android_metadata\" (\"locale\" TEXT DEFAULT 'en_US')" 
       *); 
       * db.execSQL("INSERT INTO \"android_metadata\" VALUES ('en_US')" 
       *); 
       */ 
       this.getReadableDatabase(); 
       try { 
        copyDataBase(); 
       } catch (IOException e) { 
        throw new Error("Error copying database"); 
       } 
      } 
     } 

     public SQLiteDatabase getDatabase() { 
      String myPath = DB_PATH + DATABASE_NAME; 
      return SQLiteDatabase.openDatabase(myPath, null, 
        SQLiteDatabase.OPEN_READONLY); 
     } 

     private boolean checkDataBase() { 
      SQLiteDatabase checkDB = null; 
      try { 
       String myPath = DB_PATH + DATABASE_NAME; 
       checkDB = SQLiteDatabase.openDatabase(myPath, null, 
         SQLiteDatabase.OPEN_READONLY); 
      } catch (SQLiteException e) { 
      } 
      if (checkDB != null) { 
       checkDB.close(); 
      } 
      return checkDB != null ? true : false; 
     } 

     private void copyDataBase() throws IOException { 

      // Open your local db as the input stream 
      InputStream myInput = helperContext.getAssets().open(DATABASE_NAME); 

      // Path to the just created empty db 
      String outFileName = DB_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(); 
     } 

     public void openDataBase() throws SQLException { 
      // Open the database 
      String myPath = DB_PATH + DATABASE_NAME; 
      mDb = SQLiteDatabase.openDatabase(myPath, null, 
        SQLiteDatabase.OPEN_READWRITE); 
     } 

     @Override 
     public synchronized void close() { 

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

      super.close(); 

     } 
    } 

} 
+1

Czy Twoja klasa może otworzyć bazę danych znajdującą się na karcie SD? – Thiago

+0

Jeśli masz istniejący db, który skopiowałeś na swoją kartę SD, prawdopodobnie spróbujesz usunąć wywołanie 'copyDataBase()' i zmienić DB_PATH w odpowiednie miejsce. Ale to tylko domysły. Wolałbym nie pozwolić użytkownikowi na bezpośredni dostęp do danych aplikacji, więc nigdy nie brałem pod uwagę tej opcji. –

+0

gdzie jest zdefiniowany mContext? – Carnivoris

4
DatabaseHelper dbHelper = new DatabaseHelper(getApplicationContext()); 

Upewnij się, że obiekt DatabaseHelper utworzysz raz w trakcie okresu użytkowania aplikacji i ponownie go wykorzystasz.

do odczytu danych:

SQLiteDatabase db = dbHelper.getReadableDatabase(); 

do odczytu i/modyfikacji danych:

SQLiteDatabase db = dbHelper.getWritableDatabase(); 

następnego użycia insert(), query(), update(), delete() metody obiektu SQLiteDatabase:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

Nie powinieneś również tworzyć bazy danych, bezpośrednio uzyskując dostęp do pliku sqlite, co robisz w metodzie createNewDatabase. Użyj metody execSQL() obiektu SQLiteDatabase w metodzie onCreate (...). Wykonaj tam zapytania CREATE TABLE.

+0

Cześć radek-k, czy mógłbyś rozwinąć swój pierwszy punkt? 'Upewnij się, że obiekt DatabaseHelper utworzysz raz podczas okresu istnienia aplikacji i ponownie go wykorzystasz. –

+1

Jeśli utworzysz obiekt DatabaseHelper wiele razy, upewnij się, że poprzednio została zamknięta baza danych - getWritableDatabase.close(). W wielowątkowym modelu aplikacji nie można odtworzyć DatabaseHelper, gdy nie zamknąłeś poprzedniej. Po prostu dostaniesz kilka wyjątków. Najlepszym rozwiązaniem jest utworzenie obiektu DatabaseHelper tylko jeden raz (w aplikacji na przykład) i używanie tego samego odwołania do obiektu przez cały czas. – plugmind

+1

Nie polecam używania 'getApplicationContext()'. Użyj tego zamiast tego, ponieważ cokolwiek reaguje na 'getApplicationContext()' jest 'Kontekstem'. – CommonsWare

Powiązane problemy