Android - sqlcipher抛出没有这样的表异常

时间:2016-09-28 18:52:00

标签: android database sqlite encryption sqlcipher

当我从加密数据库中选择数据时,我被困在没有这样的表错误的中间。我在DB Browser中准备了加密数据库。在Android Studio中,我将此数据库放在assets / databases文件夹中。然后我将数据库从资产/数据库复制到设备。为此我使用复制并连接到数据库的类,这里是这个类:

import android.content.Context;
import android.content.res.AssetManager;
import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteException;
import net.sqlcipher.database.SQLiteOpenHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Repository extends SQLiteOpenHelper {
    private static final int VERSION = 1;
    private static final String DATABASE_NAME = "mydb.db";
    private static File DATABASE_FILE;

    // This is an indicator if we need to copy the
    // database file.
    private boolean mInvalidDatabaseFile = false;
    private boolean mIsUpgraded = false;
    private Context mContext;

    /**
     * number of users of the database connection.
     * */
    private int mOpenConnections = 0;

    private static Repository mInstance;

    synchronized static public Repository getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new Repository(context.getApplicationContext());
        }
        return mInstance;
    }

    private Repository(Context context) {
        super(context, DATABASE_NAME, null, VERSION);
        this.mContext = context;

        SQLiteDatabase db = null;
        try {

            db = getReadableDatabase("123456");
            if (db != null) {
                db.close();
            }

            DATABASE_FILE = context.getDatabasePath(DATABASE_NAME);

            if (mInvalidDatabaseFile) {
                copyDatabase();
            }
            if (mIsUpgraded) {
                doUpgrade();
            }
        } catch (SQLiteException e) {
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        mInvalidDatabaseFile = true;
    }

    @Override
    public void onUpgrade(SQLiteDatabase database,
                          int old_version, int new_version) {
        mInvalidDatabaseFile = true;
        mIsUpgraded = true;
    }

    /**
     * called if a database upgrade is needed
     */
    private void doUpgrade() {
        // implement the database upgrade here.
    }

    @Override
    public synchronized void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        // increment the number of users of the database connection.
        mOpenConnections++;
        if (!db.isReadOnly()) {
            // Enable foreign key constraints
            db.execSQL("PRAGMA foreign_keys=ON;");
        }
    }

    /**
     * implementation to avoid closing the database connection while it is in
     * use by others.
     */
    @Override
    public synchronized void close() {
        mOpenConnections--;
        if (mOpenConnections == 0) {
            super.close();
        }
    }

    private void copyDatabase() {
        AssetManager assetManager = mContext.getResources().getAssets();
        InputStream in = null;
        OutputStream out = null;
        try {
            in = assetManager.open(DATABASE_NAME);
            out = new FileOutputStream(DATABASE_FILE);
            byte[] buffer = new byte[1024];
            int read = 0;
            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
        } catch (IOException e) {
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {}
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {}
            }
        }
        setDatabaseVersion();
        mInvalidDatabaseFile = false;
    }

    private void setDatabaseVersion() {
        SQLiteDatabase db = null;
        try {
            db = SQLiteDatabase.openDatabase(DATABASE_FILE.getAbsolutePath(), "123456", null,
                    SQLiteDatabase.OPEN_READWRITE);
            db.execSQL("PRAGMA user_version = " + VERSION);
        } catch (SQLiteException e ) {
        } finally {
            if (db != null && db.isOpen()) {
                db.close();
            }
        }
    }
}

这是我的MainActivity类:

import android.content.ContentValues;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import net.sqlcipher.Cursor;
import net.sqlcipher.database.SQLiteDatabase;

import java.io.File;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SQLiteDatabase.loadLibs(this);
        Repository repo = Repository.getInstance( this );
        SQLiteDatabase db = repo.getWritableDatabase("123456");

        String result;
        Cursor cursor = null;

        try {
            cursor = db.rawQuery("SELECT * FROM stations", null);
            while (cursor.moveToNext()) {

                int index1 = cursor.getColumnIndex("station");
                result = cursor.getString(index1);


                Log.d(MainActivity.class.getSimpleName(), "Station: " + result);
            }


        } finally {
            if(cursor != null)
                cursor.close();
        }


    }

当它选择数据的时候,它会给我带来这个错误:

Caused by: net.sqlcipher.database.SQLiteException: no such table: stations: , while compiling: SELECT * FROM stations

我不知道,我做错了什么?如果使用没有加密的标准SQLite数据库都可以正常工作。

0 个答案:

没有答案