安装在android中的应用程序后如何复制现有数据库

时间:2014-02-19 11:18:22

标签: android sqlite

我在资源文件夹中有数据库我想在安装过程中将其复制到数据库文件夹中, 有没有办法做到这一点?

或者,如果没有办法做到这一点,那么当应用程序启动后应用程序处理数据库时,是否有办法制作进度条?

编辑:

我的数据库有问题 logcat“显示无法在30176行打开文件” 我试过这个

    if(android.os.Build.VERSION.SDK_INT >= 4.2){
        DB_PATH = context.getApplicationInfo().dataDir + "/databases/";         
    } else {
        DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    }

但它不起作用:(

2 个答案:

答案 0 :(得分:1)

这是我的DataBaseHelper.java

public class DataBaseHelper extends SQLiteOpenHelper {

private static String DB_PATH="data/data/yourPackageName/databases/";
private static final String DB_NAME="yourDbName.db";
private SQLiteDatabase myDatabase;
private final Context myContext;

public DataBaseHelper(Context context) {
    super(context, DB_NAME, null, 1);
    // TODO Auto-generated constructor stub
    this.myContext = context; 
}

public void createDataBase() throws IOException{

    boolean dbExist = checkDataBase();

    SQLiteDatabase db_read = null;

    if(dbExist){
        //Do nothing

    }else{

        db_read = this.getReadableDatabase();
        db_read.close();

        try {
            copyDataBase();
        } catch (Exception e) {
            // TODO: handle exception
            throw new Error("Error copying database (createDataBase)");
        }
    }

}

public boolean checkDataBase() {
    File dbFile = new File(DB_PATH+DB_NAME);
    return dbFile.exists();

}

public void copyDataBase() throws IOException{

    //Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(DB_NAME);
    // Path to the just created empty db. Destination folder (where we created the DB empty)
    String outFileName = DB_PATH+DB_NAME;
    //Open the empty db as the output stream. //We opened it BBDD empty as OutputStream
    OutputStream myOutPut = new FileOutputStream(outFileName);

    Log.e("LocAndroid", "ESTOY EN copyDataBase");


    //transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int lenght;


    while((lenght = myInput.read(buffer))!=-1){
        if(lenght > 0){

            myOutPut.write(buffer, 0, lenght);


        }

    }
    //Close the streams
    myOutPut.flush();
    myOutPut.close();
    myInput.close();

}

public void openDataBase() throws SQLException{


    //Open the database
    String myPath = DB_PATH+DB_NAME;
    myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}


public synchronized void close(){

    if(myDatabase != null){
        myDatabase.close();
    }
    super.close();
}

LoadDbASync.java

public class LoadDbAsync extends AsyncTask <Void, Void, Boolean>{

    Context context;
    boolean loadedDb = false;
    //private Activity mActivity;

    //constructor
     public LoadDbAsync(Context context) {
            //mActivity = activity;
         this.context = context;
        }

    private DataBaseHelper myDbHelper;
    private ProgressDialog pDialog; 

    //Se ejecutará antes del código principal de nuestra tarea. 
    //Se suele utilizar para preparar la ejecución de la tarea, inicializar la interfaz, etc
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        Log.i("LocAndroid", "Entra en PreExecute");

        pDialog = new ProgressDialog(context);
        pDialog.setMessage("Cargando Base de datos...");
        pDialog.setCancelable(false);//erabiltzaileak atzera botoia sakatuz ez kantzelatzeko
        pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//barrarewn estiloa. Espiral bat izango da

    }

    //Se ejecutará cada vez que llamemos al método publishProgress() desde el método doInBackground().
    //se usa para poder realizar cambios en la interface. En doInBackground no se pueden realizar cambios en la interface
    @Override
    protected void onProgressUpdate(Void... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);

        Log.i("LocAndroid", "Entra en onProgressUpdate");

        pDialog.show();
    }


    @Override
    protected Boolean doInBackground(Void... params) {
        // TODO Auto-generated method stub
        Log.i("LocAndroid", "Entra en doInBackground");

        myDbHelper = new DataBaseHelper(context);
        boolean dbExist = myDbHelper.checkDataBase();

        if(dbExist){
            loadedDb = true;


        }else{

            publishProgress(null);
        }



        try {
            myDbHelper.createDataBase();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            throw new Error ("No se puede crear. Boton Crear. try. doInBAckground");
        }
        myDbHelper.close();


        return null;
    }


    @Override
    protected void onPostExecute(Boolean result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        Log.i("LocAndroid", "Entra en onPostExecute");

        if(!loadedDb){
        pDialog.dismiss();
        Log.i("LocAndroid", "Se termino de cargar la BD");
        Toast.makeText(context, "Base de datos cargada", Toast.LENGTH_SHORT).show();
        }else{
            Log.i("LocAndroid", "La BD ya estaba cargada");

        }
            try {
                    finalize();
                } catch (Throwable e) {
                    // TODO Auto-generated catch block
                            e.printStackTrace();
                }
    }

}

然后,在onCreate的MainActivity.java中:

LoadDbAsync task = new LoadDbAsync(this);
task.execute();

答案 1 :(得分:0)

  

这不是我的代码工作正常,但我想在应用程序启动之前应对数据库

那是不可能的。在第一次启动应用程序之前,您的所有代码都没有运行。

  

或者,如果没有办法做到这一点,那么当应用程序启动后应用程序处理数据库时,是否有办法制作进度条?

查看ProgressDialogAsyncTask

  • ProgressDialog AsyncTask
  • 中设置onPreExecute()
  • 复制doInBackground()中的数据库,可能会使用publishProgress()onProgressUpdate()
  • 更新进度
  • 取消ProgressDialog
  • 中的onPostExecute()