开发者

ContentProvider fails on insert

I am brand new to developing for android and have hit something of a stumbling block that I cant seem to get around.

Using the NotePad example, I have created my own ContentProvider to serve up data from a database that I will eventually host on a webserver. But that is lightyears away from where I am right now.

Just testing my ContentProvider has caused a bit of a headache that I cant solve. For some reason, when the provider calls SQLiteDatabase db = mOpenHelper.getWritableDatabase(); I get a null pointer exception.

Code Follows:

MainWindow.java


public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    /**
     * Check for DB, if none, d/l from web server
     */
    Uri first_use = Rules.CONTENT_URI;
    ContentResolver cr = getContentResolver();
    Cursor c = cr.query(first_use, null, null, null, null);
    if(c == null){
        ContentProvider cp = new CoreRulesProvider();
        if (cp.onCreate()) {
            ContentValues values = new ContentValues();
            values.put(Rules._ID, 1);
            values.put(Rules.TERM, "Player");
            values.put(Rules.TEXT, "You, the person reading these rules, are a Player.");开发者_运维百科
                cp.insert(Rules.CONTENT_URI, values);
        }
    }

RulesContentProvider.java


package com.vortex.rules;


import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import java.util.HashMap;

import com.vortex.rules.Rule.Rules;

/**
 * Provides access to a database of rules.  Each rule has a TERM, the RULE itself, and a creation date and modified data.
 * @author Michael Martin
 *
 */

public class CoreRulesProvider extends ContentProvider {

    private static final String TAG = "CoreRulesProvider";

    private static final String DATABASE_NAME = "core_rules.db";
    private static final int DATABASE_VERSION = 2;
    private static final String RULES_TABLE_NAME = "rules";

    private static HashMap<String, String> sRulesProjectionMap;
    private static HashMap<String, String> sLiveFolderProjectionMap;

    private static final int RULES = 1;
    private static final int RULE_ID = 2;
    private static final int LIVE_FOLDER_RULES = 3;

    private static final UriMatcher sUriMatcher;

    /**
     * This class helps open, create, and upgrade the database file.
     */
    private static class DatabaseHelper extends SQLiteOpenHelper {

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

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE " + RULES_TABLE_NAME + " ("
                    + Rules._ID + " INTEGER PRIMARY KEY,"
                    + Rules.TERM + " TEXT,"
                    + Rules.TEXT + " LONGTEXT"
                    + ");");
        }

        @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 rules");
            onCreate(db);
        }
    }
    /**
     * END OF DatabaseHelper CLASS!!!!!
     */

    private DatabaseHelper mOpenHelper;

    @Override
    public boolean onCreate() {
        mOpenHelper = new DatabaseHelper(getContext());
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(RULES_TABLE_NAME);

        switch (sUriMatcher.match(uri)) {
        case RULES:
            qb.setProjectionMap(sRulesProjectionMap);
            break;

        case RULE_ID:
            qb.setProjectionMap(sLiveFolderProjectionMap);
            qb.appendWhere(Rules._ID + "=" + uri.getPathSegments().get(1));
            break;

        default:
            throw new IllegalArgumentException("Uknown URI " + uri);
        }

        //If no sort order is specified, use the default
        String orderBy;
        if (TextUtils.isEmpty(sortOrder)) {orderBy = Rules.DEFAULT_SORT_ORDER;
    } else {
        orderBy = sortOrder;
    }

        //Get the database and run the query
        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);

        //Tell the cursor what uri to watch, so it knows when its source data changes
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    @Override
    public String getType(Uri uri) {
        switch (sUriMatcher.match(uri)) {
        case RULES:
        case LIVE_FOLDER_RULES:
            return Rules.CONTENT_TYPE;

        case RULE_ID:
            return Rules.CONTENT_ITEM_TYPE;

        default:
            throw new IllegalArgumentException("Uknown URI " + uri);
        }
    }

    public Uri insert(Uri uri, ContentValues initialValues) {
        //Validate the requested uri
        if (sUriMatcher.match(uri) != RULES) {
            throw new IllegalArgumentException("Uknown URI " + uri);
        }

        ContentValues values;
        if (initialValues != null) {
            values = new ContentValues(initialValues);
        } else {
            values = new ContentValues();
        }


        //Make sure that the fields are all set
        if (values.containsKey(Rules.TERM) == false) {
            Resources r = Resources.getSystem();
            values.put(Rules.TERM, r.getString(android.R.string.untitled));
        }

        if (values.containsKey(Rules.TEXT) == false) {
            values.put(Rules.TEXT, "");
        }
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        long rowId = db.insert(RULES_TABLE_NAME, Rules.TEXT, values);
        if (rowId > 0) {
            Uri ruleUri = ContentUris.withAppendedId(Rules.CONTENT_URI, rowId);
            getContext().getContentResolver().notifyChange(ruleUri, null);
            return ruleUri;
        }

        throw new SQLException("Failed to insert row into " + uri);
    }

    public int delete(Uri uri, String where, String[] whereArgs) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
        case RULES:
            count = db.delete(RULES_TABLE_NAME, where, whereArgs);
            break;

        case RULE_ID:
            String ruleId = uri.getPathSegments().get(1);
            count = db.delete(RULES_TABLE_NAME, Rules._ID + "=" + ruleId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
                    whereArgs);
            break;

        default:
            throw new IllegalArgumentException("Uknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        int count;
        switch (sUriMatcher.match(uri)) {
        case RULES:
            count = db.update(RULES_TABLE_NAME, values, where, whereArgs);
            break;

        case RULE_ID:
            String ruleId = uri.getPathSegments().get(1);
            count = db.update(RULES_TABLE_NAME, values, Rules._ID + "=" + ruleId
                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : "")
                    , whereArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }

    static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(Rule.AUTHORITY, "rules", RULES);
        sUriMatcher.addURI(Rule.AUTHORITY, "rules/#", RULE_ID);
        sUriMatcher.addURI(Rule.AUTHORITY, "live_folders/rules", LIVE_FOLDER_RULES);

        sRulesProjectionMap = new HashMap<String, String>();
        sRulesProjectionMap.put(Rules._ID, Rules._ID);
        sRulesProjectionMap.put(Rules.TERM, Rules.TERM);
        sRulesProjectionMap.put(Rules.TEXT, Rules.TEXT);
    }

}

Stack Trace


07-30 10:22:19.078: ERROR/AndroidRuntime(10903): Uncaught handler: thread main exiting due to uncaught exception 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.vortex.rules/com.vortex.rules.MainWindow}: java.lang.NullPointerException 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2444) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2460) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.app.ActivityThread.access$2300(ActivityThread.java:119) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1837) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.os.Handler.dispatchMessage(Handler.java:99) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.os.Looper.loop(Looper.java:123) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.app.ActivityThread.main(ActivityThread.java:4246) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at java.lang.reflect.Method.invokeNative(Native Method) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at java.lang.reflect.Method.invoke(Method.java:521) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at dalvik.system.NativeStart.main(Native Method) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): Caused by: java.lang.NullPointerException 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at com.vortex.rules.CoreRulesProvider.insert(CoreRulesProvider.java:157) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at com.vortex.rules.MainWindow.onCreate(MainWindow.java:42) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2407) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903): ... 11 more


Figuered this out on my own eventualy. Turns out I was missing a letter in my URI, got it fixed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜