1

编辑:该应用程序在Android 版本 2.3.5的手机上崩溃

我昨天在 Google Play 上上传了我的第一个应用程序,今天我收到以下错误报告:

android.database.sqlite.SQLiteException: unable to open database file
at android.database.sqlite.SQLiteDatabase.dbopen(Native Method)
at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1956)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:918)
at com.hazcheck.dgl.data.ExternalDBOpenHelper.openDataBase(ExternalDBOpenHelper.java:96)
at com.hazcheck.dgl.SearchActivity.afterTextChanged(SearchActivity.java:284)
at android.widget.TextView.sendAfterTextChanged(TextView.java:6566)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:6989)
at android.text.SpannableStringBuilder.sendTextHasChanged(SpannableStringBuilder.java:897)
at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:353)
at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:269)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:432)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:409)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:28)
at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:679)
at android.view.inputmethod.BaseInputConnection.commitText(BaseInputConnection.java:185)
at com.android.internal.widget.EditableInputConnection.commitText(EditableInputConnection.java:120)
at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:332)
at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:86)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4268)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

编辑:这是我的 SQLiteOpenHelper 类,我可能做错了什么,请检查一下:

package com.hazcheck.dgl.data;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
//import java.util.zip.ZipInputStream;

import com.hazcheck.dgl.R;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
//import android.content.res.Resources;

public class ExternalDBOpenHelper  extends SQLiteOpenHelper{

    //public static int DB_PATH_ID; 
    public static String DB_NAME;
    public static String DB_PATH;
    public static int DB_VERSION;
    public SQLiteDatabase database;
    public final Context context;

    //private Resources resources;

    public SQLiteDatabase getDb() {
        return database;
    }
        public ExternalDBOpenHelper(Context context) {
        super(context, DB_NAME = context.getString(R.string.app_data_name), null, DB_VERSION = Integer.parseInt((context.getString(R.string.app_database_version))));
        this.context = context;
        String packageName = context.getPackageName();
        //resources = context.getResources();
        //DB_PATH_ID = R.raw.imdg35;
        DB_PATH = String.format("//data//data//%s//databases//", packageName);

        openDataBase(); //createDataBase();
    }


    public void createDataBase() {
        boolean dbExist = checkDataBase();
        if (!dbExist) {
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {
                Log.e(this.getClass().toString(), "Copying error");
                throw new Error("Error copying database!");
            }
        } else {
            Log.i(this.getClass().toString(), "Database already exists");
        }
    }

    private boolean checkDataBase() {
        String path = DB_PATH + DB_NAME;
        File dbFile = new File(path);
        return dbFile.exists();
    }

    private void copyDataBase() throws IOException {
        InputStream externalDbStream = context.getAssets().open(DB_NAME);

        String outFileName = DB_PATH + DB_NAME;

        OutputStream localDbStream = new FileOutputStream(outFileName);

    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = externalDbStream.read(buffer)) > 0) {
        localDbStream.write(buffer, 0, bytesRead);
    }

    localDbStream.close();
    externalDbStream.close();
/*  String outFileName = DB_PATH + DB_NAME;
    InputStream is = resources.openRawResource(DB_PATH_ID);
    OutputStream myOutput = new FileOutputStream(outFileName);
    ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is));
    try {
        while (zis.getNextEntry() != null) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int count;
            while ((count = zis.read(buffer)) != -1) {
                baos.write(buffer, 0, count);
                //Log.d("", buffer.toString());
            }
            baos.writeTo(myOutput);
        }
    }
    finally{
        zis.close();
        myOutput.flush();
        myOutput.close();
        is.close();
    }*/
}

public SQLiteDatabase openDataBase() throws SQLException {
    String path = DB_PATH + DB_NAME;
    if (database == null) {
        createDataBase();
        database = SQLiteDatabase.openDatabase(path, null,  SQLiteDatabase.OPEN_READWRITE);
    }
    return database;
}
@Override
public synchronized void close() {
    if (database != null) {
        database.close();
    }
    super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}
4

4 回答 4

0

1)您在这一行指的是哪个数据库:com.hazcheck.dgl.SearchActivity.afterTextChanged(SearchActivity.java:284)?相应的数据库是否存在?您是否在 OnCreate() 方法中实例化/创建了数据库?如果没有,那就是你的错误。您可能在您的设备上测试了该应用程序,而您只是第一次创建它;即使您替换了应用程序包,应用程序也会在其中重新使用数据库。

2)关于“1个错误报告,而0个安装”,这也发生在我的应用程序中。更新安装数量的过程可能是周期性的,而更新错误日志是即时的。

于 2012-04-11T09:08:30.420 回答
0
    > String outFileName = DB_PATH + DB_NAME;

这可能是一个问题,具体取决于应用程序是安装在 SD 卡上还是手机内存中。

DatabaseContext及其后代(如Activity)有一个方法

    File getDatabasePath(String name)

那应该给你正确的目录。

于 2012-04-11T09:20:47.913 回答
0

我发现问题出在数据库本身,它是用旧的 Sqlite 版本创建的。现在,我使用 Sqlite 3.7.11 并重新创建了数据库,现在它工作得很好。

于 2012-05-10T09:08:45.027 回答
0

在我的情况下,当我使用该方法使用 databaseInstance 打开数据库时

private static boolean openDB(String dbPathWithName) {
        boolean status = true;
        try {
            if (databaseInstance == null || !databaseInstance.isOpen()){
                databaseInstance = SQLiteDatabase.openDatabase(dbPathWithName, null, SQLiteDatabase.OPEN_READWRITE + SQLiteDatabase.CREATE_IF_NECESSARY);

            }
        } catch (Exception ex){
            status = false;
            NGAndroidUtil.logErr("DataHelper", ex.getMessage(), ex);
        }
        return status;
    }

在此它抛出异常“无法打开数据库”......在这个我没有以正确的格式给出数据库的路径,这就是它抛出异常“无法打开数据库......确保路径您要打开的正确格式的数据库..

于 2013-01-01T03:30:06.293 回答