android - 部分手机复制数据库失败

标签 android sqlite

我使用下面的代码将sqlite数据库asset文件夹复制到/data/data/{package_name}/databases/并且它在我测试过的大多数手机(HTC、三星、索尼、华为)上运行良好,但在某些手机(如 LG G2)上不起作用

public void createDatabase() throws IOException {
    boolean dbExist = checkDatabase();
    try {
        if (dbExist)
            deleteDatabase();

        this.getReadableDatabase();
        copyDatabase();
    } catch (IOException e) {
        Log.v("db", e.toString());
        throw new Error(e.getMessage());
    }
}

我还尝试了下面的代码,而不是使用 this.getReadableDatabase();

private void createDirectory() {
    File dbDirectory = new File(DB_PATH);
    if (!dbDirectory.exists())
        dbDirectory.mkdirs();
}

结果还是一样,请问问题出在哪里?我该如何解决这个问题?

编辑 完整代码:

public class SQLiteDBHelper extends SQLiteOpenHelper
{
private final Context myContext;

public SQLiteDBHelper(Context context) {
    super(context, G.DB_NAME, null, 1);
    this.myContext = context;
}

/**
 * Creates a empty database on the system and overwrite it with your own
 * database.
 **/
public void createDatabase() throws IOException {
    boolean dbExist = checkDatabase();
    if (dbExist) {
        try {
            deleteDatabase();
        } catch (IOException e) {
            Log.v("db", e.toString());
            throw new Error("Error copying database");
        }
    }
    // if (!dbExist) {
    try {
    super.getReadableDatabase();

        copyDatabase();
    } catch (IOException e) {
        Log.v("db", e.toString());
        throw new Error("Error copying database");
    }
    // }
}

/**
 * Check if the database already exist to avoid re-copying the file each
 * time you open the application.
 * 
 * @return true if it exists, false if it doesn't
 */
private boolean checkDatabase() {
    SQLiteDatabase checkDB = null;

    try {
        checkDB = SQLiteDatabase.openDatabase(G.DB_FULL_PATH, null,
                SQLiteDatabase.OPEN_READONLY
                        | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
    } catch (SQLiteException e) {
        // database does't exist yet.
    }

    if (checkDB != null) {
        checkDB.close();
    }
    return checkDB != null ? true : false;
}

private void copyDatabase() throws IOException {
    String[] dbFiles = myContext.getAssets().list(G.ASSETS_DB_FOLDER);
    String outFileName = G.DB_FULL_PATH;
    Log.v("db", dbFiles[0]);
    Log.v("db", outFileName);
    InputStream in = myContext.getAssets().open(
            G.ASSETS_DB_FOLDER + "/" + dbFiles[0]);
    OutputStream out = new FileOutputStream(outFileName);

    // Transfer bytes from in to out
    byte[] buf = new byte[1024];
    int len;
    while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    in.close();
    out.close();

    /*
     * OutputStream myOutput = new FileOutputStream(outFileName); //for(int
     * i =0; i < dbFiles.length; i++) { InputStream myInput =
     * myContext.getAssets().open(G.ASSETS_DB_FOLDER+"/"+dbFiles[0]); byte[]
     * buffer = new byte[1024]; int length; while ((length =
     * myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); }
     * myInput.close(); //} myOutput.flush(); myOutput.close();
     */
}

public void deleteDatabase() throws IOException {
    if (checkDatabase())
        G.context.deleteDatabase(G.DB_FULL_PATH);
}

public void openDatabase() throws SQLException {
    // Open the database
    G.database = SQLiteDatabase.openDatabase(G.DB_FULL_PATH, null,
            SQLiteDatabase.OPEN_READONLY
                    | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
}

@Override
public synchronized void close() {
    if (G.database != null)
        G.database.close();
    super.close();
}

@Override
public void onCreate(SQLiteDatabase db) {
}

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

@Override
public synchronized SQLiteDatabase getReadableDatabase() {
    try {
        createDatabase();
        openDatabase();
    } catch (SQLException e) {
        G.database = null;
        e.printStackTrace();
    } catch (IOException e) {
        G.database = null;
        e.printStackTrace();
    }
    return G.database;
}
}

它在 this.getReadableDatabase() 上给了我一个 IOException 我认为问题与 sdcard 有关

最佳答案

我认为问题在于用于定位数据库的数据库文件的路径:

DB_PATH = Environment.getExternalStorageDirectory()+ context.getApplicationContext().getPackageName() +File.separatorChar+ "databases" + File.separatorChar + "/test.db";

并获得

/data/data/pkgname/databases/dbname

使用以下内容

ContextWrapper c = new ContextWrapper(this);
String DBPath = c.getDatabasePath(DB_NAME).getPath();

希望这对您有所帮助。

关于android - 部分手机复制数据库失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26129323/

相关文章:

java - 我不能在我的 android 应用程序中将对象保存到 sqlite 中吗

android - 如何让我的按钮在 Fragments,ViewPager 中执行某些操作

java - 带 fragment 的 ListView Volley

android - 无需 root 即可永久增加 Android 中的文件描述符 ulimit

python - 查找具有特定子行组合的父级 - SQLite 与 Python

ios - 如何在 swift 中使用 BLOB 将字节数组 [UInt8] 存储和检索到 sqlite3 数据库中?

android - 如何在Android系统应用程序中升级 native 库

Android Camera2 预览和捕获 4 :3 aspect ratio but width > height

Android Sqlite 没有这样的表报错

iphone - FMDB 查询不能正确使用 LIKE