title: ContentProvider fails on insert
body: <p>I am brand new to developing for android and have hit something of a stumbling block that I cant seem to get around.</p>
  
  <p>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.</p>
  
  <p>Just testing my ContentProvider has caused a bit of a headache that I cant solve.  For some reason, when the provider calls <code>SQLiteDatabase db = mOpenHelper.getWritableDatabase();</code> I get a null pointer exception.</p>
  
  <p>Code Follows:</p>
  
  <p>MainWindow.java</p>
  
  <hr>
  
  <pre><code>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);
          }
      }
  </code></pre>
  
  <p>RulesContentProvider.java</p>
  
  <hr>
  
  <pre><code>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&lt;String, String&gt; sRulesProjectionMap;
      private static HashMap&lt;String, String&gt; 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 &gt; 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&lt;String, String&gt;();
          sRulesProjectionMap.put(Rules._ID, Rules._ID);
          sRulesProjectionMap.put(Rules.TERM, Rules.TERM);
          sRulesProjectionMap.put(Rules.TEXT, Rules.TEXT);
      }
  
  }
  </code></pre>
  
  <p>Stack Trace</p>
  
  <hr>
  
  <p>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</p>