5

Ich versuche, ein Kontaktfoto mit URI "content: //com.android.contacts/contacts/295" mithilfe von Glide zu laden.Wie lade ich einen URI mit dem Präfix "content: //" mit Glide Android?

Wenn ich

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

Glide gibt mir eine 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) 

Offensichtlich versucht Glide das Bild von der falschen Stelle zu bekommen.

Ich würde mich freuen, wenn mir jemand zeigen würde, wie man ein Foto mit "content: //" URIs lädt.

+0

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

Antwort

0

Sie müssen dafür einen ContentResolver verwenden.

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); 
} 

Versuchen Sie dies. Das sollte funktionieren.

+0

Ja, ich weiß, dass es eine Methode ist openContactPhotoInputStream genannt. Aber das würde das Foto im Hauptthread abrufen, und ich rufe den Glide-Code in einem Adapter und möchte, dass es das Bild in einem Hintergrundthread erhält. –

+0

Ich habe diese Methode nicht verwendet, da sie nicht unter API 14 funktioniert. Und ich sehe das Problem hier nicht; Glide kann nicht schneller sein als die nativen Framework-Klassen. Außerdem garantiert Glide nicht, automatisch mit 'Uri' umzugehen. –

+0

Ich bekomme 'java.lang.IllegalArgumentException: Ungültige Spalte data15', die sich auf' public static final String PHOTO = DATA15' bezieht. Mit API 21. –

1

Scheint, dass Glide Inhalt Fotos Uri nicht automatisch behandelt.

Also habe ich mein Problem mit einem RxJava Ansatz gelöst.

Hier ist eine Methode, die eine Bitmap (Bitte beachten Sie den Scheduler, da es wichtig ist, um die Scroll-Leistung nicht zurückzubleiben) emittiert

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()); 
} 

Und hier ist der Client-Code, der die Methode (Bitte beachten Sie die Abbestellen verwendet wie es im Recycling wichtig ist).

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

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

Sie müssen einen benutzerdefinierten Loader erstellen, der einen ContentResolver verwendet. In Picasso zum Beispiel funktioniert das, weil es already a custom request handler gibt, die einen ContentResolver verwendet.

Ich habe eine benutzerdefinierte Glide loader for contacts for my internal use erstellt, die Sie als Referenz nehmen können.

+2

Danke für Ihre Antwort, ich habe bereits eine Pull-Anfrage an Glide gesendet, die diese Funktion nativ implementiert, ich denke, dass es bald zusammengeführt wird. https://github.com/bumptech/glide/pull/1119 –

+0

@ AhmedI.Khalil Könnten Sie bitte ein Beispiel veröffentlichen? – Mussa

+2

https://github.com/bumptech/glide/issues/394 Die Feature-Anfrage ist jetzt gelöst und wird in Glide mit Version 3.8.0 veröffentlicht. Sie müssen entweder auf v3.8.0 warten oder Sie können den Glide-Quellcode (Zweig v3.0) als eine Abhängigkeit in Ihr Projekt aufnehmen und sich dieses Beispiel ansehen, das ich geschrieben habe. 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);