views:

33

answers:

1

this is the code for my custom provider,
mostly copied from the SDK notepad project
i cant understand why am i getting nullPointException,
why doesnt the provider instance get created?

thanks ! :)

RegistrationProvider.java

package alon.beginner.registerform;

import android.database.SQLException;
import java.util.HashMap;

import alon.beginner.registerform.RegistrationFormMetaData.Users;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
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;

/**
 * Provides access to the database of registered users.
 * each user has a 
 * name, email , birthday date, a creation date and modification date
 */
public class RegistrationProvider extends ContentProvider {

  private static final String TAG = "RegistrationProvider";

  private static final String DATABASE_NAME = "register_yourself.db";
  private static final int DATABASE_VERSION = 1;
  private static final String USERS_TABLE_NAME = "users"; 

  private static HashMap sUsersProjectionMap;

  private static final int USERS = 1;
  private static final int USER_ID = 2;

  private static final UriMatcher sUriMatcher;

  static {
   sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
   sUriMatcher.addURI(RegistrationFormMetaData.AUTHORITY, "users", USERS);
   sUriMatcher.addURI(RegistrationFormMetaData.AUTHORITY, "users/#", USER_ID);

   sUsersProjectionMap.put(Users._ID, Users._ID);
   sUsersProjectionMap.put(Users.FULL_NAME, Users.FULL_NAME);
   sUsersProjectionMap.put(Users.EMAIL, Users.EMAIL);
   sUsersProjectionMap.put(Users.BIRTHDAY_DATE, Users.BIRTHDAY_DATE);
   sUsersProjectionMap.put(Users.CREATED_DATE, Users.CREATED_DATE);
   sUsersProjectionMap.put(Users.MODIFIED_DATE, Users.MODIFIED_DATE);
  }
  /** 
   * this class helps to create, open , and upgrade the database files
   */
  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 " + USERS_TABLE_NAME + " ("
       + Users._ID + " INTEGER PRIMARY KEY, "
       + Users.FULL_NAME + " TEXT, "
       + Users.EMAIL + " TEXT, "
       + Users.BIRTHDAY_DATE + " TEXT, "
       + Users.CREATED_DATE + " INTEGER, "
       + Users.MODIFIED_DATE + " INTEGER"
       + ");"  );  
   }

        @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 users");
            onCreate(db);
        }
  }

  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(USERS_TABLE_NAME);

      switch(sUriMatcher.match(uri)){
      case USERS:
        qb.setProjectionMap(sUsersProjectionMap);
        break;
      case USER_ID:
       qb.setProjectionMap(sUsersProjectionMap);
       break;

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

      //if no sort order is specified use the default
      String orderBy;
      if (TextUtils.isEmpty(sortOrder)){
       orderBy = Users.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;
  }//here i am

  @Override
  public String getType(Uri uri) {
  switch(sUriMatcher.match(uri)){
  case USERS:
   return Users.CONTENT_TYPE;
  case USER_ID:
   return Users.CONTENT_ITEM_TYPE;

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

  @Override
  public Uri insert(Uri uri, ContentValues initialValues) {
   //Validate the requested uri
   if (sUriMatcher.match(uri) != USERS )
    throw new IllegalArgumentException("Unknown URI " + uri);

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

   Long now = Long.valueOf(System.currentTimeMillis());

   //Make sure that the fields are all set
   if(values.containsKey(Users.CREATED_DATE) == false )
    values.put(Users.CREATED_DATE, now);
   if(values.containsKey(Users.MODIFIED_DATE) == false )
    values.put(Users.MODIFIED_DATE, now);
   if(values.containsKey(Users.FULL_NAME) == false )
    throw new IllegalArgumentException("Missing a full name field");
   if(values.containsKey(Users.EMAIL) == false )
    throw new IllegalArgumentException("Missing an Email field");
   if(values.containsKey(Users.BIRTHDAY_DATE) == false)
    throw new IllegalArgumentException("Missing a birthday date field");

   SQLiteDatabase db = mOpenHelper.getWritableDatabase();
   long rowId = db.insert(USERS_TABLE_NAME,Users.FULL_NAME, values);
   if (rowId > 0){
    Uri userUri = ContentUris.withAppendedId(Users.CONTENT_URI, rowId);
    getContext().getContentResolver().notifyChange(userUri, null);
    return userUri;
   }

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

 @Override
 public int delete(Uri uri, String where, String[] whereArgs) {
  SQLiteDatabase db = mOpenHelper.getWritableDatabase();
  int count;
  switch (sUriMatcher.match(uri)){
  case USERS:
   count = db.delete(USERS_TABLE_NAME, where, whereArgs);
   break;
  case USER_ID:
   String userId = uri.getPathSegments().get(1);
   count = db.delete(USERS_TABLE_NAME,
       Users._ID + "=" + userId +
       (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
       whereArgs);
   break;
  default:
   throw new IllegalArgumentException("Unknown 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 USERS:
   count = db.update(USERS_TABLE_NAME, values, where, whereArgs);
   break;
  case USER_ID:
   String userId = uri.getPathSegments().get(1);
   count = db.update(USERS_TABLE_NAME, values,
      Users._ID + "=" + userId + (!TextUtils.isEmpty(where) ?  " AND (" + where + ')' : ""),
      whereArgs);
   break;

  default: 
   throw new IllegalArgumentException("Unkown URI " + uri);
  }
  getContext().getContentResolver().notifyChange(uri, null);
  return count;
 }

}

LogCat


10-03 14:25:14.476: INFO/ActivityManager(63): Start proc alon.beginner.registerform for activity alon.beginner.registerform/.RegisterForm: pid=287 uid=10041 gids={}
10-03 14:25:14.488: INFO/AndroidRuntime(281): NOTE: attach of thread 'Binder Thread #3' failed
10-03 14:25:15.388: INFO/ARMAssembler(63): generated scanline__00000077:03545404_00000004_00000000 [ 47 ipp] (67 ins) at [0x34e7d0:0x34e8dc] in 893200 ns
10-03 14:25:15.545: INFO/ActivityThread(287): Publishing provider alon.beginner.registerform.RegistrationFormMetaData: alon.beginner.registerform.RegistrationProvider
10-03 14:25:15.623: WARN/dalvikvm(287): Exception Ljava/lang/NullPointerException; thrown during Lalon/beginner/registerform/RegistrationProvider;.
10-03 14:25:15.634: WARN/dalvikvm(287): Class init failed in newInstance call (Lalon/beginner/registerform/RegistrationProvider;)
10-03 14:25:15.634: DEBUG/AndroidRuntime(287): Shutting down VM
10-03 14:25:15.634: WARN/dalvikvm(287): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
10-03 14:25:15.660: ERROR/AndroidRuntime(287): FATAL EXCEPTION: main
10-03 14:25:15.660: ERROR/AndroidRuntime(287): java.lang.ExceptionInInitializerError
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at java.lang.Class.newInstanceImpl(Native Method)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at java.lang.Class.newInstance(Class.java:1429)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.app.ActivityThread.installProvider(ActivityThread.java:4494)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.app.ActivityThread.installContentProviders(ActivityThread.java:4281)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4237)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.app.ActivityThread.access$3000(ActivityThread.java:125)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2071)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.os.Looper.loop(Looper.java:123)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at android.app.ActivityThread.main(ActivityThread.java:4627)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at java.lang.reflect.Method.invokeNative(Native Method)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at java.lang.reflect.Method.invoke(Method.java:521)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at dalvik.system.NativeStart.main(Native Method)
10-03 14:25:15.660: ERROR/AndroidRuntime(287): Caused by: java.lang.NullPointerException
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     at alon.beginner.registerform.RegistrationProvider.(RegistrationProvider.java:45)
10-03 14:25:15.660: ERROR/AndroidRuntime(287):     ... 15 more

A: 

You have not initialized your sUsersProjectionMap data member, so it is null, so it raises a NullPointerException when you try to use it.

Change:

private static HashMap sUsersProjectionMap;

to:

private static HashMap sUsersProjectionMap=new HashMap();

Even better will be to use generics, so instead of HashMap it is HashMap<String, String> in both occurrences in the above line.

CommonsWare
thank you!, i've been trying to figure this out for hours
iandroid