Search code examples
androidimagecontactslistadapterfilenotfoundexception

How to Control BitmapFactory FileNotFoundException with ListAdapter


I'm making an Activity where I show the contact list of the phone by their names and their photos. I use a Cursor and a Managedquery with a ListAdapter to adapt everything to a layout.

It works nice, but I see in Logcat an error related with those who don't have picture and I'd like to control them, showing the android default no-photo icon but I haven't found a way to do it.

Here is an example:

Example of the contact list generated

The blue blur are the names. Hidden to preserve their identities :P

Here's the code:

Contactos.java

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contactos);

        //Llamamos función para conseguir todos los contactos.
        Cursor cursor = getContacts();
        startManagingCursor(cursor);
        // Llenamos la ListView con los contactos del teléfono
        try {
            ListAdapter infoContacto = new SimpleCursorAdapter(this,R.layout.contacto,
                    cursor,new String[] {ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,ContactsContract.Contacts.DISPLAY_NAME},
                    new int[] {R.id.foto, R.id.nombreContacto}, 0);
            setListAdapter(infoContacto);
        }catch(Exception e){
            Log.d("Excepcion",e.toString());
        }

    }
private Cursor getContacts() {
            Uri contacto = ContactsContract.Contacts.CONTENT_URI;
            /* Seleccionamos la información que necesitamos. ID SIEMPRE NECESARIO. */
            String[] projection = new String[] {ContactsContract.Contacts._ID,ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,ContactsContract.Contacts.DISPLAY_NAME};
            /* Los ordenamos por nombre */
            String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP;
            String[] selectionArgs = null;
            String ordenarPorNombre = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
            /* Devolvemos los contactos */
            return managedQuery(contacto, projection, selection, selectionArgs,
                    ordenarPorNombre);
     }

Logcat

06-08 23:50:41.429: E/BitmapFactory(20808): Unable to decode stream: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)
06-08 23:50:41.429: I/System.out(20808): resolveUri failed on bad bitmap uri: 
06-08 23:50:41.439: E/BitmapFactory(20808): Unable to decode stream: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)
06-08 23:50:41.439: I/System.out(20808): resolveUri failed on bad bitmap uri: 
06-08 23:50:41.469: E/BitmapFactory(20808): Unable to decode stream: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)
06-08 23:50:41.469: I/System.out(20808): resolveUri failed on bad bitmap uri: 
06-08 23:50:41.479: E/BitmapFactory(20808): Unable to decode stream: java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)

I guess I should put an if statement somewhere before the projection definition to check if is a valid URI or file and not a directory, but how and where?

And one last question, should I use the current method or better change it to a getContentResolver().query(blablabla...)??

Thanks for your time.


Solution

  • To specify contacts image for those that have none on the phone, you will need to setViewBinder() method of your SimpleCursorAdapter and check if image is null, then place default no-photo image (only Image I can find in Android system resources is android.R.drawable.ic_contact_picture shown below)

    enter image description here

    Regarding your last question, I think it will not make much difference (your code is already working). But if you will edit the contact data, I think you will have to use a ContentResolver.