数据库文件不是从资产复制到data / data / <package name =“”> / databases </package>

时间:2014-02-27 08:09:53

标签: android mysql database sqlite assets

有很多与这个问题相关的问题,但没有一个问题对我有帮助。如果我看到我的代码的逻辑它应该工作,但仍然没有工作。我在之前的项目中做到了这一点,当时工作正常,但现在不行。

安装应用程序时,数据库文件位于/ data / data // databases / path中。但是说错误:(1)没有这样的表:表名。然后我使用SQLite浏览器打开数据库文件,我可以看到只有一个表android_metadata。缺少其他表格。它清除说明数据库尚未从assets文件夹复制。相反,它是在给定路径中创建新数据库。如果给定的路径在SD卡中,那么我的手机上没有SD卡,而且我的手机已经植根了。每次首次安装应用程序时,我都需要更改数据/数据//数据库/目录的权限,以查看数据库的数据。

但是,当我将数据库文件从assets文件夹动态提取到/ data / data // databases /时,我的应用程序不会崩溃。当然,我不希望这样做。请问您能查看我的代码并找出可以更改的内容。谢谢!

public DatabaseHelper() throws IOException {
    super(Attendance.getContext(), DB_NAME, null, DB_VERSION);
    /*try {
        createDataBase();
        openDataBase();
    } catch (IOException e) {
        e.printStackTrace();
    }*/
    boolean dbexist = checkDataBase();
    if(dbexist){
        openDataBase();
    }else{
        createDataBase();
    }
}

/**
 * Database maintains global state in application
 * 
 * @return singleton instance
 */
public static DatabaseHelper getInstance() {

    if (mInstance == null) {
        try {
            mInstance = new DatabaseHelper();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return mInstance;
}

/**
 * Creates a empty database on the system and rewrites it with your own
 * database.
 * 
 * @throws IOException
 */
public void createDataBase() throws IOException {

    boolean dbexist = checkDataBase();
    if (dbexist) {

    }else{
        this.getReadableDatabase();
        try{
            copyDataBase();
        }catch(IOException e){
            throw new Error("Error copying database");
        }
    }
}

/**
 * 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 checkDataBase = null;
    boolean checkDataBase =true;
    try {
        String Path = DB_PATH + DB_NAME;
        File dbFile = new File(Path);
        /*
         * checkDataBase = SQLiteDatabase.openDatabase(Path, null,
         * SQLiteDatabase.OPEN_READONLY);
         */
        checkDataBase = dbFile.exists();
    } catch (SQLiteException e) {
        Log.e("CheckDb", "DB not found");
        // database does't exist yet.
    }
    return checkDataBase;
}

/**
 * Copies your database from 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 transfering bytestream.
 * 
 * @throws IOException
 */

private void copyDataBase() throws IOException {

    // Open your local database as the input stream
    InputStream myInput = context.getAssets().open(DB_NAME);

    // Open the empty db as the output stream.
    OutputStream myOutput = new FileOutputStream(DB_PATH + DB_NAME);

    // transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }
    // Close the stream.
    myOutput.close();
    myOutput.flush();
    myInput.close();
    Log.i("Database", "New database has been copied to device!");

}

/**
 * Open the database
 * 
 * @throws SQLException
 */
public boolean openDataBase() throws SQLException {
    String path = DB_PATH + DB_NAME;
    db = SQLiteDatabase.openDatabase(path, null,
            SQLiteDatabase.OPEN_READWRITE);
    Log.i("DB....", "database opened....");
    return db != null;
}

public synchronized void close() {
    if (mInstance != null)
        db.close();
    super.close();
}

logcat的:

02-27 13:30:26.509: D/AndroidRuntime(20480): Shutting down VM
02-27 13:30:26.509: W/dalvikvm(20480): threadid=1: thread exiting with uncaught  exception (group=0x4188eba8)
02-27 13:30:26.509: E/AndroidRuntime(20480): FATAL EXCEPTION: main
02-27 13:30:26.509: E/AndroidRuntime(20480): Process: <package-name>, PID: 20480
02-27 13:30:26.509: E/AndroidRuntime(20480): java.lang.RuntimeException: Unable to start activity ComponentInfo{<package-name>/<package-name>.MainActivity}: java.lang.NullPointerException
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.os.Looper.loop(Looper.java:136)
 02-27 13:30:26.509: E/AndroidRuntime(20480):   at android.app.ActivityThread.main(ActivityThread.java:5017)
 02-27 13:30:26.509: E/AndroidRuntime(20480):   at java.lang.reflect.Method.invokeNative(Native Method)
 02-27 13:30:26.509: E/AndroidRuntime(20480):   at java.lang.reflect.Method.invoke(Method.java:515)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at dalvik.system.NativeStart.main(Native Method)
02-27 13:30:26.509: E/AndroidRuntime(20480): Caused by: java.lang.NullPointerException
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.copyDataBase(DatabaseHelper.java:172)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.createDataBase(DatabaseHelper.java:130)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.<init>(DatabaseHelper.java:94)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.helper.DatabaseHelper.getInstance(DatabaseHelper.java:107)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com.Areva.areva_attendance.model.Portfolio.<init>(Portfolio.java:25)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at com .Areva.areva_attendance.MainActivity.onCreate(MainActivity.java:43)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.Activity.performCreate(Activity.java:5231)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-27 13:30:26.509: E/AndroidRuntime(20480):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
02-27 13:30:26.509: E/AndroidRuntime(20480):    ... 11 more

2 个答案:

答案 0 :(得分:0)

我想你的DB_PATH是硬编码的。

您应该使用Environment.getDataDirectory()获取内部存储路径,因为Android可能会根据设备/操作系统版本将其定位在其他位置。

答案 1 :(得分:0)

严重!!我不相信这一点。我刚刚在我的应用程序的第一个查询中添加了 db.openDataBase(); 函数,然后就可以了。我无法相信这。我现在意识到我应该在查询之前打开数据库。在这类问题中它可能会有所帮助。 CHEERSS! :d

不要忘记在pause()和resume()db.open();

中的db.close