0

我在字符串 selectedImagePath 中存储了一个图像路径。现在我想将此字符串存储在 SQL 数据库中。因此,我创建了另一个类 ImageAdapter。

您能否查看代码并告诉我为什么当我尝试保存字符串时代码总是崩溃?

这是我的 onActivityResult 方法,如果我检索图像路径并将其存储在字符串 selectedImagePath 中:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == PICK_FROM_FILE) {
            Uri selectedImageUri = data.getData();
            selectedImagePath = getPath(selectedImageUri);

            Log.v("IMAGE PATH====>>>> ",selectedImagePath);

            // Save the image path to the database
            long id = mImageHelper.createImage(selectedImagePath);
            if (id > 0) {
                id = mImageRowId;
            }
        }
    }
}

这是我的数据库助手 ImageAdapter:

public class ImageAdapter {

//
// Database Related Constants
//
private static final String DATABASE_NAME = "dataImage";
private static final String DATABASE_TABLE = "remindersImage";
private static final int DATABASE_VERSION = 4;

public static final String KEY_IMAGE = "image";
public static final String KEY_ROWID = "_id";


private static final String TAG = "ImageAdapter";
private DatabaseHelper mImageHelper;
private SQLiteDatabase mImageDb;

/**
 * Database creation SQL statement
 */
private static final String DATABASE_CREATE =
    "create table " + DATABASE_TABLE + " ("
            + KEY_ROWID + " integer primary key autoincrement, "
            + KEY_IMAGE + " text not null)"; 



private final Context mImageCtx;

private static class DatabaseHelper extends SQLiteOpenHelper {

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

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(DATABASE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
        onCreate(db);
    }
}

/**
 * Constructor - takes the context to allow the database to be
 * opened/created
 * 
 * @param ctx the Context within which to work
 */
public ImageAdapter(Context ctx) {
    this.mImageCtx = ctx;
}

/**
 * Open the database. If it cannot be opened, try to create a new
 * instance of the database. If it cannot be created, throw an exception to
 * signal the failure
 * 
 * @return this (self reference, allowing this to be chained in an
 *         initialization call)
 * @throws SQLException if the database could be neither opened or created
 */
public ImageAdapter open() throws SQLException {
    mImageHelper = new DatabaseHelper(mImageCtx);
    mImageDb = mImageHelper.getWritableDatabase();
    return this;
}

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



public long createImage(String selectedImagePath) {
    ContentValues cv = new ContentValues();
    cv.put(KEY_IMAGE, selectedImagePath);

    return mImageDb.insert(DATABASE_TABLE, null, cv);
}


public boolean deleteImage(long rowId) {

    return mImageDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}


public Cursor fetchAllImages() {

    return mImageDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_IMAGE}, null, null, null, null, null);
}


public Cursor fetchImage(long rowId) throws SQLException {

    Cursor mCursor =

            mImageDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
                    KEY_IMAGE}, KEY_ROWID + "=" + rowId, null,
                    null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;

}


public boolean updateImage(long rowId, String image) {
    ContentValues args = new ContentValues();
    args.put(KEY_IMAGE, image);

    return mImageDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}

更新:这是我的 LogCat:

05-31 21:10:14.947: E/AndroidRuntime(533): FATAL EXCEPTION: main
05-31 21:10:14.947: E/AndroidRuntime(533): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { dat=content://media/external/images/media/22 }} to activity {com.xyz.android.taskreminder/com.xyz.android.taskreminder.ReminderEditActivity}: java.lang.NullPointerException
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.app.ActivityThread.deliverResults(ActivityThread.java:2980)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.app.ActivityThread.handleSendResult(ActivityThread.java:3023)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.app.ActivityThread.access$1100(ActivityThread.java:123)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1177)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.os.Handler.dispatchMessage(Handler.java:99)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.os.Looper.loop(Looper.java:137)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.app.ActivityThread.main(ActivityThread.java:4424)
05-31 21:10:14.947: E/AndroidRuntime(533):  at java.lang.reflect.Method.invokeNative(Native Method)
05-31 21:10:14.947: E/AndroidRuntime(533):  at java.lang.reflect.Method.invoke(Method.java:511)
05-31 21:10:14.947: E/AndroidRuntime(533):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-31 21:10:14.947: E/AndroidRuntime(533):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-31 21:10:14.947: E/AndroidRuntime(533):  at dalvik.system.NativeStart.main(Native Method)
05-31 21:10:14.947: E/AndroidRuntime(533): Caused by: java.lang.NullPointerException
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:115)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1718)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1591)
05-31 21:10:14.947: E/AndroidRuntime(533):  at com.xyz.android.taskreminder.ImageAdapter.createImage(ImageAdapter.java:114)
05-31 21:10:14.947: E/AndroidRuntime(533):  at com.xyz.android.taskreminder.ReminderEditActivity.onActivityResult(ReminderEditActivity.java:233)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.app.Activity.dispatchActivityResult(Activity.java:4649)
05-31 21:10:14.947: E/AndroidRuntime(533):  at android.app.ActivityThread.deliverResults(ActivityThread.java:2976)
05-31 21:10:14.947: E/AndroidRuntime(533):  ... 11 more
4

3 回答 3

2

首先,让我们清理一些代码:)

改变这个

private static final String DATABASE_CREATE =
"create table " + DATABASE_TABLE + " ("
        + KEY_ROWID + " integer primary key autoincrement, "
        + KEY_IMAGE + " text not null)"; 

private static final String DATABASE_CREATE =
"create table if not exists " + DATABASE_TABLE + " ("
        + KEY_ROWID + " integer primary key autoincrement, "
        + KEY_IMAGE + " text not null)"; 

现在,卸载应用程序或清除数据,以便删除之前创建的任何数据库。试用您的应用,然后发布结果。还请发布此行的结果:

Log.v("IMAGE PATH====>>>> ", selectedImagePath);
于 2012-05-31T19:51:45.147 回答
0

ImageAdapter.open()在插入之前打电话吗?如果不是,那么您mImageDb将是null,那将导致崩溃。

于 2012-05-31T19:06:00.800 回答
0

编辑:
Ole 恰当地指出,我假设您正在存储图像,但是您正在存储图像路径,所以现在我建议您遵循 Ole 的回答。

为了进一步说明我为什么建议这样做,以下是:
“尝试在已经包含同名表、索引或视图的数据库中创建新表通常是错误的。但是,如果“ IF NOT EXISTS" 子句被指定为 CREATE TABLE 语句的一部分,并且同名的表或视图已经存在,CREATE TABLE 命令根本不起作用(并且不返回错误消息)。如果由于现有索引,即使指定了“IF NOT EXISTS”子句,也无法创建表。”
资料来源:sqlite.org

另外,我总是建议使用try-catch块并logs尽可能多地进行故障排除。

于 2012-05-31T20:01:23.240 回答