アプリで DB SQLite を使用しようとしていますが、問題が発生しています。アプリを実行しようとすると、Android が「強制終了」というアプリのクラッシュを返します。コードをチェックして、値と戻り値が問題ないかどうかを確認しました。問題はないようです。いくつかのデバッグを行い、問題は明らかに createDataBase にあります。方法。彼は DB の場所を見つける必要があります。私は変数 PATH を渡しましたが、それでもクラッシュします。タブレットで直接実行するのが正しい原因かどうかわかりません。データ/データのような別のパスを作成する必要があります。 ...(調査中に発見しましたが、わかりません)およびAVD(それが問題です)デスクトップ上のDBの場所を指定する必要がありますか?
コードを見てください:
ConnectDB
package com.victor.profile;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Dialog;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import com.victor.profile.MainActivity;
public class ConnectDB extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "C:/Users/Victor/Dropbox/workspace/Profile/database";
private static String DB_NAME = "profile_db";
private SQLiteDatabase myDataBase;
private final Context myContext;
Dialog dialog;
boolean dbalert;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* @param context
*/
public ConnectDB(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
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 checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
dbalert = new MainActivity().dbFail();
}
if(checkDB != null){
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your 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.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//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 streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
主な活動
package com.victor.profile;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void onDestroy(){
System.exit(0);
}
public void RegisterActivity(View view) throws IOException{
Intent intent = new Intent (this, RegisterActivity.class);
ConnectDB dbcreator = new ConnectDB(this);
dbcreator.createDataBase();
startActivity(intent);
}
public boolean dbFail(){
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Closing App");
alertDialog.setMessage("Unable to find Database...");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
onDestroy();
}
});
alertDialog.show();
return true;
}
}
これがlogcatエラーです
08-06 17:44:09.915: I/Database(283): sqlite returned: error code = 14, msg = cannot open file at source line 25467
*08-06 17:44:09.915: E/Database(283): sqlite3_open_v2("profile_db", &handle, 1, NULL) failed*
08-06 17:44:09.925: D/AndroidRuntime(283): Shutting down VM
08-06 17:44:09.925: W/dalvikvm(283): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
*08-06 17:44:09.946: E/AndroidRuntime(283): FATAL EXCEPTION: main
08-06 17:44:09.946: E/AndroidRuntime(283): java.lang.IllegalStateException: Could not execute method of the activity
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View$1.onClick(View.java:2072)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View.performClick(View.java:2408)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View$PerformClick.run(View.java:8816)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.os.Handler.handleCallback(Handler.java:587)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.os.Handler.dispatchMessage(Handler.java:92)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.os.Looper.loop(Looper.java:123)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.app.ActivityThread.main(ActivityThread.java:4627)
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invokeNative(Native Method)
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invoke(Method.java:521)
08-06 17:44:09.946: E/AndroidRuntime(283): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-06 17:44:09.946: E/AndroidRuntime(283): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-06 17:44:09.946: E/AndroidRuntime(283): at dalvik.system.NativeStart.main(Native Method)
08-06 17:44:09.946: E/AndroidRuntime(283): Caused by: java.lang.reflect.InvocationTargetException
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.MainActivity.RegisterActivity(MainActivity.java:36)
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invokeNative(Native Method)
08-06 17:44:09.946: E/AndroidRuntime(283): at java.lang.reflect.Method.invoke(Method.java:521)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.view.View$1.onClick(View.java:2067)
08-06 17:44:09.946: E/AndroidRuntime(283): ... 11 more
08-06 17:44:09.946: E/AndroidRuntime(283): Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
08-06 17:44:09.946: E/AndroidRuntime(283): at android.app.Activity.getSystemService(Activity.java:3526)
08-06 17:44:09.946: E/AndroidRuntime(283): at com.android.internal.app.AlertController$AlertParams.<init>(AlertController.java:743)
08-06 17:44:09.946: E/AndroidRuntime(283): at android.app.AlertDialog$Builder.<init>(AlertDialog.java:273)
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.MainActivity.dbFail(MainActivity.java:43)
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.ConnectDB.checkDataBase(ConnectDB.java:83)
08-06 17:44:09.946: E/AndroidRuntime(283): at com.victor.profile.ConnectDB.createDataBase(ConnectDB.java:47)
08-06 17:44:09.946: E/AndroidRuntime(283): ... 15 more
08-06 17:44:09.965: W/ActivityManager(58): Force finishing activity com.victor.profile/.MainActivity
08-06 17:44:10.315: I/ARMAssembler(58): generated scanline__00000077:03515104_00000000_00000000 [ 33 ipp] (47 ins) at [0x342d00:0x342dbc] in 385721 ns
08-06 17:44:10.525: W/ActivityManager(58): Activity pause timeout for HistoryRecord{44fee218 com.victor.profile/.MainActivity}
08-06 17:44:20.796: W/ActivityManager(58): Activity destroy timeout for HistoryRecord{44fee218 com.victor.profile/.MainActivity}*