首页 \ 问答 \ 首次将.apk文件上传到市场后,“SQLiteException:无法打开数据库文件”(Android 2.3.5)(“SQLiteException: unable to open database file” after first uploading the .apk file to the market (Android 2.3.5))

首次将.apk文件上传到市场后,“SQLiteException:无法打开数据库文件”(Android 2.3.5)(“SQLiteException: unable to open database file” after first uploading the .apk file to the market (Android 2.3.5))

编辑:该应用程序崩溃在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) {}
}

EDIT: The app is crashing on mobile phones with Android version 2.3.5

I have uploaded my first app on Google Play yesterday, today I got error report with the follwoing:

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)

EDIT: Here is my SQLiteOpenHelper class, I might be doing something wrong, please check it out:

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) {}
}

原文:https://stackoverflow.com/questions/10102764
更新时间:2022-02-17 14:02

最满意答案

你有没有尝试过CellEditEnding活动? eventargs有一个'EditingElement'属性,它将为您提供实际的编辑元素(在本例中为ComboBox),您可以使用它来查找单元格中的'SelectedValue'。


Did you try CellEditEnding event? The eventargs has an 'EditingElement' property which will give you the actual editing element (ComboBox in this case), you can use it to find the 'SelectedValue' in the cell.

相关问答

更多
  • 就像我在评论中提到的那样,你需要阅读更多有关WPF和绑定的信息,因为它试图从UI获取的值可以很容易地从底层数据对象中获取 。 假设您已将dataGrid绑定到某个列表ObservableCollection并且dataGrid的第一列绑定到属性Name 。 您可以像这样获得第一个单元格的值: for (int i = 0; i < dataGridView1.Items.Count; i++) { string value = ((MyObject)dataGridView1.I ...
  • 尝试使用DataTemplate.Triggers:1。命名您的VisualBrush:
    如果要阻止选择某些列中的单元格,可以使用DataGridCell样式将这些单元格的IsHitTestVisible属性设置为true :