5

Sto provando a caricare una foto di contatto con URI "content: //com.android.contacts/contacts/295" usando Glide.Come caricare un URI con prefisso "content: //" usando Glide Android?

Quando uso

Glide.with(context).load(Uri.parse(contactPhoto).into(imageview) 

Glide mi dà una FileNotFoundException

java.io.FileNotFoundException: File does not exist; URI: content://com.android.contacts/contacts/264, calling user: android.uid.shared:10006, calling package is one of: [com.android.providers.contacts, com.android.contacts, com.android.providers.userdictionary] 
     at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146) 
     at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:689) 
     at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1080) 
     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:921) 
     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:848) 
     at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:21) 
     at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:14) 
     at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44) 
     at com.bumptech.glide.load.model.ImageVideoModelLoader$ImageVideoFetcher.loadData(ImageVideoModelLoader.java:83) 
     at com.bumptech.glide.load.model.ImageVideoModelLoader$ImageVideoFetcher.loadData(ImageVideoModelLoader.java:53) 
     at com.bumptech.glide.load.engine.DecodeJob.decodeSource(DecodeJob.java:170) 
     at com.bumptech.glide.load.engine.DecodeJob.decodeFromSource(DecodeJob.java:128) 
     at com.bumptech.glide.load.engine.EngineRunnable.decodeFromSource(EngineRunnable.java:122) 
     at com.bumptech.glide.load.engine.EngineRunnable.decode(EngineRunnable.java:101) 
     at com.bumptech.glide.load.engine.EngineRunnable.run(EngineRunnable.java:58) 
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
     at java.lang.Thread.run(Thread.java:818) 
     at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:52) 

Ovviamente Glide cerca di ottenere l'immagine dal posto sbagliato.

Sarei grato se qualcuno mi indichi come caricare una foto con URI "content: //".

+0

https://github.com/bumptech/glide/issues/394 – TWiStErRob

risposta

0

Per questo è necessario utilizzare un ContentResolver.

ContentResolver contextResolver = context.getContentResolver(); 
Uri uri = Uri.parse("content://com.android.contacts/contacts/295"); 
Bitmap thumbnail = null; 
Cursor cursor = contentResolver.query(uri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null); 

try { 
    if (cursor.moveToFirst()) { 
     final byte[] thumbnailBytes = cursor.getBlob(0); 
     if (thumbnailBytes != null) { 
      thumbnail = BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length); 
     } 
    } 
} 
finally { 
    cursor.close(); 
} 

if (thumbnail != null) { 
    imageView.setImageBitmap(thumbnail); 
} 

Prova questo. Questo dovrebbe funzionare.

+0

Si lo so che c'è un metodo chiamato openContactPhotoInputStream. Ma quello recupera la foto nel thread principale e sto chiamando il codice Glide in un adapter e voglio che maneggi l'immagine in un thread in background. –

+0

Non ho usato questo metodo perché non funziona sotto l'API 14. E non vedo il problema qui; Glide non può essere più veloce delle classi del framework nativo. Inoltre, Glide non garantisce di gestire alcun 'Uri' automaticamente. –

+0

Ottiene 'java.lang.IllegalArgumentException: dati colonna15 non validi che sono correlati a' public final static String PHOTO = DATA15'. Utilizzo dell'API 21. –

1

Sembra che Glide non gestisca automaticamente le foto dei contenuti Uri.

Quindi ho risolto il problema utilizzando un approccio RxJava.

Ecco un metodo che emette un bitmap (Si prega di notare l'utilità di pianificazione in quanto è importante non essere in ritardo le prestazioni di scorrimento)

private Observable<Bitmap> _getConvertInputStreamToBitmapObservable(ContentResolver cr, 
                    Uri contactUri) { 
    return Observable.create(new Observable.OnSubscribe<Bitmap>() { 
     @Override 
     public void call(Subscriber<? super Bitmap> subscriber) { 
      InputStream inputStream = 
        ContactsContract.Contacts.openContactPhotoInputStream(cr, contactUri); 
      if (inputStream != null) { 
       Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
       subscriber.onNext(bitmap); 
      } 
      subscriber.onCompleted(); 
     } 
    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()); 
} 

Ed ecco il codice client che utilizza il metodo (Si prega di notare l'annullamento dell'iscrizione come è importante nel riciclaggio).

 if (holder.bitmapSubscription != null) { 
      holder.bitmapSubscription.unsubscribe(); 
     } 

     holder.bitmapSubscription = _getConvertInputStreamToBitmapObservable(context.getContentResolver(), 
       contactUri) 
       .subscribe(holder.userImg::setImageBitmap); 
2

È necessario creare un caricatore personalizzato che utilizza ContentResolver. Ad esempio, in Picasso funziona perché c'è already a custom request handler che utilizza ContentResolver.

Ho creato uno personalizzato Glide loader for contacts for my internal use che è possibile prendere come riferimento.

+2

Grazie per la tua risposta, ho già inviato una richiesta pull a Glide che implementa questa funzionalità in modo nativo, penso che presto verrà unita. https://github.com/bumptech/glide/pull/1119 –

+0

@ AhmedI.Khalil Potresti pubblicare un esempio? – Mussa

+2

https://github.com/bumptech/glide/issues/394 La richiesta di funzione è ora risolta e verrà rilasciata con v3.8.0 in Glide. Dovrai aspettare la v3.8.0 o includere il codice sorgente Glide (ramo v3.0) come dipendenza nel tuo progetto e dare un'occhiata a questo esempio che ho scritto. https://github.com/bumptech/glide/blob/3.0/samples/contacturi/src/main/java/com/bumptech/glide/samples/contacturi/MainActivity.java –

-1
Uri uri = 
    ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new 
    Long(contactsPojo.getId())); 
      final Uri displayPhotoUri = Uri.withAppendedPath(uri, 
        ContactsContract.Contacts.Photo.DISPLAY_PHOTO); 
      Glide.with(context) 
        .load(displayPhotoUri) 
        .placeholder(R.mipmap.ic_launcher) 
        .error(R.mipmap.ic_launcher) 
        .fallback(R.mipmap.ic_launcher) 
        .diskCacheStrategy(DiskCacheStrategy.ALL) 
        .into(holder.image); 
Problemi correlati