【问题标题】:Copy the existing database sqlite and run at device - android复制现有的数据库 sqlite 并在设备上运行 - android
【发布时间】:2013-08-28 14:02:25
【问题描述】:

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

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/数据库(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:打开失败:EROFS(只读文件系统) 08-28 11:01:10.875: W/System.err(9975): 在 libcore.io.IoBridge.open(IoBridge.java:416) 08-28 11:01:10.880: W/System.err(9975): 在 java.io.FileOutputStream.(FileOutputStream.java:88) 08-28 11:01:10.880: W/System.err(9975): 在 java.io.FileOutputStream.(FileOutputStream.java:128) 08-28 11:01:10.880: W/System.err(9975): 在 java.io.FileOutputStream.(FileOutputStream.java:117) 08-28 11:01:10.880: W/System.err(9975): 在 com.canmmy.expensesmanager.data.DatabaseAdapter.copyDatabase(DatabaseAdapter.java:70) 08-28 11:01:10.880: W/System.err(9975): 在 com.canmmy.expensesmanager.data.DatabaseAdapter.(DatabaseAdapter.java:50) 08-28 11:01:10.880: W/System.err(9975): 在 com.canmmy.expensesmanager.data.UserDbAdapter.processConnection(UserDbAdapter.java:35) 08-28 11:01:10.880: W/System.err(9975): 在 com.canmmy.expensesmanager.data.UserDbAdapter.getUser(UserDbAdapter.java:77) 08-28 11:01:10.880: W/System.err(9975): 在 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): 在 java.lang.reflect.Method.invokeNative(Native Method) 08-28 11:01:10.880: W/System.err(9975): 在 java.lang.reflect.Method.invoke(Method.java:511) 08-28 11:01:10.880: W/System.err(9975): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008) 08-28 11:01:10.880: W/System.err(9975): 在 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: 打开失败: EROFS (只读文件系统) 08-28 11:01:10.885: W/System.err(9975): 在 libcore.io.Posix.open(本机方法) 08-28 11:01:10.885: W/System.err(9975): 在 libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) 08-28 11:01:10.885: W/System.err(9975): 在 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/数据库(9975):找到文件 08-28 11:01:10.885:W/数据库(9975):打开数据库 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): Select UserId, Name, Password FROM User; 08-28 11:01:10.895: E/SQLiteLog(9975): (1) 没有这样的表:用户 08-28 11:01:10.895: D/AndroidRuntime(9975): 关闭虚拟机 08-28 11:01:10.895: W/dalvikvm(9975): threadid=1: 线程退出未捕获异常 (group=0x410502a0) 08-28 11:01:10.900:E/AndroidRuntime(9975):致命异常:主要 08-28 11:01:10.900: E/AndroidRuntime(9975): android.database.sqlite.SQLiteException: no such table: User (code 1): , 编译时: Select UserId, Name, Password FROM User; 08-28 11:01:10.900: E/AndroidRuntime(9975): at 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): 在 java.lang.reflect.Method.invoke(Method.java:511) 08-28 11:01:10.900: E/AndroidRuntime(9975): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008) 08-28 11:01:10.900: E/AndroidRuntime(9975): 在 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)

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    以下代码对我有用。我将数据库放在 assets 文件夹中。

    你唯一需要注意的是,如果你改变了asset文件夹中的数据库,你必须先用adb uninstall 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;
    }
    
    }
    

    祝你有美好的一天。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-23
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-12
      • 2015-03-29
      • 2012-04-17
      相关资源
      最近更新 更多