4

「asset」フォルダーにコピーした sqlite db があります。私のプログラムでは、データベースが既に存在するかどうかを確認し、存在しない場合は新しいデータベースを作成してコピーします。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]

これは、初めて DB を開こうとしたときに発生します。エミュレータでプログラムを実行すると、このメッセージが表示されません。プログラムを 2 回目に実行すると、データベースが検出され、開くときにエラーは発生しませんが、テーブルは存在しません。

エミュレータとデバイスでプログラムを数回デバッグしましたが、解決策が見つかりませんでした。

これはある種の許可の問題でしょうか?(私もデバイス上のdbを見ることができないので、adb -->権限が拒否されました')

私はAndroidに非常に慣れていないので、愚かなことを見逃しただけかもしれません....

ありがとう

4

2 に答える 2

0

自分のディレクトリを作成し、ディレクトリ内にファイルを配置することで、それを機能させます

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; 
} 

これが新参者の助けになることを願っています。

乾杯

于 2012-09-06T11:04:00.777 に答える
0
  1. 文字列を連結してパスを作成しないでください。適切なFileコンストラクターを使用します。
  2. あなたDB_PATHは無効である可能性がありますが、表示することを拒否したため、確実なことは言えません.
  3. このコードの元のクラスが の場合、SQLiteOpenHelperを呼び出すとgetReadableDatabase()、空のデータベースが作成されます。
  4. 「(私はまた、adb を使用してデバイス上のデータベースを表示できないため --> 許可が拒否されました'」 -- 実稼働デバイスでそのディレクトリを表示する権限がないため、これは予期されたものです。
于 2011-03-26T18:16:38.027 に答える