2015-04-23 81 views
1

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

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

像现在这样,我只是在做这个设备上:

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 = “/数据/”

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()); 
    } 
} 
+0

我在帖子上添加了方法copyDataBaseFromAsset,非常感谢〜 –

回答

0
下面

是复制数据库从资产文件夹中的数据目录中的工作代码:

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方法将被调用,您应该在其中使用查询来创建表并将默认数据插入到数据库中。