Android lollipop error: Null pointer exception whi

2019-09-08 05:34发布

问题:

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

回答1:

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.



回答2:

/**
 * This method is to read contacts.
 */
public void readContacts() {
localPhTempList.clear();
ContentResolver cr = activity.getContentResolver();
Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
String phone = null;
Cursor c = null;
Cursor pCur = null;

try {
    if (cur != null && 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 = activity.getContentResolver().query(entityUri, new String[] {

        RawContacts.SOURCE_ID }, null, null, null);
        String source_id = "";
        if (c != null) {
            while (c.moveToNext()) {
            source_id = c.getString(0);
            }

        }
        if (c != null) {
            c.close();
        }

        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, "-1");
            } else {
            entry = new PhoneNumberEntry(name, "-2");
            }

            pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " ='"
                + id + "'", null, null);

            if (pCur != 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;
                    String names = getType(phoneType);
                    String number = phone;
                    if (names != null && names.length() > 0 && number != null && number.length() > 0
                    /*
                     * && !number.equalsIgnoreCase("-1")
                     * && !number.equalsIgnoreCase("-1")
                     */) {
                    oEntry.addContact(names, number);
                    }

                } else {
                    entry.getPhNumberList().add(phone);
                }

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

            }
            if (pCur != null) {
                pCur.close();
            }
            }

        }
        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);
            if (!(entry.getNumber().equalsIgnoreCase("-1") || entry.getNumber().equalsIgnoreCase("-2"))) {

            localPhTempList.add(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();
        pCur = null;
    }
    if (c != null) {
        c.close();
        c = null;
    }
    if (cur != null) {
        cur.close();
        cur = null;
    }

    cr = null;
    } catch (Exception e) {
    Log.e(CLASS_NAME, "Error closing cursor", e);
    }
}

}


回答3:

Always do a 

Cursor cursor = query();//Your Custom Query Method
if(cursor != null){

//Iterate

for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
//Get cursor values
}

if(!cursor.isClosed()){cursor.close();}
}