为什么我的SQL数据库无法存储字符串?

时间:2012-05-31 18:55:45

标签: android sql string

我在字符串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

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

插入之前是否致电ImageAdapter.open()?如果没有,则mImageDb将为null,这将导致崩溃。

答案 2 :(得分:0)

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

为了进一步说明我的建议,请按以下步骤进行: “尝试在已包含同名的表,索引或视图的数据库中创建新表通常是错误的。但是,如果将”IF NOT EXISTS“子句指定为CREATE TABLE语句的一部分,已存在同名的表或视图,CREATE TABLE命令根本没有效果(并且不返回任何错误消息)。如果由于现有索引而无法创建表,则仍会返回错误,即使“IF” NOT EXISTS“条款被指定。”
资料来源:sqlite.org

此外,我始终建议尽可能使用try - catch块和logs进行故障排除。