Android复制数据库目录问题?

时间:2015-04-23 02:05:24

标签: android

我有一个应用程序需要访问资产文件夹数据库来获取应用程序启动时的数据,所以我从资产操作中做了一些复制数据,但在上一个版本中,用户说无法打开应用程序,所以有些用户可以。 / p>

我可以知道,如果我需要将资源文件夹中的数据库复制到用户设备,我应该使用哪个数据库目录路径来存储复制的数据库?或者在我的代码中遗漏了一些重要的东西?

就像现在一样,我只是在设备上执行此操作:

createDirectory:

public boolean createDirectory() {  
    if(Environment.getExternalStorageState().contains(Environment.MEDIA_MOUNTED)) 
    {
        String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath()+GlobalConfig.CONFIG_DATA_DIR;
        if( isNeedDL( rootPath )) {
            File myDir = new File(rootPath);
            return myDir.mkdirs();
        }
    }

    return false;
}

和数据库目录,GlobalConfig.CONFIG_DATA_DIR =" / data /"

path = Environment.getExternalStorageDirectory().getAbsolutePath()+GlobalConfig.CONFIG_DATA_DIR;

并在SQLiteOpenHelper类中:检查数据库是否退出,执行复制操作。

private NOLDatabaseHelper(Context context, String path) {
    super(context, path + DB_NAME_OUTDBNAME, null, DB_VERSION);
    this.context = context;
}   

public void createDatabase() {

    if(!isDatabaseExited()) {
        Log.v(GlobalConfig.TAG, "NO database");
        getReadableDatabase();
        copyDataBaseFromAsset();
    } else {
        Log.v(GlobalConfig.TAG, "Has database");
    }
}

public static boolean isDatabaseExited() {
    SQLiteDatabase checkDB = null;
    try {
        checkDB = SQLiteDatabase.openDatabase( DB_PATH + DB_NAME_OUTDBNAME, null,
                SQLiteDatabase.OPEN_READONLY);
        checkDB.close();

        Log.v(GlobalConfig.TAG,"check? "+DB_PATH + DB_NAME_OUTDBNAME+" checkDB:"+checkDB);
    } catch (SQLiteException e) {}

    return checkDB != null ? true : false;
}

谢谢!

这是复制功能:

// to fix database is locked issue
private synchronized void copyDataBaseFromAsset() 
{
    int length                  = -1;
    byte[] buffer               = new byte[1024];
    AssetManager am             = context.getAssets();

    try 
    {
        InputStream assetsDB    = am.open(DB_NAME_INDBNAME);
        String outFileName      = DB_PATH + DB_NAME_OUTDBNAME;
        OutputStream dbOut      = new FileOutputStream(outFileName);

        while ((length = assetsDB.read(buffer)) > 0) {
            dbOut.write(buffer, 0, length);
        }

        dbOut.flush();
        dbOut.close();
        assetsDB.close();

    } catch(Exception e) {
        Log.e( GlobalConfig.TAG, "copyDataBaseFromAsset error, is say: "+e.toString() );
    }
}

1 个答案:

答案 0 :(得分:0)

下面是将数据库从assets文件夹复制到数据目录的工作代码:

public class DatabaseHelper extends SQLiteOpenHelper {
// varaible declaration
public static String TAG = "DatabaseHelper";
private static String DB_NAME = "DMDatabase.sqlite";//file name in assets
private SQLiteDatabase sqliteDatabase;
private final Context myContext;
private String DatabasePath;

public DatabaseHelper(Context context) {
    super(context, DB_NAME, null, 1);
    this.myContext = context;
    DatabasePath = "/data/data/" + myContext.getPackageName()
            + "/databases/";
}

/**
 * Method to create the database inside application
 * 
 * @throws IOException
 */
public void createDatabase() throws IOException {
    try {

        // check if the database exists
        boolean dbExist = checkDatabase();
        if (!dbExist) {
            // database is not present copy databse
            this.getReadableDatabase();
            try {
                copyDatabse();
            } catch (IOException e) {
                // TODO: handle exception
                // String ex = e.getMessage();
                e.printStackTrace();
            }
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

/**
 * 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 = null;
        try {
            File file = new File(DatabasePath + DB_NAME);
            if (file.exists()) {
                checkDB = SQLiteDatabase.openDatabase(DatabasePath
                        + DB_NAME, null, SQLiteDatabase.OPEN_READONLY);
            } else {
                return false;
            }
        } catch (SQLException e) {
            Log.d("DB Exception", "");
        }
        if (checkDB != null) {
            checkDB.close();
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    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 tranfering bytestream.
 * */
private void copyDatabse() throws IOException {
    try {
        // Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        // Path to the just created empty db
        String outFileName = DatabasePath + 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 * 2];
        int length;

        while ((length = myInput.read(buffer)) > 0) {
            try {
                myOutput.write(buffer, 0, length);
            } catch (Exception e) {
            }
        }
        myOutput.flush();
        myOutput.close();
        myInput.close();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}



@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub
    createDatabase();
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub

}

/**
 * Other Methods to insert,delete, update,select in Database
 */

}

我希望对你有所帮助。

  

但不建议从数据目录中的资产中复制数据库。创建数据库后,将调用onCreate方法,您应该使用查询来创建表并将默认数据插入数据库。