2010-08-23 92 views
13

我想用现有的SQLite数据库部署一个应用程序。什么是现有SQLite数据库的完整Android数据库帮助器类?

我已经通读并试图在线实现多个示例,但是我发现它们总是缺少一些代码,并且不会按照所宣传的进行编译或工作。

有没有人有一个完整的Android数据库帮助类在Android上部署现有的SQLite数据库?

+0

我用你的代码尝试,但它卡住在这一部分: ActivityManager:开始:意向{行动= android.intent.action.MAIN猫= [android.intent.category.LAUNCHER] CMP = com.mdegges/.MicheleActivity。 data/data/com.mdegges/database文件永远不会被创建。 – mdegges 2012-03-06 20:10:40

+0

@mdegges我不知道那里出了什么问题。从你的其他问题看,你似乎也陷在了LAUNCHER部分。在包含db代码之前,您能够执行hello world测试吗? – 2012-03-06 21:36:07

+0

是的,我已经能够在开发者网站上完成大量的内容(包括hello world)。奇怪的是,我尝试过的指南都没有工作。数据库在我的资产文件夹中,我将DB_PATH更改为正确的输出文件夹,并且将db名称更改为我的数据库(有和没有扩展名),但没有运气! – mdegges 2012-03-06 21:55:48

回答

27

这就是我想出来的,希望它可以帮助其他有麻烦的人。

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

您的班级可以打开驻留在SD卡上的数据库吗? – Thiago 2011-07-20 19:51:52

+0

如果你有一个现有的数据库,你自己复制到你的SD卡我想你可以尝试删除'copyDataBase()'调用并将DB_PATH更改为适当的位置。但这只是一个猜测。我宁愿不让用户直接访问应用程序数据,所以我从来没有考虑过这个选项。 – 2011-07-20 21:47:25

+0

其中是mContext定义? – Carnivoris 2011-07-26 17:53:22

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

确保在应用程序生命周期中创建DatabaseHelper对象一次并重用它。

为了读取数据:

SQLiteDatabase db = dbHelper.getReadableDatabase(); 

对于读/修改数据:

SQLiteDatabase db = dbHelper.getWritableDatabase(); 

下次使用insert()query()update(),SQLiteDatabase对象的delete()方法:

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

你也不应该通过直接访问sqlite文件来创建你在createNewDatabase方法中做的事情。 在onCreate(...)方法中使用SQLiteDatabase对象的execSQL()方法。在那里执行你的CREATE TABLE查询。

+0

嗨radek-k,你能扩展你的第一点吗? '确保在应用程序生命周期中创建一次DatabaseHelper对象并重用它。' – 2010-08-23 19:30:18

+1

如果您多次创建DatabaseHelper对象,请确保先前已关闭数据库 - getWritableDatabase.close()。在多线程应用程序模型中,当您没有关闭前一个时,您不能重新创建DatabaseHelper。你只会得到一些例外。最好的方法是仅创建一次DatabaseHelper对象(例如,在Application中),并始终使用相同的对象引用。 – plugmind 2010-08-23 19:46:31

+1

我不会推荐使用'getApplicationContext()'。因为无论对“getApplicationContext()”作出响应的是“Context”。 – CommonsWare 2010-08-23 21:51:17