有很多与这个问题相关的问题,但没有一个问题对我有帮助。如果我看到我的代码的逻辑它应该工作,但仍然没有工作。我在之前的项目中做到了这一点,当时工作正常,但现在不行。
安装应用程序时,数据库文件位于/ 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
答案 0 :(得分:0)
我想你的DB_PATH是硬编码的。
您应该使用Environment.getDataDirectory()
获取内部存储路径,因为Android可能会根据设备/操作系统版本将其定位在其他位置。
答案 1 :(得分:0)
严重!!我不相信这一点。我刚刚在我的应用程序的第一个查询中添加了 db.openDataBase(); 函数,然后就可以了。我无法相信这。我现在意识到我应该在查询之前打开数据库。在这类问题中它可能会有所帮助。 CHEERSS! :d
不要忘记在pause()和resume()db.open();
中的db.close