6

編集: 携帯電話でこれを試してみましたが、動作します。エミュレータで動作しない理由を誰か教えてもらえますか?

Androidでデータベースを開こうとしていますが、「データベースファイルを開けませんでした」という例外がスローされています。デバッガでは、ライン上でエラーが発生しているようですmDb = mDbHelper.getWritableDatabase();

私のコードは次のとおりです。

package com.track.map;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;


    public class DBAdapter {

        protected static final String DATABASE_NAME = "data";
        protected static final int DATABASE_VERSION = 1;

        //database tables
        //track table
        protected static final String TRACK_TABLE = "tracks";
        protected static final String TRACK_ID = "_id";
        protected static final String TRACK_DATE_TIME_START = "date_time_start";
        protected static final String TRACK_DATE_TIME_END = "date_time_end";

        //tables create
        protected static final String TRACK_TABLE_CREATE = 
                                "create table " + TRACK_TABLE + " ("
                                    + TRACK_ID + " integet promary key not null, "
                                    + TRACK_DATE_TIME_START + " text not null, "
                                    + TRACK_DATE_TIME_END + " text not null);";

        protected DatabaseHelper mDbHelper;
        protected SQLiteDatabase mDb;

        protected final Context mContext;

        public DBAdapter(Context context) {
            mContext = context;
        }

        public DBAdapter open() throws android.database.SQLException {
            mDbHelper = new DatabaseHelper(mContext);
            mDb = mDbHelper.getWritableDatabase();
            return this;
        }

        public void close() {
            mDb.close();
        }

        protected static class DatabaseHelper extends SQLiteOpenHelper {

            public DatabaseHelper(Context context) {
                super(context, DATABASE_NAME, null, DATABASE_VERSION);
            }

            @Override
            public void onCreate(SQLiteDatabase db) {
                db.execSQL(TRACK_TABLE_CREATE);
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                onCreate(db); //for now just recreate the database
            }

        }

    }

package com.track.map;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    private DBAdapter db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        db = new DBAdapter(this);
        db.open();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

誰が問題が何であるか知っていますか?

編集:

ログキャットは次のとおりです。

03-24 11:43:42.022: I/Database(758): sqlite returned: error code = 14, msg = cannot open file at source line 25467
03-24 11:43:42.022: E/Database(758): sqlite3_open_v2("/data/data/com.track.map/databases/data", &handle, 6, NULL) failed
03-24 11:43:42.032: D/AndroidRuntime(758): Shutting down VM
03-24 11:43:42.032: W/dalvikvm(758): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
03-24 11:43:42.062: E/AndroidRuntime(758): FATAL EXCEPTION: main
03-24 11:43:42.062: E/AndroidRuntime(758): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.track.map/com.track.map.MainActivity}: android.database.sqlite.SQLiteException: unable to open database file
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.os.Handler.dispatchMessage(Handler.java:99)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.os.Looper.loop(Looper.java:123)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.ActivityThread.main(ActivityThread.java:4627)
03-24 11:43:42.062: E/AndroidRuntime(758):  at java.lang.reflect.Method.invokeNative(Native Method)
03-24 11:43:42.062: E/AndroidRuntime(758):  at java.lang.reflect.Method.invoke(Method.java:521)
03-24 11:43:42.062: E/AndroidRuntime(758):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
03-24 11:43:42.062: E/AndroidRuntime(758):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
03-24 11:43:42.062: E/AndroidRuntime(758):  at dalvik.system.NativeStart.main(Native Method)
03-24 11:43:42.062: E/AndroidRuntime(758): Caused by: android.database.sqlite.SQLiteException: unable to open database file
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1812)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
03-24 11:43:42.062: E/AndroidRuntime(758):  at com.track.map.DBAdapter.open(DBAdapter.java:37)
03-24 11:43:42.062: E/AndroidRuntime(758):  at com.track.map.MainActivity.onCreate(MainActivity.java:17)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-24 11:43:42.062: E/AndroidRuntime(758):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
03-24 11:43:42.062: E/AndroidRuntime(758):  ... 11 more
4

5 に答える 5

5

これは少し遅れているかもしれませんが、これがこの問題を抱えている人の助けになることを願っています (決定的な解決策が見つからないため)。

私はこの原因の理由を知っていると思います(少なくとも私の場合)。DDMS -->ファイル エクスプローラーを見ると、データベース フォルダー ( /data/data//databases/) が存在しないことがわかります。これが、アプリケーションが存在しないフォルダーにデータベース ファイルを作成できない理由です。何らかの方法でデータベース フォルダーを作成できる場合は、この問題を回避できます。

私は怠け者なので/data/data//files/、エミュレータ モードのときにフォルダを使用しただけです。これを使用してファイルディレクトリを取得できます:

context.getFilesDir().getPath()

これは、エミュレーターでうまく機能しました。

これが誰かに役立つことを願っています。

いくつかのコードを見たい場合:

String dbFilename = "example.db";
try
{       
    File databaseFile = getDatabasePath(dbFilename);        
    SQLiteDatabase _db = SQLiteDatabase.openOrCreateDatabase(databaseFile);
} catch (Exception e)
{
    String databasePath =  getFilesDir().getPath() +  "/" + dbFilename;
    File databaseFile = new File(databasePath); 
    _db = SQLiteDatabase.openOrCreateDatabase(databaseFile);
}

編集:

エミュレーターで Facebook (私のアプリには FB 統合があります) にログインしようとしましたが、その後 /databases フォルダーが表示されました (そして永続化されました)。何が起こったのかわかりませんが、どうにかしてそのフォルダーを作成することは可能です。このあたりの別の専門家が明らかにする何か。

于 2013-08-29T12:49:14.227 に答える
2

コンストラクタでこれを試してください

public youeConstructor(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        context.openOrCreateDatabase(DATABASE_NAME, context.MODE_PRIVATE, null);
    }
于 2014-12-01T11:09:39.513 に答える
1

現在の問題とは関係ありませんが、SQLiteOpenHelper の onUpgrade メソッドも将来失敗する可能性があります。データベースの新しいバージョンがデプロイされたときに実行したいアクションがゼロから開始する場合は、削除する必要があります最初に古いテーブル。

編集いくつかの調査の後、あなたの問題はかなり一般的であることがわかりました:

Android SQLiteOpenHelper がデータベース ファイルを開けません

この回答で提供される3つのリンク

https://stackoverflow.com/a/8957994/2177061

特に興味深いものであり、バグを消すためのきれいな方法が見つからない場合に備えて、何らかの回避策を提供します。

そうは言っても、複雑な回避策を検討する前に問題を解決するための最初の試みとして、すべての Android 開発ツール (特に SD​​K ですが、Eclipse プラグインを更新しても害はありません) を完全に削除しようとします。エミュレーターとデバイスの両方からアプリを削除し、再度実行します。

幸運を!

編集2次の発言は無視してください(正しくありません。参考のためにここに残します)

SQL クエリが間違っているため、コードが機能しません。

integet promary

あるべき場所

integer primary

(さらに、問題がSQLクエリにあることに気付くだけで、Android dbクラスに夢中になることも私には起こります:))

お役に立てれば

于 2013-03-24T10:22:21.097 に答える
1

私はこの問題の解決策を探していましたが、うまくいくものは何も見つかりませんでした...しかし、幸いにもそれを解決する何かをしました。これは私がしたことです:

adb シェルを開き、開こうとしているデータベースを削除します。Linux ターミナルの使い方がわからない人向け:

// 最初にコマンド ラインから adb シェルを開きます

adb shell

// これらは必要なコマンドです (アプリ パッケージの YOUR.APP.PACKAGE を変更します。com.domain.apilcation のようになります)

cd /data/data/YOUR.APP.PACKAGE/databases/
ls

最後のコマンド (ls) は、プロジェクト用に作成したすべてのデータベースを一覧表示し、開くことができないデータベースを削除できるようになりました。まず、重要なデータを失わないようにコピーする必要があります。(あなたのデータベースはyour_database.dbと呼ばれていると思います)

cp your_database.db your_database.db_backup
rm your_database.db

次に、アプリを起動する必要があります。新しいデータベースが作成され、私にとってはこれで問題が完全に解決されました。

これが役立つことを願っています!

于 2014-03-30T12:05:41.183 に答える
0
Why are you keeping code complex try this


public SQLiteDatabase sampleDB;
    public String COLUMN_ID="_id";
    public String COLUMN1="username";
    public String COLUMN2="password";
    public String TABLE_NAME="Androdata";

sampleDB =  this.openOrCreateDatabase(TABLE_NAME, MODE_PRIVATE, null);

private void insertDB() {
        sampleDB.execSQL("INSERT INTO " +
                TABLE_NAME +
                " Values ('1','Androviewer','viewer');");   
        System.out.println("Inserted data successfully....");
    }
    private void createDB() {
        sampleDB.execSQL("CREATE TABLE IF NOT EXISTS " +
                TABLE_NAME+ "(" + COLUMN_ID
                + " integer primary key autoincrement, " + COLUMN1
                + " text not null,"+ COLUMN2
                + " text not null);");
        System.out.println("Database created successfully....");
    }
于 2013-03-24T10:06:42.257 に答える