在android中的sdCard上创建SQLCiphered数据库时出错

时间:2012-11-22 17:16:38

标签: java android eclipse

我正在尝试在sdCard中创建一个sqlCipher加密数据库,然后从那里读取并存储值。

这是我的代码。

public class DataBaseHelper extends SQLiteOpenHelper 
{
    private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
    private static String DB_PATH ;//path of our database
    private static String DB_NAME = "application-database";// Database name
    private static int DATABASE_VERSION = 1;

    private SQLiteDatabase mDataBase; 
    private final Context mContext;

    private static final String DATABASE_CREATE_TABLE1 =
            "create table notes (_id integer primary key autoincrement, myval);";


    public DataBaseHelper(Context context) 
    {
        super(context, DB_NAME, null, DATABASE_VERSION );    
        this.mContext = context;
        DB_PATH = Environment.getExternalStorageDirectory() + "/Personal Folder/";
    }

    public void createDataBase() throws IOException
    {
        //If database not exists create it from the assets
        boolean mDataBaseExist = checkDataBase();
        if(!mDataBaseExist)
        {
          try 
          {
                File dbFile = new File(DB_PATH + DB_NAME);
                SQLiteDatabase.loadLibs(mContext);
                dbFile.mkdirs();
                dbFile.delete();
                SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, "setPassword", null);
                db.execSQL(DATABASE_CREATE_TABLE1);
                Log.e(TAG, "createDatabase database created");
          } 
          catch (SQLException mIOException) 
          {
                throw new Error("Error Creating Database");
          }
        }
    }

    private boolean checkDataBase()
    {
       File dbFile = new File(DB_PATH + DB_NAME);
       return dbFile.exists();
    }

    //Open the database, so we can query it
    public boolean openDataBase() throws SQLException
    {
        String mPath = DB_PATH + DB_NAME;
        SQLiteDatabase.loadLibs(mContext);
        mDataBase = SQLiteDatabase.openDatabase(mPath, "setPassword", null, SQLiteDatabase.CREATE_IF_NECESSARY);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() 
    {
        if(mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    {
       Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");

       /*
        if (oldVersion == 2)
        {
            db.execSQL("ALTER TABLE notes ADD " + KEY_DATA + " blog");
            db.execSQL("ALTER TABLE notes ADD " + KEY_TYPE + " text");

        }

        if (newVersion == 3)
        {
            db.execSQL("ALTER TABLE notes ADD " + KEY_TYPE + " text");
        }
        */
    }

    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub

    }

}


public class PADatabaseAdapter 
{
    private static final String TAG = "DbAdapter";
    private final Context mContext;
    private DataBaseHelper mDbHelper;
    private SQLiteDatabase mDb;

    /**
     * Database creation sql statement
     */
    public PADatabaseAdapter(Context ctx)
    {
        this.mContext = ctx;
        mDbHelper = new DataBaseHelper(mContext);
    }

    public PADatabaseAdapter createDatabase() throws SQLException 
    {
        try 
        {
            mDbHelper.createDataBase();
        } 
        catch (IOException mIOException) 
        {
            Log.e(TAG, mIOException.toString() + "  UnableToCreateDatabase");
            throw new Error("UnableToCreateDatabase");
        }
        return this;
    }

    public PADatabaseAdapter open(String password) throws SQLException 
    {
        try 
        {
            mDbHelper.openDataBase(password);
            //mDbHelper.close();
            mDb = mDbHelper.getmDataBase();
                    // mDbHelper.getWritableDatabase(password);

        } 
        catch (SQLException mSQLException) 
        {
            Log.e(TAG, "open >>"+ mSQLException.toString());
            throw mSQLException;
        }
        System.gc();
        return this;
    }

    public boolean isOpen ()
    {
        if (mDb !=null)
            return mDb.isOpen();
        else
            return false;
    }

    public void rekey (String password)
    {
        mDb.execSQL("PRAGMA rekey = '" + password + "'");
        System.gc();
    }

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

这是我在活动中使用的代码

   mContext = this;
   mDbHelper = new PADatabaseAdapter(this);        
   mDbHelper.createDatabase();

   mDbHelper.open("setPassword");
   long as = mDbHelper.createNote("abc");
   mDbHelper.close();

   mDbHelper.open("setPassword");
   Cursor mCursor =   mDbHelper.fetchAllNotes();
   mDbHelper.close();

问题是,在db.exec(CREATE_tABLE)中,它要么不创建表,要么其他错误,因为long as = mDbHelper.createNote("abc");给出了错误no such table notes

2 个答案:

答案 0 :(得分:1)

如果查看代码,您会看到:

@Override
public void onCreate(SQLiteDatabase arg0) {
    // TODO Auto-generated method stub

}

这个想法是你应该用填充数据库的实际代码替换// TODO。你可以告诉reading the documentation for SQLiteOpenHelper

  

您创建了一个实现onCreate(SQLiteDatabase),onUpgrade(SQLiteDatabase,int,int)和可选的onOpen(SQLiteDatabase)的子类,该类负责打开数据库(如果存在),创建数据库(如果不存在),以及升级如有必要。事务用于确保数据库始终处于合理状态。

然后使用getReadableDatabase()上的getWritableDatabase()SQLiteOpenHelper方法访问您的数据库。对于SQLCipher for Android这些方法的版本,您将密码作为参数传递。

因此,我建议您:

  1. SQLiteDatabase.loadLibs(mContext);移至构造函数。

  2. 删除剩余的openDataBase()和所有close()(因为该代码已存在)

  3. 重写checkDataBase()以清除无效DB_PATHuse getDatabasePath() instead

  4. db.execSQL(DATABASE_CREATE_TABLE1);移至onCreate()

  5. 删除剩余的createDataBase()

  6. 在您的活动中正确使用SQLiteOpenHelper

答案 1 :(得分:0)

为什么要对SQLiteOpenHelper进行子类化?此类的目的是管理数据库文件,打开/关闭它们,在必要时创建它们以及管理应用程序数据库对象(SQLiteDatabase)。

但是你自己这样做,而SQLiteOpenHelper.onCreate中的没有这意味着SQLiteOpenHelper什么都不做。如果您自己创建数据库文件,请不要继承SQLiteOpenHelper

SQLiteDatabase班是什么?我在offical one中没有看到任何loadLibs方法,也没有看到接受您传递的参数的openOrCreateDatabase / openDatabase重载...