0

I will try to explain this as best I can. (I'm still new with both Java and Android)

Issue:

I am trying to compare an incoming number string to a Contact object's number string by searching the arrayList.

Background:

I am able to load Contacts from an arrayList into different views (ListView, textView, etc) so I know the methods and objects are working. It's this new class (RingerService) that I'm having the issue with.

Design

I have an arrayList of contacts in a class named contactStorage. It works as intended for displaying different views:

//constructor with context to access project resources and instantiate from JSONfile to arrayList 
private ContactStorage(Context appContext){
    mAppContext = appContext;
    mSerializer = new ContactJSONer(mAppContext, FILENAME);
    
    try{
        mContacts = mSerializer.loadContacts();
    }catch (Exception e){
        mContacts = new ArrayList<Contact>();
        Log.e(TAG, "No contacts available, creating new list: ", e);
    }
}

//get method to only return one instance from the constructor
public static ContactStorage get(Context c){
    if (sContactStorage == null){
        sContactStorage = new ContactStorage(c.getApplicationContext());
    }
    return sContactStorage;
}

//for ringer service to find matching number
public Contact getContactNumber(String number){
    for (Contact c: mContacts){
        if(c.getNumber().replaceAll("[^0-9]", "").equals(number))
            return c;
    }
    return null;
}

when I call the get method above in the RingerService class below, that's when things break. To be specific, I am getting a NullPointerException on onCallStateChanged:

 private Contact mContact;
private String number;
private Context mContext;

    @Override
   public void onCreate(){
       mTelephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
       mPhoneStateListener = new PhoneStateListener(){
           // state change 
           @Override
           public void onCallStateChanged(int state, String incomingNumber){
               if (state == 1 ){ 
                   try{
                        mContact = ContactStorage.get(mContext).getContactNumber(incomingNumber);
                        number = mContact.getNumber();
                        Log.d(TAG, state+" received an incoming number: " + number);
                    }catch(Exception e){
                        Log.d(TAG, " exception: " + e);
                    }
               } else {
                   Log.d(TAG, state+" number not found" + incomingNumber);
               }
           }   
       };
       super.onCreate();
   }

Troubeshooting:

1. I've removed the reference to number (number = mContact.getNumber();) - the program runs fine in that case. I can send a test call to the emulator and the log message displays correctly with the test number arg. I considered it could be the way in which the array searching works in getContactNumber class. Is it never finding a matching value, resulting in null?

2. I also thought that since this is a service, I'm somehow not getting the right context when calling the ContactStorage.get(Context c) method.

3. if I set my mContact reference and no number match was found, would mContact = null; still let the program run?

4
  • Since getContactNumber can potentially return null and then you turn right around and call mContact.getNumber() where mContact is the return of getContactNumber ... thats a NullPointerException waiting to happen. Commented Jun 20, 2014 at 3:55
  • 1
    Did you initialize your context (mContext) anywhere?. I feel like your context is null. Debug and check. Commented Jun 20, 2014 at 4:42
  • 1
    possible duplicate of What is a Null Pointer Exception, and how do I fix it? Commented Jun 20, 2014 at 7:05
  • The reason I used getApplicationContext() in ContactStorage was that I expected to use the model data in multiple areas, application wide (Activities, fragments, services). Since service is a context, could I simply set Context mContext = RingerService(this) to directly access it? Commented Jun 20, 2014 at 16:51

2 Answers 2

4

You are trying to match strings with == in c.getNumber() == number which will check if two objects reference are equals

Use c.getNumber().equals(number)

Sign up to request clarification or add additional context in comments.

4 Comments

Is the number you are trying to match is in the list mContacts? If not then you will have to handle mContact being null case in the code
@Aniruddha for (Contact c: mContacts){ if (c.getNumber() == number) return c; } return null; returns null everytime as its doing reference equally
@Pallavi didn't see that return null before. Sorry
I tried using a number that I knew was already on one of the contact objects, but in a real world scenario something like a try, catch exception block would be better.
0

Thanks for the suggestions. It turns out that when testing an incoming phone call in Eclipse to an emulator device, the GUI field only takes numerics without spaces or hyphens: (1112221122)

Since my contact objects' number field is getting assigned through android's CONTACT_URI, the format is saved as a string (###) ###-####. This will never match, causing the nullPointerException error. I updated the getContactNumber method to replace this formatting for the long string of numbers for any potential match.

I then added a catch for any RuntimeException on the RingerService method. All is working now.

Out of curiosity, does anyone know the format for real incoming phone numbers?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.