I'm using SQLCIPHER to read or write database getting error

android, database, sqlcipher, sqlite

Solution

That error usually occurs if you have not called `SQLiteDatabase.loadLibs()` before attempting to use the database.

Problem

Hiee, i'm using sqlcipher to read the database but before reading the data it is giving the following error.Below is my logcat please have a look. ``` E/AndroidRuntime(21826): FATAL EXCEPTION: main 02-27 11:33:10.608: E/AndroidRuntime(21826): java.lang.UnsatisfiedLinkError: Native method not found: net.sqlcipher.database.SQLiteDatabase.dbopen:(Ljava/lang/String;I)V 02-27 11:33:10.608: E/AndroidRuntime(21826): at net.sqlcipher.database.SQLiteDatabase.dbopen(Native Method) 02-27 11:33:10.608: E/AndroidRuntime(21826): at net.sqlcipher.database.SQLiteDatabase. <init>(SQLiteDatabase.java:1942) 02-27 11:33:10.608: E/AndroidRuntime(21826): at net.sqlcipher.database.SQLiteDatabase.<init>(SQLiteDatabase.java:1920) 02-27 11:33:10.608: E/AndroidRuntime(21826): at example.SQLDemoActivity.onCreate(SQLDemoActivity.java:19) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.Activity.performCreate(Activity.java:5020) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2211) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.access$600(ActivityThread.java:149) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1300) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.os.Handler.dispatchMessage(Handler.java:99) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.os.Looper.loop(Looper.java:153) 02-27 11:33:10.608: E/AndroidRuntime(21826): at android.app.ActivityThread.main(ActivityThread.java:4987) 02-27 11:33:10.608: E/AndroidRuntime(21826): at java.lang.reflect.Method.invokeNative(Native Method) 02-27 11:33:10.608: E/AndroidRuntime(21826): at java.lang.reflect.Method.invoke(Method.java:511) 02-27 11:33:10.608: E/AndroidRuntime(21826): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:821) 02-27 11:33:10.608: E/AndroidRuntime(21826): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584) 02-27 11:33:10.608: E/AndroidRuntime(21826): at dalvik.system.NativeStart.main(Native Method) ``` Below is the link from where i have got this sqlcipher class which i'm trying to run sqlcipher link This is the class where i'm calling SQLiteDatabase.loadLibs(this), please have a look ``` public class SQLDemoActivity extends Activity { EventDataSQLHelper eventsData; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //you must set Context on SQLiteDatabase first SQLiteDatabase.loadLibs(this); String password = "foo123"; eventsData = new EventDataSQLHelper(this); //then you can open the database using a password SQLiteDatabase db = eventsData.getWritableDatabase(password); for (int i = 1; i < 100; i++) addEvent("Hello Android Event: " + i, db); db.close(); db = eventsData.getReadableDatabase(password); Cursor cursor = getEvents(db); showEvents(cursor); db.close(); } @Override public void onDestroy() { eventsData.close(); } private void addEvent(String title, SQLiteDatabase db) { ContentValues values = new ContentValues(); values.put(EventDataSQLHelper.TIME, System.currentTimeMillis()); values.put(EventDataSQLHelper.TITLE, title); db.insert(EventDataSQLHelper.TABLE, null, values); } private Cursor getEvents(SQLiteDatabase db) { Cursor cursor = db.query(EventDataSQLHelper.TABLE, null, null, null, null, null, null); startManagingCursor(cursor); return cursor; } private void showEvents(Cursor cursor) { StringBuilder ret = new StringBuilder("Saved Events:\n\n"); while (cursor.moveToNext()) { long id = cursor.getLong(0); long time = cursor.getLong(1); String title = cursor.getString(2); ret.append(id + ": " + time + ": " + title + "\n"); } Log.i("sqldemo",ret.toString()); } } ``` And below is the method body ``` public class SQLiteDatabase extends SQLiteClosable { private static final String TAG = "Database"; private static final int EVENT_DB_OPERATION = 52000; private static final int EVENT_DB_CORRUPT = 75004; public int status(int operation, boolean reset){ return native_status(operation, reset); } private static void loadICUData(Context context, File workingDir) { try { File icuDir = new File(workingDir, "icu"); if(!icuDir.exists()) icuDir.mkdirs(); File icuDataFile = new File(icuDir, "icudt46l.dat"); if(!icuDataFile.exists()) { ZipInputStream in = new ZipInputStream(context.getAssets().open("icudt46l.zip")); in.getNextEntry(); OutputStream out = new FileOutputStream(icuDataFile); byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.flush(); out.close(); } } catch (Exception e) { Log.e(TAG, "Error copying icu data file", e); } } public static void loadLibs (Context context) { loadLibs(context, context.getFilesDir()); } public static void loadLibs (Context context, File workingDir) { System.loadLibrary("stlport_shared"); System.loadLibrary("sqlcipher_android"); System.loadLibrary("database_sqlcipher"); boolean systemICUFileExists = new File("/system/usr/icu/icudt46l.dat").exists(); String icuRootPath = systemICUFileExists ? "/system/usr" : workingDir.getAbsolutePath(); setICURoot(icuRootPath); if(!systemICUFileExists) { loadICUData(context, workingDir); } } } ```

Original source