1

我在我的 android 应用程序中遇到了一个奇怪的行为。当我开始应用程序并创建表并将信息输入数据库时​​,数据库正在工作。

但是当我从应用程序中注销并再次登录时,我收到了错误。

07-04 02:54:03.427 5171-5877/? E/Database: CREATE TABLE android_metadata failed
07-04 02:54:03.427 5171-5877/? E/Database: Failed to setLocale() when constructing, closing the database
                                           net.sqlcipher.database.SQLiteException: file is encrypted or is not a database
                                               at net.sqlcipher.database.SQLiteDatabase.native_setLocale(Native Method)
                                               at net.sqlcipher.database.SQLiteDatabase.setLocale(SQLiteDatabase.java:2474)
                                               at net.sqlcipher.database.SQLiteDatabase.openDatabaseInternal(SQLiteDatabase.java:2338)
                                               at net.sqlcipher.database.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1087)
                                               at net.sqlcipher.database.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1150)
                                               at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:162)
                                               at net.sqlcipher.database.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:129)
                                               at com.package.helper.MyOpenHelper.getWritableDatabase(MyOpenHelper.java:58)
                                               at com.package.provider.MyContentProvider.query(MyContentProvider.java:31)
                                               at android.content.ContentProvider.query(ContentProvider.java:857)
                                               at android.content.ContentProvider$Transport.query(ContentProvider.java:200)
                                               at android.content.ContentResolver.query(ContentResolver.java:461)
                                               at android.support.v4.content.ContentResolverCompatJellybean.query(ContentResolverCompatJellybean.java:29)
                                               at android.support.v4.content.ContentResolverCompat$ContentResolverCompatImplJB.query(ContentResolverCompat.java:57)
                                               at android.support.v4.content.ContentResolverCompat.query(ContentResolverCompat.java:125)
                                               at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:59)
                                               at android.support.v4.content.CursorLoader.loadInBackground(CursorLoader.java:37)
                                               at android.support.v4.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:296)
                                               at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:54)
                                               at android.support.v4.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:42)
                                               at android.support.v4.content.ModernAsyncTask$2.call(ModernAsyncTask.java:128)
                                               at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                               at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                                               at java.lang.Thread.run(Thread.java:841)

MyOpenHelper.java

@ContextSingleton
public class MyOpenHelper extends SQLiteOpenHelper {

    Context context;
    private static final String PWD = "databse password";

    @Inject
    public MyOpenHelper(Context context) {
        super(context, Constants.DB_NAME, null, 25);
        this.context = context;
        SQLiteDatabase.loadLibs(context);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }



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

    }

    public SQLiteDatabase getWritableDatabase() {
        return getWritableDatabase(PWD);
    }

    public SQLiteDatabase getReadableDatabase() {
        return getReadableDatabase(PWD);
    }

MyContentProvider.java

import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
import com.google.inject.Inject;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteQueryBuilder;
import roboguice.content.RoboContentProvider;

public class MyContentProvider extends RoboContentProvider {

    @Inject
    MyOpenHelper openHelper;

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        try {
            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
            qb.setTables(parsePath(uri));
            SQLiteDatabase db = openHelper.getWritableDatabase();
            Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);

            // Tell the cursor what uri to watch, so it knows when its source data changes
            c.setNotificationUri(getContext().getContentResolver(), uri);
            return c;
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return null;
    }

    @Override
    public String getType(Uri uri) {
        return "";
    }

    @Override
    public Uri insert(Uri uri, ContentValues initialValues) {
        SQLiteDatabase db = openHelper.getWritableDatabase();
        long rowId = db.insert(parsePath(uri), null, initialValues);
        if (rowId > 0) {
            Uri noteUri = ContentUris.withAppendedId(uri, rowId);
            getContext().getContentResolver().notifyChange(noteUri, null);
            return noteUri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = openHelper.getWritableDatabase();
        int i = db.delete(parsePath(uri), where, whereArgs);
        getContext().getContentResolver().notifyChange(uri, null);
        return i;
    }

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
        SQLiteDatabase db = openHelper.getWritableDatabase();
        int count = db.update(parsePath(uri), values, where, whereArgs);
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    public String parsePath(Uri uri) {
        String path = uri.getPath();
        return parsePath(path);
    }

    public String parsePath(String path) {
        //TODO implement method correctly using RegExp
        //When update gnerates must return following string /table_name/id
        int index = path.indexOf("/");
        if (index < 0) {
            return path;
        } else {
            index = path.lastIndexOf("/");
            if (index > 0) {
                String str = path.substring(index + 1, path.length());
                try {
                    Integer.valueOf(str);
                    return parsePath(path.substring(0, index));
                } catch (NumberFormatException e) {
                    return str;
                }
            } else {
                return path.replace("/", "");
            }
        }
    }

}

由于我不知道为什么会发生此错误,因此仍然无法解决问题。有人可以提出建议。

仅供参考:这是一个使用 Salesforce Android Mobile SDK 的 Salesforce 应用程序。并将 2 个 ContentProviders 用于 salesforce SmartStore SyncAdapter。但我认为这对这个问题没有影响

4

0 回答 0