复制现有数据库sqlite并在设备 - android上运行

时间:2013-08-28 03:05:25

标签: android sqlite

我想检查数据库是否存在。如果不存在,我将文件复制到特定路径。这里的代码如下:

Main.java

   UserDbAdapter objChatMessageDbAdapter = new UserDbAdapter();
   objChatMessageDbAdapter.context = context;
   User objChatMessage = objChatMessageDbAdapter.getUser();

   if(objChatMessage.getID()<1){

        //call register intent
   }else{
        // call the first intent
   }

UserDbAdapter.java

    private SQLiteDatabase db;
    private static String TABLE_USER = "User";
    private boolean isDbClosed =true;
    public Context context;
    String TAG = "UserDbAdapter";

    public UserDbAdapter() { }

    public void init(Context context) {

      if(isDbClosed){
        DatabaseAdapter dbAdapter = DatabaseAdapter.getInstance(context);
        isDbClosed =false;
        db = dbAdapter.getWritableDatabase();
      }     

      this.context = context;
    }

    private void processConnection()
    {
      Log.i(TAG, "isDbClosed==="+isDbClosed);
      if(isDbClosed){
        DatabaseAdapter dbAdapter = new DatabaseAdapter(context);
        dbAdapter = DatabaseAdapter.getInstance(context);
        isDbClosed =false;
        db = dbAdapter.getWritableDatabase();
        Log.i(TAG, "processConnection db===="+db.toString());
       }     
   }

   public boolean isDatabaseClosed(){
     return isDbClosed;
   }

   public User getUser()
   {

            processConnection();
            User objChatMessageEntity = new User();
            String selectQuery = "Select UserId, Name, Password FROM "+TABLE_USER;  
            Cursor cursor = db.rawQuery(selectQuery, null);
            // looping through all rows and adding to list 
            if (cursor.moveToFirst()) {                              
            objChatMessageEntity = fieldMappingForGetRecord(cursor);

             }
             cursor.close();
             db.close();
             isDbClosed =true;
             return objChatMessageEntity;
   }
}

DatabaseAdapter.java

private static String dbPath;
private static String dbName = "ownexpensesdb"; 
private SQLiteDatabase applicationDatabase;  
public final Context applicationContext;
private static DatabaseAdapter mInstance = null;
private static final int DATABASE_VERSION = 1;


public static DatabaseAdapter getInstance(Context ctx) { 

    if (mInstance == null) { 
        dbPath = "/data/data/" + ctx.getPackageName() + "/databases/";
        mInstance = new DatabaseAdapter(ctx.getApplicationContext()); 
    } 
    return mInstance; 
}

public DatabaseAdapter(Context context) {    
    super(context,  dbName , null, DATABASE_VERSION);
    this.applicationContext  = context;

    boolean  dbExist = checkDataBase();
    //SQLiteDatabase db_Read = null;
    if (dbExist){
       Log.w("Database","file found ");
       openDataBase();
    }
    else
    {
        Log.w("Database","file not found ");
        this.getReadableDatabase(); 
        try 
        {
            copyDatabase();
        } 
        catch (IOException e) 
        {
            Log.e("Error",""+e.getMessage());
            e.printStackTrace();
        } 
   }
}


private boolean checkDataBase(){  
   File dbFile = new File( dbPath +  dbName);  
   return dbFile.exists();
}

private void copyDatabase() throws IOException
{  
    InputStream input =  applicationContext.getAssets().open(dbName);
     String outPutFileName=  dbPath  +  dbName ;
     OutputStream output = new FileOutputStream( outPutFileName); 
    byte[] buffer = new byte[1024];
    int length;
    while ((length = input.read(buffer))>0){
     output.write(buffer, 0, length);
    }
    output.flush();
    output.close();
    input.close();
}


   public void openDataBase() throws SQLException
   {
        String fullDbPath= dbPath + dbName;
        Log.w("Database","open DB");
        try
        {
            applicationDatabase = SQLiteDatabase.openDatabase( fullDbPath, null,SQLiteDatabase.OPEN_READONLY);
        }
        catch (Exception e) {
            Log.e("error",e.toString());
        }
   }

  @Override
    public synchronized void close() {
         if( applicationDatabase != null)
           applicationDatabase .close();
               super.close();
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
  }

  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
  }

当我运行代码时,我收到如下错误,应用程序崩溃: 08-28 11:01:10.785:W / Database(9975):找不到文件 08-28 11:01:10.875:E /错误(9975):/ nullownexpensesdb:打开失败:EROFS(只读文件系统) 08-28 11:01:10.875:W / System.err(9975):java.io.FileNotFoundException:/ nullownexpensesdb:open failed:EROFS(只读文件系统) 08-28 11:01:10.875:W / System.err(9975):at libcore.io.IoBridge.open(IoBridge.java:416) 08-28 11:01:10.880:W / System.err(9975):at java.io.FileOutputStream。(FileOutputStream.java:88) 08-28 11:01:10.880:W / System.err(9975):at java.io.FileOutputStream。(FileOutputStream.java:128) 08-28 11:01:10.880:W / System.err(9975):at java.io.FileOutputStream。(FileOutputStream.java:117) 08-28 11:01:10.880:W / System.err(9975):at com.canmmy.expensesmanager.data.DatabaseAdapter.copyDatabase(DatabaseAdapter.java:70) 08-28 11:01:10.880:W / System.err(9975):at com.canmmy.expensesmanager.data.DatabaseAdapter。(DatabaseAdapter.java:50) 08-28 11:01:10.880:W / System.err(9975):at com.canmmy.expensesmanager.data.UserDbAdapter.processConnection(UserDbAdapter.java:35) 08-28 11:01:10.880:W / System.err(9975):at com.canmmy.expensesmanager.data.UserDbAdapter.getUser(UserDbAdapter.java:77) 08-28 11:01:10.880:W / System.err(9975):at com.canmmy.expensesmanager.SplashActivity.initMain(SplashActivity.java:34) 08-28 11:01:10.880:W / System.err(9975):at com.canmmy.expensesmanager.SplashActivity.access $ 0(SplashActivity.java:32) 08-28 11:01:10.880:W / System.err(9975):at com.canmmy.expensesmanager.SplashActivity $ 1.run(SplashActivity.java:27) 08-28 11:01:10.880:W / System.err(9975):在android.os.Handler.handleCallback(Handler.java:615) 08-28 11:01:10.880:W / System.err(9975):在android.os.Handler.dispatchMessage(Handler.java:92) 08-28 11:01:10.880:W / System.err(9975):在android.os.Looper.loop(Looper.java:137) 08-28 11:01:10.880:W / System.err(9975):在android.app.ActivityThread.main(ActivityThread.java:4898) 08-28 11:01:10.880:W / System.err(9975):at java.lang.reflect.Method.invokeNative(Native Method) 08-28 11:01:10.880:W / System.err(9975):at java.lang.reflect.Method.invoke(Method.java:511) 08-28 11:01:10.880:W / System.err(9975):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1008) 08-28 11:01:10.880:W / System.err(9975):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775) 08-28 11:01:10.880:W / System.err(9975):at dalvik.system.NativeStart.main(Native Method) 08-28 11:01:10.880:W / System.err(9975):引起:libcore.io.ErrnoException:open failed:EROFS(只读文件系统) 08-28 11:01:10.885:W / System.err(9975):at libcore.io.Posix.open(Native Method) 08-28 11:01:10.885:W / System.err(9975):at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) 08-28 11:01:10.885:W / System.err(9975):at libcore.io.IoBridge.open(IoBridge.java:400) 08-28 11:01:10.885:W / System.err(9975):......还有19个 08-28 11:01:10.885:W / Database(9975):找到文件 08-28 11:01:10.885:W / Database(9975):打开DB 08-28 11:01:10.895:I / UserDbAdapter(9975):processConnection db ==== SQLiteDatabase:/data/data/com.canmmy.expensesmanager/databases/ownexpensesdb 08-28 11:01:10.895:I / sqlite-select query(9975):选择UserId,Name,Password FROM User; 08-28 11:01:10.895:E / SQLiteLog(9975):( 1)没有这样的表:用户 08-28 11:01:10.895:D / AndroidRuntime(9975):关闭VM 08-28 11:01:10.895:W / dalvikvm(9975):threadid = 1:线程退出未捕获异常(组= 0x410502a0) 08-28 11:01:10.900:E / AndroidRuntime(9975):致命异常:主要 08-28 11:01:10.900:E / AndroidRuntime(9975):android.database.sqlite.SQLiteException:没有这样的表:用户(代码1):,同时编译:选择UserId,Name,Password FROM User; 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1011) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:622) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteProgram。(SQLiteProgram.java:58) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteQuery。(SQLiteQuery.java:37) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253) 08-28 11:01:10.900:E / AndroidRuntime(9975):at com.canmmy.expensesmanager.data.UserDbAdapter.getUser(UserDbAdapter.java:81) 08-28 11:01:10.900:E / AndroidRuntime(9975):at com.canmmy.expensesmanager.SplashActivity.initMain(SplashActivity.java:34) 08-28 11:01:10.900:E / AndroidRuntime(9975):at com.canmmy.expensesmanager.SplashActivity.access $ 0(SplashActivity.java:32) 08-28 11:01:10.900:E / AndroidRuntime(9975):at com.canmmy.expensesmanager.SplashActivity $ 1.run(SplashActivity.java:27) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.os.Handler.handleCallback(Handler.java:615) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.os.Handler.dispatchMessage(Handler.java:92) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.os.Looper.loop(Looper.java:137) 08-28 11:01:10.900:E / AndroidRuntime(9975):在android.app.ActivityThread.main(ActivityThread.java:4898) 08-28 11:01:10.900:E / AndroidRuntime(9975):at java.lang.reflect.Method.invokeNative(Native Method) 08-28 11:01:10.900:E / AndroidRuntime(9975):at java.lang.reflect.Method.invoke(Method.java:511) 08-28 11:01:10.900:E / AndroidRuntime(9975):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1008) 08-28 11:01:10.900:E / AndroidRuntime(9975):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775) 08-28 11:01:10.900:E / AndroidRuntime(9975):at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:0)

以下代码适用于我。我把数据库放在assets文件夹中。

您唯一需要注意的是,如果更改资产文件夹中的数据库,则必须首先使用adb卸载yourpackagename卸载应用程序,否则应用程序将更新但数据库不会更新。我花了一点时间来弄明白这一点。希望这会有所帮助。

注意:TDAdb是一种定义数据库使用的变量的方法。在这种情况下,TDAdb.onCreate和TDAdb.onUpdate不必执行任何操作。

    public class TDAdbHelper extends SQLiteOpenHelper {

public static String DATABASE_PATH;
public static final String DATABASE_NAME = "tda.db";
private static final int DATABASE_VERSION = 1;
private Context context;
private SQLiteDatabase db;

public TDAdbHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    this.context = context;
    String packageName = context.getPackageName();
    DATABASE_PATH = String.format(context.getString(R.string.str_databasepath),
            packageName);
    openDataBase();
}

@Override
public void onCreate(SQLiteDatabase db) {
    TDAdb.onCreate(db);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    TDAdb.onUpgrade(db, oldVersion, newVersion);
}

// Performing a database existence check
private boolean checkDataBase() {
    SQLiteDatabase checkDb = null;
    try {
        String path = DATABASE_PATH + DATABASE_NAME;
        checkDb = SQLiteDatabase.openDatabase(path, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLException e) {
        Log.e(this.getClass().toString(), context.getString(R.string.str_error_while_checking_db));
    }

    if (checkDb != null) {
        checkDb.close();
    }
    return checkDb != null;
}

// Method for copying the database
private void copyDataBase() throws IOException {
    //Log.i(this.getClass().toString(), "... in copyDataBase ");
    InputStream externalDbStream = context.getAssets().open(DATABASE_NAME);

    String outFileName = DATABASE_PATH + DATABASE_NAME;

    OutputStream localDbStream = new FileOutputStream(outFileName);

    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = externalDbStream.read(buffer)) > 0) {
        localDbStream.write(buffer, 0, bytesRead);
    }

    localDbStream.close();
    externalDbStream.close();
}

public void createDataBase() {
    //Log.i(this.getClass().toString(), "... in createDataBase ");
    boolean dbExist = checkDataBase();
    if (!dbExist) {
        this.getReadableDatabase();
        try {
            copyDataBase();
        } catch (IOException e) {
            Log.e(this.getClass().toString(), context.getString(R.string.str_copying_error));
            throw new Error(context.getString(R.string.str_error_copying_database_exclamation));
        }
    } else {
        //Log.i(this.getClass().toString(), "Database already exists");
    }
}

public SQLiteDatabase openDataBase() throws SQLException {
    String path = DATABASE_PATH + DATABASE_NAME;
    // Log.i(this.getClass().toString(), "Starting openDatabase " + path);
    if (db == null) {
        createDataBase();
        db = SQLiteDatabase.openDatabase(path, null,
                SQLiteDatabase.OPEN_READWRITE);
    }

    return db;
}

}

度过美好的一天。

相关问题