与此问题相关的问题很多,但没有一个对我有帮助。如果我看到我的代码的逻辑,它应该可以工作,但仍然根本无法工作。我在之前的项目中做到了这一点,当时效果很好,但现在不行了。
安装应用程序时,数据库文件位于/data/data//databases/路径中。但说错误:(1)没有这样的表:表名。然后我使用SQLite浏览器打开数据库文件,可以看到只有一张表android_metadata。其他表丢失。它清楚地表明数据库尚未从 Assets 文件夹中复制。相反,它在给定路径中创建新数据库。如果给定的路径在 SDCard 中,那么我的手机上没有 SD 卡,并且我的手机已 root。每次第一次安装应用程序时,我都需要更改data/data//databases/目录的权限才能查看数据库的数据。
但是当我将数据库文件从 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();
}
日志猫:
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
最佳答案
我想你的 DB_PATH 是硬编码的。
您应该使用 Environment.getDataDirectory()
来获取内部存储路径,因为 Android 可能会根据设备/操作系统版本将其定位在不同的位置。
关于android - 数据库文件未从 Assets 复制到 data/data/<package name>/databases,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22062622/