0

我目前正在开发一个包含 SQLite 数据库的 android 应用程序。我正在尝试使用 Android 2.1 的模拟器,它工作正常..但它不适用于比 Android 2.1 更新的版本 ....在我的应用程序中,我在 SQLite 管理器上创建了一个外部 SQLite 数据库,然后我在第一次启动应用程序时将此数据库复制到“/data/data/”+ getPackageName()+“/databases/MyDB”。
从资产文件夹复制数据库的代码:

try{

                try {           
                    String destPath = "/data/data/" + getPackageName() + "/databases/MyDB";
                    File f = new File(destPath);            
                    if (!f.exists()) {          
                        CopyDB( getBaseContext().getAssets().open("mydb"), 
                            new FileOutputStream(destPath));
                    }
                } catch (FileNotFoundException e) {         
                    e.printStackTrace();

复制数据库功能:

public void CopyDB(InputStream inputStream, OutputStream outputStream) 
        throws IOException {
            //---copy 1K bytes at a time---
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }
            outputStream.flush();
            inputStream.close();
            outputStream.close();
        }

DBAdapter 类:

public class DBAdapter {
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "username";
public static final String KEY_PASSWORD = "password";


private static final String DATABASE_NAME = "MyDB";
private static final String DATABASE_TABLE = "users";
private static final int DATABASE_VERSION = 3;



private final Context context;    

private DatabaseHelper DBHelper;
private SQLiteDatabase db;

public DBAdapter(Context ctx) 
{
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
}

private static class DatabaseHelper extends SQLiteOpenHelper 
{
    DatabaseHelper(Context context) 
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) 
    {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    {

    }
}    

//---opens the database---
public DBAdapter open() throws SQLException 
{
    db = DBHelper.getWritableDatabase();
    return this;
}

//---closes the database---    
public void close() 
{
    DBHelper.close();
}


//---retrieves all the users---
public Cursor getAllusers() 
{
    return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
            KEY_PASSWORD}, null, null, null, null, null);
}

//---retrieves a particular user---
public User getuser(String username) throws SQLException 
{

    Cursor mCursor =
            db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
            KEY_NAME, KEY_PASSWORD}, KEY_NAME + "=" + "'"+username+ "'", null,
            null, null, null, null);
    if(mCursor.moveToFirst())
    {
        mCursor.moveToFirst();
        User u=new User(Integer.valueOf(mCursor.getString(0)),mCursor.getString(1),mCursor.getString(2));
        return u;
    }else
        return null;

}

public List<Device> getNotupdatedDevices() {
    List<Device> Devices = new ArrayList<Device>();

    SQLiteDatabase db = DBHelper.getWritableDatabase();
    Cursor myCursor =
            db.query("Devices", new String[] {"_DeviceID","current_state","current_level","current_CD_Channel" }, "updated=?", new String[] {"false"}, null, null, null);

    if (myCursor.moveToFirst()) {
        do {
            Device d = new Device(Integer.valueOf(myCursor.getString(0)), myCursor.getString(1),Integer.valueOf(myCursor.getString(2)), Float.valueOf(myCursor.getString(3)));

            Devices.add(d);
        } while (myCursor.moveToNext());
        return Devices;
    }

    return null;

    }


public Device getDevice(String DeviceType,String RoomType,int floor) throws SQLException 
{
    Cursor mCursor =
          db.query("Rooms", new String[] {"_RoomID" }, "RoomType=? AND floor=?", new String[] {RoomType, floor+""}, null, null, null);

    if(mCursor.moveToFirst())
    {
        mCursor.moveToFirst();

        int id=Integer.valueOf(mCursor.getString(0));
        Cursor myCursor =
                db.query("Devices", new String[] {"current_state","current_level","current_CD_Channel" }, "DeviceType=? AND RoomID=?", new String[] {DeviceType, id+""}, null, null, null);

        if(myCursor.moveToFirst())
        {
            myCursor.moveToFirst();     
            Device d=new Device(DeviceType,floor,RoomType,myCursor.getString(0), Integer.valueOf(myCursor.getString(1)),Float.valueOf(myCursor.getString(2)));
            return d;
        }else 
            return null;
    }else
        return null;

}



public void updateDevice(int floor, String RoomType, String DeviceType, String current_state,int current_level,float current_CD_Channel  ) {
    SQLiteDatabase db = DBHelper.getWritableDatabase();

    Cursor mCursor =
            db.query("Rooms", new String[] {"_RoomID" }, "RoomType=? AND floor=?", new String[] {RoomType, floor+""}, null, null, null);

        mCursor.moveToFirst();

        int id=Integer.valueOf(mCursor.getString(0));

    ContentValues values = new ContentValues();
    values.put("current_state", current_state);
    values.put("current_level", current_level);
    values.put("current_CD_Channel", current_CD_Channel);
    values.put("updated", "false");


    db.update("Devices", values, "RoomID= ? AND DeviceType=?",new String[] { String.valueOf(id),DeviceType  });

    db.close();
}


public void SyncDevice(int id, String current_state,int current_level,float current_CD_Channel  ) {
    SQLiteDatabase db = DBHelper.getWritableDatabase();



    ContentValues values = new ContentValues();
    values.put("current_state", current_state);
    values.put("current_level", current_level);
    values.put("current_CD_Channel", current_CD_Channel);
    values.put("updated", "true");

    // updating row
    db.update("Devices", values, "_DeviceID= ?", new String[] { String.valueOf(id) });
    db.close();
}

}

在冰淇淋三明治模拟器上运行应用程序时的 logcat 消息:

    06-26 22:59:29.418: E/AndroidRuntime(6230): FATAL EXCEPTION: main

06-26 22:59:29.418: E/AndroidRuntime(6230): android.database.sqlite.SQLiteException: no such table: users: , while compiling: SELECT DISTINCT _id, username, password FROM users WHERE username='aya'

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:68)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:127)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:94)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:53)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1564)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1449)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1405)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at cse.HomeAutomation.DBAdapter.getuser(DBAdapter.java:79)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at cse.HomeAutomation.Login$1.onClick(Login.java:53)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.view.View.performClick(View.java:3511)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.view.View$PerformClick.run(View.java:14105)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.os.Handler.handleCallback(Handler.java:605)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.os.Handler.dispatchMessage(Handler.java:92)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.os.Looper.loop(Looper.java:137)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at android.app.ActivityThread.main(ActivityThread.java:4424)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at java.lang.reflect.Method.invokeNative(Native Method)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at java.lang.reflect.Method.invoke(Method.java:511)
06-26 22:59:29.418: E/AndroidRuntime(6230):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)

06-26 22:59:29.418: E/AndroidRuntime(6230):     at dalvik.system.NativeStart.main(Native Method)

我进行了很多搜索,但没有找到解决这个问题的方法......提前非常感谢你:)

4

2 回答 2

0

你有一个复制数据库的功能,但你没有显示你从哪里调用它......这可能会影响结果。我通常在我的 db 助手类的构造函数中调用这样的东西(它也都包含在其中)。

编辑

完整示例

public class DBAdapter {
    // DB info
    public static final String MAIN_DATABASE_NAME = "Bowers";
    public static final int MAIN_DATABASE_VERSION = 1;
    public static String MAIN_DB_PATH = "/data/data/cdc.workshopapps.BowersMfgHelper/databases/";

    // static strings removed for brevity

    // database control variables
    private DatabaseHelper mDbHelper;
    private static SQLiteDatabase mDb;
    private static Context mCtx;

    private static class DatabaseHelper extends SQLiteOpenHelper {
        DatabaseHelper(Context context, String dbname, int dbversion) {
            super(context, dbname, null, dbversion);
            if (checkDataBase(dbname)) {
                openDataBase(dbname);
            } else {
                try {
                    this.getReadableDatabase();
                    copyDataBase(dbname);
                    this.close();
                    openDataBase(dbname);
                } catch (IOException e) {
                    throw new Error("Error copying database");
                }
                Toast.makeText(context,
                        "Initial " + dbname + " database has been created",
                        Toast.LENGTH_LONG).show();
            }
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
    public DBAdapter(Context ctx) {
        DBAdapter.mCtx = ctx;
    }
    public DBAdapter open(String dbname, int dbversion) throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx, dbname, dbversion);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }
    public void close() {
        mDbHelper.close();
    }
    private static void copyDataBase(String dbname) throws IOException {
        InputStream myInput = mCtx.getAssets().open(dbname);
        String outFileName = MAIN_DB_PATH + dbname;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }
    private static boolean checkDataBase(String dbname) {
        SQLiteDatabase checkDB = null;
        boolean exist = false;
        try {
            String db = MAIN_DB_PATH + dbname;
            checkDB = SQLiteDatabase.openDatabase(db, null,
                    SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            Log.v("db log", "database does't exist");
        }
        if (checkDB != null) {
            exist = true;
            checkDB.close();
        }
        return exist;
    }
    private static void openDataBase(String dbname) throws SQLException {
        String dbPath = MAIN_DB_PATH + dbname;
        mDb = SQLiteDatabase.openDatabase(dbPath, null,
                SQLiteDatabase.OPEN_READWRITE);
    }
    // insert, update, delete and cursor methods follow, removed for brevity
}

我已经用这个直到Android 3.2 ...

于 2012-06-30T11:30:52.340 回答
0
  • android.database.sqlite.SQLiteException: no such table: users: , while compile: SELECT DISTINCT _id, username, password FROM u

您尚未创建表

@Override
        public void onCreate(SQLiteDatabase db) 
        {

        }

应该

http://www.vogella.com/articles/AndroidSQLite/article.html

// Database creation sql statement
    private static final String DATABASE_CREATE = "create table "
            + TABLE_COMMENTS + "(" + COLUMN_ID
            + " integer primary key autoincrement, " + COLUMN_COMMENT
            + " text not null);";

    public MySQLiteHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(DATABASE_CREATE);//<--------------------
    }
于 2012-06-30T06:14:43.443 回答