首页 > 解决方案 > 平板电脑的 SQLITE 数据库复制失败

问题描述

我正面临一个奇怪的情况。

我正在使用以下代码从 assets 文件夹创建一个 sqlite db。对于任何手机,它都可以正常工作。但对于平板电脑,复制失败了。例如:示例 db 为 526kb,但为平板电脑创建的只有 12kb。我可以在模拟器中手动上传文件。但我真的需要代码适用于平板电脑,而不需要对真正的平板电脑进行任何手动干预。

public class DatabaseHelper extends SQLiteOpenHelper {

    private static String DB_PATH = "C:/temp/";
    private static String DB_NAME = "sample.db";
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
        if (android.os.Build.VERSION.SDK_INT >= 4.2) {
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        } else {
            DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        }
    }

    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {          
        } else {
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {               
                throw new RuntimeException(e);
            }
        }
    }

    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            String myPath = DB_PATH+DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
        }
        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    /**
    * Copies your database from your local assets-folder to the just created    empty database in the
    * system folder, from where it can be accessed and handled.
    * This is done by transfering bytestream.
    * */
    private void copyDataBase() throws IOException {
        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        //System.exit(0);

        // Path to the just created empty db
        String outFileName =  DB_PATH+DB_NAME;

        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0) {
            myOutput.write(buffer, 0, length);
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    public void openDataBase() throws SQLException {
        String myPath =  DB_PATH+DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);      
    }

}

标签: android

解决方案


我遇到了同样的问题,直到我发现一个晦涩的线程说某些类型的对象在添加到资产文件夹时会被压缩。如果您将数据库命名为 .db 或 .sql,它将被压缩。您需要将其命名为 .jpg 并且它不会被压缩。然后,当您在运行时将数据库从资产复制到应用程序的数据文件夹时,您可以随意命名:

private String DB_PATH = "";
private static String DB_IN = "mydatabase.jpg";
private static String DB_NAME = "mydatabase.db";

private void copyDataBase() throws IOException{

    DB_PATH = myContext.getFilesDir().getParentFile().getPath() + "/databases/";

    //Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(DB_IN);

    // Path to the just created empty db
    String outFileName = DB_PATH + DB_NAME;

    //Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    //transfer bytes from the input file to the output file
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    //Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();

}

推荐阅读