Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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


    }
like image 427
Yushi Avatar asked Feb 27 '14 06:02

Yushi


3 Answers

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

like image 56
CommonsWare Avatar answered Nov 18 '22 20:11

CommonsWare


The UnsatisfiedLinkError is due to the native libraries not being included with your application. For an example on integrating SQLCipher with an existing application, please review this tutorial. Alternatively, take a look at the SQLCipher for Android test suite.

like image 31
Nick Parker Avatar answered Nov 18 '22 20:11

Nick Parker


@CommonsWare is correct and you down-voted it.

When your app is being resumed from a long sleep, the libs have been cycled out and thus restoring state is crashing because libs are absent.

Put your SQLiteDatabase.loadLibs(this); ahead of super.onCreate(savedInstanceState)

@Override
public void onCreate(Bundle savedInstanceState) {

    //you must set Context on SQLiteDatabase first
    SQLiteDatabase.loadLibs(this);

    super.onCreate(savedInstanceState);
like image 25
Dan Davis Avatar answered Nov 18 '22 22:11

Dan Davis