1

I am trying to create a sqlCipher encrypted database in sdCard and then read from there and store values.

This is my code.

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();
    }

This is the code I am using in my activity

   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();

The problem is, in db.exec(CREATE_tABLE) it either does not create table OR something else is wrong because long as = mDbHelper.createNote("abc"); gives error no such table notes

4

2 回答 2

1

If you look at your code, you will see:

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

}

The idea is that you are supposed to replace the // TODO with actual code that populates the database. You can tell this reading the documentation for SQLiteOpenHelper:

You create a subclass implementing onCreate(SQLiteDatabase), onUpgrade(SQLiteDatabase, int, int) and optionally onOpen(SQLiteDatabase), and this class takes care of opening the database if it exists, creating it if it does not, and upgrading it as necessary. Transactions are used to make sure the database is always in a sensible state.

You then use getReadableDatabase() and getWritableDatabase() methods on SQLiteOpenHelper to access your database. In the case of SQLCipher for Android's version of those methods, you pass the passphrase as a parameter.

Hence, I recommend that you:

  1. Move SQLiteDatabase.loadLibs(mContext); to your constructor.

  2. Delete the rest of openDataBase(), and all of close() (since that code already exists)

  3. Rewrite checkDataBase() to get rid of the invalid DB_PATH and use getDatabasePath() instead

  4. Move db.execSQL(DATABASE_CREATE_TABLE1); to onCreate()

  5. Delete the rest of createDataBase()

  6. Use the SQLiteOpenHelper properly in your activity

于 2012-11-22T18:06:09.767 回答
0

Why are you subclassing SQLiteOpenHelper? The purpose of this class is managaing database files, opening/closing them, creating them if necessary and managing application database objects (SQLiteDatabase).

But you're doing that on your own, while doing nothing in SQLiteOpenHelper.onCreate which means SQLiteOpenHelper does nothing. Don't subclass SQLiteOpenHelper if you are creating the database files on your own.

What is that SQLiteDatabase class? I don't see any loadLibs method in the offical one, nor openOrCreateDatabase/openDatabase overloads which accept the parameters you are passing...

于 2012-11-22T18:07:22.333 回答