将 sqlite db 复制到 Android 设备失败

发布于 2024-10-27 13:11:26 字数 3086 浏览 6 评论 0原文

我有一个 sqlite 数据库,我将其复制到“asset”文件夹中。在我的程序中,我检查数据库是否已存在,如果不存在,我创建一个新数据库并复制它。 我(或多或少)使用了 http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/comment-page-2/

    public void createDataBase() throws IOException {
    boolean dbExist = checkDataBase();

    if (dbExist) {
        Log.i(DEBUG_TAG, "createDataBase -> Datenbank existiert");
        // do nothing - database already exist
    } else {
        // By calling this method and empty database will be created into
        // the default system path
        // of your application so we are gonna be able to overwrite that
        // database with our database.
        this.getReadableDatabase();
        Log.i(DEBUG_TAG, "else, db existiert nicht 1");
        try {
            copyDataBase();
            Log.i(DEBUG_TAG, "nach copydatabase");
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

/**
 * Checked ob Database bereits existiert
 * 
 * @return
 */
private boolean checkDataBase() throws SQLiteException {
    SQLiteDatabase checkDB = null;
    Boolean checkTable = false;
    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);
        Log.i(DEBUG_TAG, "checkdatabase1");

    } catch (SQLiteException e) {
        Log.e(DEBUG_TAG, "Fehler checkDataBase: ", 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 = dbContext.getAssets().open(DB_NAME);

    // 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 inputfile to the outputfile
    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();
    Log.i(DEBUG_TAG, "copydatabase");
}

在模拟器中它工作得很好美好的。

然后我尝试在我的设备(HTC Desire HD)上运行它。我收到以下消息:

03-26 17:02:05.053: INFO/Database(24458): sqlite returned: error code = 14, msg = cannot open file at line 27206 of [42537b6056]

当我第一次尝试打开数据库时,会发生这种情况。当我在模拟器中运行该程序时,我没有收到此消息。当我第二次运行该程序时,它找到数据库,打开时没有错误,但表不存在。

我已经在模拟器和设备上调试了多次程序,但找不到任何解决方案。

这可能是某种权限问题吗? (因为我也无法使用 adb 查看设备上的数据库 --> 权限被拒绝')

我对 android 很陌生,所以也许我只是错过了一些愚蠢的东西......

谢谢

I have an sqlite db which I copied to the 'asset' folder. In my prog I check if the database already exists, if not I create a new one and copy it.
I used (more or less) the code from http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/comment-page-2/

    public void createDataBase() throws IOException {
    boolean dbExist = checkDataBase();

    if (dbExist) {
        Log.i(DEBUG_TAG, "createDataBase -> Datenbank existiert");
        // do nothing - database already exist
    } else {
        // By calling this method and empty database will be created into
        // the default system path
        // of your application so we are gonna be able to overwrite that
        // database with our database.
        this.getReadableDatabase();
        Log.i(DEBUG_TAG, "else, db existiert nicht 1");
        try {
            copyDataBase();
            Log.i(DEBUG_TAG, "nach copydatabase");
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

/**
 * Checked ob Database bereits existiert
 * 
 * @return
 */
private boolean checkDataBase() throws SQLiteException {
    SQLiteDatabase checkDB = null;
    Boolean checkTable = false;
    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);
        Log.i(DEBUG_TAG, "checkdatabase1");

    } catch (SQLiteException e) {
        Log.e(DEBUG_TAG, "Fehler checkDataBase: ", 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 = dbContext.getAssets().open(DB_NAME);

    // 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 inputfile to the outputfile
    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();
    Log.i(DEBUG_TAG, "copydatabase");
}

In the Emulator it works perfectly fine.

I tried then to run it on my device (HTC Desire HD). There I get the following message:

03-26 17:02:05.053: INFO/Database(24458): sqlite returned: error code = 14, msg = cannot open file at line 27206 of [42537b6056]

This happens, when I try the first time to open the DB. When I run the Program in the emulator, I dont get this message. When I run the programm the 2nd time, it finds the database, no errors with opening, but the tables do not exist.

I've debugged the program on the emulator and the device several times, but could not find any solution.

Could this be some kind of permission problem? (Since I'm also not able to see the db on the device with adb --> permission denied')

I'm very new to android, so maybe I just missed something stupid....

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野鹿林 2024-11-03 13:11:26
  1. 不要通过字符串连接创建路径。使用适当的 File 构造函数。
  2. 您的 DB_PATH 可能无效,但由于您拒绝显示它,我们无法确定。
  3. 如果此代码来自的类是 SQLiteOpenHelper,则对 getReadableDatabase() 的调用将创建一个空数据库。
  4. “(因为我也无法使用 adb 查看设备上的数据库 --> 权限被拒绝'”——这是预期的,因为您无权在生产设备上查看该目录。
  1. Do not create paths via string concatenation. Use the appropriate File constructor.
  2. Your DB_PATH may be invalid, but since you declined to show it, we cannot say for certain.
  3. If the class that this code comes from is a SQLiteOpenHelper, your call to getReadableDatabase() will create an empty database.
  4. "(Since I'm also not able to see the db on the device with adb --> permission denied'" -- this is expected, as you do not have rights to view that directory on a production device.
后eg是否自 2024-11-03 13:11:26

我通过创建自己的目录并将文件放入目录中来使其工作

String path=mContext.getDir("Folder_name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();

。代码创建文件夹。

然后进行我们检查数据库和复制数据库的操作。

enter code here 

 public void createDataBase() throws IOException { 
 String path=mContext.getDir("Folder_Name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();
 DB_PATH=path;
 boolean mDataBaseExist = checkDataBase(); 
 if(!mDataBaseExist) 
 { 
   try  
    { 
     copyDataBase(); 
    }  
    catch (IOException mIOException)  
    { 
    Log.d("Exception",mIOException.getMessage());
    throw new Error("ErrorCopyingDataBase"); 
    } 
} 
}


private boolean checkDataBase() 
{ 
    Log.d(TAG, "In checkDataBase :::::"); 
    File dbFile = new File( DB_PATH+DATABASE_NAME); 
    Log.d("dbFile", dbFile + "   "+ dbFile.exists()); 
    return dbFile.exists(); 
} 

//Copy the database from assets 
private void copyDataBase() throws IOException 
{ 
    Log.d(TAG, "In copyDataBase :::::"); 
    InputStream mInput = mContext.getAssets().open(DB_NAME);
    String outFileName = DB_PATH  + DATABASE_NAME;

    Log.d(TAG, "In copyDataBase  outFileName:::::"+outFileName);

    OutputStream mOutput = new FileOutputStream(outFileName); 
    byte[] mBuffer = new byte[1024]; 
    int mLength; 
    while ((mLength = mInput.read(mBuffer))>0) 
    { 
        mOutput.write(mBuffer, 0, mLength); 
    } 
    mOutput.flush(); 
    mOutput.close(); 
    mInput.close(); 
} 

//Open the database, so we can query it 
public boolean openDataBase() throws SQLException 
{ 
    //DB_PATH +
    String mPath = DB_PATH+ DATABASE_NAME; 
    Log.v("mPath", mPath); 
    mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
    return mDataBase != null; 
} 

希望这对新来者有所帮助。

干杯

I make it worked by creating my own directory and placing the File inside the Directory

String path=mContext.getDir("Folder_name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();

The Code to create the folder.

Then do our operation of checking the database and copying the database.

enter code here 

 public void createDataBase() throws IOException { 
 String path=mContext.getDir("Folder_Name", Context.MODE_WORLD_WRITEABLE).getAbsolutePath();
 DB_PATH=path;
 boolean mDataBaseExist = checkDataBase(); 
 if(!mDataBaseExist) 
 { 
   try  
    { 
     copyDataBase(); 
    }  
    catch (IOException mIOException)  
    { 
    Log.d("Exception",mIOException.getMessage());
    throw new Error("ErrorCopyingDataBase"); 
    } 
} 
}


private boolean checkDataBase() 
{ 
    Log.d(TAG, "In checkDataBase :::::"); 
    File dbFile = new File( DB_PATH+DATABASE_NAME); 
    Log.d("dbFile", dbFile + "   "+ dbFile.exists()); 
    return dbFile.exists(); 
} 

//Copy the database from assets 
private void copyDataBase() throws IOException 
{ 
    Log.d(TAG, "In copyDataBase :::::"); 
    InputStream mInput = mContext.getAssets().open(DB_NAME);
    String outFileName = DB_PATH  + DATABASE_NAME;

    Log.d(TAG, "In copyDataBase  outFileName:::::"+outFileName);

    OutputStream mOutput = new FileOutputStream(outFileName); 
    byte[] mBuffer = new byte[1024]; 
    int mLength; 
    while ((mLength = mInput.read(mBuffer))>0) 
    { 
        mOutput.write(mBuffer, 0, mLength); 
    } 
    mOutput.flush(); 
    mOutput.close(); 
    mInput.close(); 
} 

//Open the database, so we can query it 
public boolean openDataBase() throws SQLException 
{ 
    //DB_PATH +
    String mPath = DB_PATH+ DATABASE_NAME; 
    Log.v("mPath", mPath); 
    mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
    return mDataBase != null; 
} 

Hope this will help the new comers.

Cheers

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文