English 中文(简体)
从未嵌入设备中的资产文件夹复制数据库
原标题:Copy Database from assets folder in unrooted device

我正在尝试将 DB 从资产文件夹复制到设备 。 此代码对模拟器和已植入设备有效 。 我只是想知道它是否在未植入的设备上造成任何问题, 否则它也会同样有效 。

private void StoreDatabase() {
    File DbFile = new File(
            "data/data/packagename/DBname.sqlite");
    if (DbFile.exists()) {
        System.out.println("file already exist ,No need to Create");
    } else {
        try {
            DbFile.createNewFile();
            System.out.println("File Created successfully");
            InputStream is = this.getAssets().open("DBname.sqlite");
            FileOutputStream fos = new FileOutputStream(DbFile);
            byte[] buffer = new byte[1024];
            int length = 0;
            while ((length = is.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
            System.out.println("File succesfully placed on sdcard");
            // Close the streams
            fos.flush();
            fos.close();
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
最佳回答

这将在所有设备和模拟器中肯定有效, 不需要根 。

/**
 * 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(String dbname) throws IOException {
    // Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(dbname);
    // Path to the just created empty db
    File outFileName = myContext.getDatabasePath(dbname);
    // 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();
}
问题回答
    /**
 * Copy database file from assets folder inside the apk to the system database path.
 * @param context Context
 * @param databaseName Database file name inside assets folder
 * @param overwrite True to rewrite on the database if exists
 * @return True if the database have copied successfully or if the database already exists without overwrite, false otherwise.
 */
private boolean copyDatabaseFromAssets(Context context, String databaseName , boolean overwrite)  {

    File outputFile = context.getDatabasePath(databaseName);
    if (outputFile.exists() && !overwrite) {
        return true;
    }

    outputFile = context.getDatabasePath(databaseName + ".temp");
    outputFile.getParentFile().mkdirs();

    try {
        InputStream inputStream = context.getAssets().open(databaseName);
        OutputStream outputStream = new FileOutputStream(outputFile);


        // transfer bytes from the input stream into the output stream
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, length);
        }

        // Close the streams
        outputStream.flush();
        outputStream.close();
        inputStream.close();

        outputFile.renameTo(context.getDatabasePath(databaseName));

    } catch (IOException e) {
        if (outputFile.exists()) {
            outputFile.delete();
        }
        return false;
    }

    return true;
}

我不确定,但我测试过的每一个装置都用这个。 我(从这里的某个地方)偷了这个方法, 并把它用于备份和修复:

public static void movedb(File srcdb, File destdb)
{
    try 
    {
        if (Environment.getExternalStorageDirectory().canWrite()) 
        {                 
            if (srcdb.exists()) 
            {
                FileChannel src = new FileInputStream(srcdb).getChannel();
                FileChannel dst = new FileOutputStream(destdb).getChannel();
                dst.transferFrom(src, 0, src.size());
                src.close();
                dst.close();                    
            }
            else
            {
                //ERROR: "Database file references are incorrect"                    
            }
        }
        else
        {
           //ERROR: "Cannot write to file"
        }
    }
    catch (Exception e) 
    {
        //ERROR: e.getMessage()
    }
}

然后,我刚刚支持它 通过呼吁:

movedb(this, getDatabasePath(getDbName()), new File(Environment.getExternalStorageDirectory(), getDatabaseBackupPath()));

getDatabasePath () getdatabaseBackupPath () 只是字符串值

private void copyDataBase(Context context) throws IOException {

    //Log.i(TAG, "Opening Asset...");
    // Open your local db as the input stream
    InputStream myInput = context.getAssets().open(DBHelper.DATABASE_NAME);

   // Log.i(TAG, "Getting db path...");
    // Path to the just created empty db
    File dbFile = getDatabasePath(DBHelper.DATABASE_NAME);

    if (!dbFile.exists()) {
        SQLiteDatabase checkDB = context.openOrCreateDatabase(DBHelper.DATABASE_NAME, context.MODE_PRIVATE, null);
        if (checkDB != null) {
            checkDB.close();
        }
    }

    //Log.i(TAG, "Getting output stream...");
    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(dbFile);

  //  Log.i(TAG, "Writing data...");
    // 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();
}

这是科特林的作品

assets.open("sqlite_db_in_assets.db")
      .copyTo(getDatabasePath("sqlite_db_in_device.db").outputStream())

虽然技术上可行,但我认为(向或从)潜在实时数据库文件复制是一个好主意。





相关问题
Android - ListView fling gesture triggers context menu

I m relatively new to Android development. I m developing an app with a ListView. I ve followed the info in #1338475 and have my app recognizing the fling gesture, but after the gesture is complete, ...

AsyncTask and error handling on Android

I m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What s unclear to me is how to handle ...

Android intent filter for a particular file extension?

I want to be able to download a file with a particular extension from the net, and have it passed to my application to deal with it, but I haven t been able to figure out the intent filter. The ...

Android & Web: What is the equivalent style for the web?

I am quite impressed by the workflow I follow when developing Android applications: Define a layout in an xml file and then write all the code in a code-behind style. Is there an equivalent style for ...

TiledLayer equivalent in Android [duplicate]

To draw landscapes, backgrounds with patterns etc, we used TiledLayer in J2ME. Is there an android counterpart for that. Does android provide an option to set such tiled patterns in the layout XML?

Using Repo with Msysgit

When following the Android Open Source Project instructions on installing repo for use with Git, after running the repo init command, I run into this error: /c/Users/Andrew Rabon/bin/repo: line ...

Android "single top" launch mode and onNewIntent method

I read in the Android documentation that by setting my Activity s launchMode property to singleTop OR by adding the FLAG_ACTIVITY_SINGLE_TOP flag to my Intent, that calling startActivity(intent) would ...

From Web Development to Android Development

I have pretty good skills in PHP , Mysql and Javascript for a junior developer. If I wanted to try my hand as Android Development do you think I might find it tough ? Also what new languages would I ...

热门标签