Search code examples
androidsqlitecursorcontacts

Android lollipop error: Null pointer exception while trying to read phone contcats


I have got the following error while trying to read phone contact in Nexus 5(updated to lollipop) only.

java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToNext()' on a null object reference
at mycomp.android.ui.fragments.DirectoriesFragment.readContacts(SourceFile:595)
at mycomp.android.ui.fragments.DirectoriesFragment.processOneDirectory(SourceFile:744)
at mycomp.android.ui.fragments.DirectoriesFragment.onLoadFinished(SourceFile:722)
at mycomp.android.utils.RESTLoaderFragment.onLoadFinished(SourceFile:1)
at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:483)
at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:451)
at android.content.Loader.deliverResult(Loader.java:144)
at mycomp.android.utils.loader.RESTLoader.deliverResult(SourceFile:322)
at mycomp.android.utils.loader.RESTLoader.deliverResult(SourceFile:1)
at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:265)
at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:92)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

i am using following code to retrieve contacts from phone

private void readContacts() {
        ContentResolver cr = getActivity().getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
                null, null, null);
        Cursor c = null ;
        Cursor pCur = null;
        try {

            String phone = null;

            if (cur.getCount() > 0) {
                while (cur.moveToNext()) {
                    try {
                        DirectoryRecordEntry entry = null;

                        String id = cur.getString(cur
                                .getColumnIndex(ContactsContract.Contacts._ID));
                        String name = cur
                                .getString(cur
                                        .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                        int idIndex = cur.getColumnIndexOrThrow(Contacts._ID);
                        long ids = cur.getLong(idIndex);
                        Uri rawContactUri = ContentUris.withAppendedId(
                                RawContacts.CONTENT_URI, ids);

                        Uri entityUri = Uri.withAppendedPath(rawContactUri,
                                Entity.CONTENT_DIRECTORY);

                        c= getActivity().getContentResolver().query(entityUri,
                                new String[]{

                                RawContacts.SOURCE_ID}, null, null, null);
                        String source_id = "";

// Getting null pointer exception here, c is null :(

                    while (c.moveToNext()) {
                        source_id = c.getString(0);
                    }


                        if (Integer
                                .parseInt(cur.getString(cur
                                        .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                            if (source_id != null && source_id.length()>0) {
                                entry = new OutlookContactEntry(name, "");
                            } else {
                                entry = new PhoneNumberEntry(name, "");
                            }

                            pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                            null,
                                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                                    + " = ?", new String[]{id},
                                            null);
                            while (pCur.moveToNext()) {
                                try {
                                    phone = pCur
                                            .getString(pCur
                                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                                    int phoneType = pCur
                                            .getInt(pCur
                                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                                    if (entry instanceof OutlookContactEntry) {
                                        OutlookContactEntry oEntry = (OutlookContactEntry) entry;
                                        oEntry.addContact(getType(phoneType), phone);
                                    } else {
                                        entry.getPhNumberList().add(phone);
                                    }

                                } catch (Exception e) {
                                     Log.e(CLASS_NAME, "Error in retrieving contacts from phone",e);
                                }

                            }


                        }
                        if (entry != null) {
                            if (entry instanceof OutlookContactEntry) {
                                OutlookContactEntry oEntry = (OutlookContactEntry) entry;
                                List<String>  list =new ArrayList<String>(oEntry.getContacts().values());
                                if(!list.isEmpty()){
                                    entry.setNumber(list.get(0));
                                }

                            }else{
                                if(!entry.getPhNumberList().isEmpty()){
                                entry.setNumber(entry.getPhNumberList().get(0));
                                }
                            }


                            objListRowRecord.put(name, entry);
                        }
                    } catch (Exception e) {
                         Log.e(CLASS_NAME, "Error in retrieving contacts from phone",e);
                    }

                }

            }

        } catch (Exception e) {
             Log.e(CLASS_NAME, "Error in retrieving contacts from phone",e);

        }finally
        {
            try {
                if(pCur!=null){
                    pCur.close();   
                }
                if(c!=null){
                    c.close();  
                }
                if(cur!=null){
                    cur.close();    
                }
                cr=null;
            } catch (Exception e) {
                 Log.e(CLASS_NAME, "Error closing cursor",e);
            }
        }

    }

i have encountered this problem only after updating the kitkat to lollipop

It can be resolved by a null check but i really want to know the reason behind it.

Any help would be appreciated

Thanks

Amith


Solution

  • The documentation of ContentResolver.query() says:

    Returns
    A Cursor object, which is positioned before the first entry, or null

    It returns null because it is allowed to do so.

    You always need a null check when querying a content resolver.