I am referring Google Places photo android api.
I am using below code in onBindViewHolder of RecyclerView Adapter.
Half the time it throws Illegal State exception. Please help.
final Task<PlacePhotoMetadataResponse> photoMetadataResponse = mGeoDataClient.getPlacePhotos(placeId);
photoMetadataResponse.addOnCompleteListener(new OnCompleteListener<PlacePhotoMetadataResponse>() {
#Override
public void onComplete(#NonNull Task<PlacePhotoMetadataResponse> task) {
// Get the list of photos.
PlacePhotoMetadataResponse photos = task.getResult();
// Get the PlacePhotoMetadataBuffer (metadata for all of the photos).
PlacePhotoMetadataBuffer photoMetadataBuffer = photos.getPhotoMetadata();
// Get the first photo in the list.
PlacePhotoMetadata photoMetadata = photoMetadataBuffer.get(0);
// Get the attribution text.
CharSequence attribution = photoMetadata.getAttributions();
// Get a full-size bitmap for the photo.
Task<PlacePhotoResponse> photoResponse = mGeoDataClient.getPhoto(photoMetadata);
photoResponse.addOnCompleteListener(new OnCompleteListener<PlacePhotoResponse>() {
#Override
public void onComplete(#NonNull Task<PlacePhotoResponse> task) {
PlacePhotoResponse photo = task.getResult();
Bitmap bitmap = photo.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
Glide.with(mContext)
.load(stream.toByteArray())
.asBitmap()
.error(R.drawable.cast_album_art_placeholder)
.centerCrop()
.thumbnail(.2f)
.into(holder.placeImage);
}
});
}
});
StackTrace :
E/UncaughtException: java.lang.IllegalStateException
at com.google.android.gms.common.internal.zzbp.zzbg(Unknown Source)
at com.google.android.gms.common.data.zzc.zzbu(Unknown Source)
at com.google.android.gms.common.data.zzc.<init>(Unknown Source)
at com.google.android.gms.location.places.internal.zzav.<init>(Unknown Source)
at com.google.android.gms.location.places.internal.zzar.<init>(Unknown Source)
at com.google.android.gms.location.places.PlacePhotoMetadataBuffer.get(Unknown Source)
Even if thi issues is almost one year old and since the given answer didn't solve my error, I'll share my solution:
// Get the first photo in the list.
if (photoMetadataBuffer.getCount() > 0) {
PlacePhotoMetadata photoMetadata = photoMetadataBuffer.get(0);
// continue with your code
}
This, because the photoMetadataBuffer isn't null.
But yes, the error happens only for places without pictures.
I am fairly certain that the issue is that your application is crashing due to the fact that you are attempting to retrieve a photo from a location that does not have a photo to display. You must do a null check before attempting to retrieve the first photo in your photoMetadataBuffer.get(0). This is a good example of how Google's documentation is somewhat incomplete from the example code that is provided. You should have something like the following:
// Get the first photo in the list.
if (photoMetadataBuffer != null) {
PlacePhotoMetadata photoMetadata = photoMetadataBuffer.get(0);
// continue with your code
}
If the photoMetadataBuffer is null, then there isn't a photo to be displayed and you can handle your application logic appropriately, such as loading a default image, giving feedback to the user, or not displaying the ImageView.
Related
I can't seem to get the url, from the PlacePhotoMetadata object. Debugger shows that there is an URL there but I can't seem to access it.
How do you access the URL in the object?
val placeId = "ChIJa147K9HX3IAR-lwiGIQv9i4"
val photoMetadataResponse = mGeoDataClient.getPlacePhotos(placeId)
photoMetadataResponse.addOnCompleteListener { task ->
// Get the list of photos
val photos = task.result
// Get the PlacePhotoMetadataBuffer (metadata for all of the photos)
val photoMetadataBuffer = photos.photoMetadata
// Get the first photo in the list
for (photo in photoMetadataBuffer) {
// Get the attribution text
val attribution = photo.attributions
}
}
You can't. Take a look at the documentation for PlacePhotoMetadata. There are methods to download a bitmap of the image, but no methods that return the URL.
To get the photo you should do something like this:
// this is your for-loop:
photoMetadataBuffer.forEach { photo ->
photo.getPhoto(client).setResultCallback({ result ->
// do whatever you want here:
showPhotoWithAttribution(photo.attributions, result.getBitmap())
})
}
Note that replacing a for-loop with a forEach call has no real advantage, it just makes your code look cleaner.
I'm trying to get a photo from known placeID location ("ChIJqaUj8fBLzEwRZ5UY3sHGz90").
I'm using the code below (from the google guide)
PlacePhotoMetadataResult result = Places.GeoDataApi.getPlacePhotos(mGoogleApiClient, placeId).await();
if (result.getStatus().isSuccess()) {
PlacePhotoMetadataBuffer photoMetadataBuffer = result.getPhotoMetadata();
if (photoMetadataBuffer.getCount() > 0 && !isCancelled()) {
// Get the first bitmap and its attributions.
PlacePhotoMetadata photo = photoMetadataBuffer.get(0);
CharSequence attribution = photo.getAttributions();
// Load a scaled bitmap for this photo.
Bitmap image = photo.getScaledPhoto(mGoogleApiClient, mWidth, mHeight).await()
.getBitmap();
attributedPhoto = new AttributedPhoto(attribution, image);
}
// Release the PlacePhotoMetadataBuffer.
photoMetadataBuffer.release();
}
the result.getStatus returns a success, but PhotoMetadataBuffer is returned empty (photoMetadataBuffer.getCount = 0).
Has anyone successfully got an image using this method?
It looks like there aren't any photos associated with this place at the moment. If you try another place id that has associated photos, you should get some results. For example, try this place id:
ChIJN1t_tDeuEmsRUsoyG83frY4
I'm completely lost on this Facebook API for Android, BECAUSE THE DOCUMENTATION IS HORRIBLE!!
Even when I copy their examples to the character, (ammending to fit my app) it still doesn't work!
I have attached to my share button:
Session session = Session.getActiveSession();
if (session.isOpened()) {
OpenGraphAction action = GraphObject.Factory.create(OpenGraphAction.class);
action.setProperty("meal", "https://example.com/cooking-app/meal/Lamb-Vindaloo.html");
action.setType("feed");
Bitmap bitmap;
if (hasIcon) {
bitmap = ((BitmapDrawable)recipeIcon.getDrawable()).getBitmap();
} else {
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_special_rosemary);
}
List<Bitmap> images = new ArrayList<Bitmap>();
if (bitmap != null) {
Log.d("image!", bitmap.getByteCount() + "");
images.add(bitmap);
FacebookDialog shareDialog = new FacebookDialog.OpenGraphActionDialogBuilder(this, action, "meal")
.setImageAttachmentsForAction(images, true)
.build();
uiHelper.trackPendingDialogCall(shareDialog.present());
} else {
Log.d("no image", "");
FacebookDialog shareDialog = new FacebookDialog.OpenGraphActionDialogBuilder(this, action, "meal")
.build();
uiHelper.trackPendingDialogCall(shareDialog.present());
}
This goes through all fine, even the Log tells me the Bitmap is there, is not null, and contains a byteCount of ~160kb, but when I attach it to the share dialog it comes up with this...
01-21 00:39:30.214: E/Activity(2214): Error: com.facebook.FacebookException: Error retrieving image attachment.
What?! Is it not attaching correctly? Well, it mustn't be but this is the example copied direct from their documentation and it doesn't work! I only want to upload the current image. Poor show
Please see the reference docs for the method you're calling - https://developers.facebook.com/docs/reference/android/current/class/FacebookDialog.OpenGraphActionDialogBuilder/#setImageAttachmentFilesForAction
"In order for the images to be provided to the Facebook application as part of the app call, the NativeAppCallContentProvider must be specified correctly in the application's AndroidManifest.xml."
In NativeappCallContentProvider - https://developers.facebook.com/docs/reference/android/current/class/NativeAppCallContentProvider/ - you'll see that you need to add com.facebook.app.NativeAppCallContentProvider{FACEBOOK_APP_ID} to your manifest.
I'm trying to get the profile images of my followers for use within a ListView as thumbnails.
These thumbnails are around 125x125, but the standard twitter4j call of User.getProfileImageURL(); returns much smaller size of 48x48 and is also recommended to not be used as the image source.
I've tried creating a ProfileImage object and supplying it as a parameter, User.getProfileImageURL(profile image object.Original),
But this code takes some time to simply retrieve the url, which when loading a list of thumbnails, is inefficient.
Any suggestions on how to go about this?
Edit
Twitter API v1 has been disabled, so my old answer is no longer valid. Refer to API v1.1, which I believe requires authentication.
If you know the screen name, the twitter api allows for you to fetch the profile image at 4 different resolutions;
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=mini
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=normal
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=bigger
https://api.twitter.com/1/users/profile_image?screen_name=Krylez&size=original
The "bigger" image is 73x73, which is going to interpolate in your 125x125 container. If you're not okay with this, you can try to fetch the "original" photo, but this photo could be very large (slow) and it's not necessarily a square.
Whatever method you choose, make sure you're not fetching and/or decoding Bitmaps on the UI thread. The Android API documentation has excellent guidelines for the correct way to do this.
Also we can make use of the Twitter4j using:
mTwitter.getUserProfileImage();
From the official doc:
You can obtain a user’s most recent profile image from GET users/show. Within the user object, you’ll find the profile_image_url
and profile_image_url_https fields. These fields will contain the
resized “normal” variant of the user’s uploaded image. This “normal”
variant is typically 48x48px.
By modifying the URL, you can retrieve other variant sizings such as
“bigger”, “mini”, and “original”.
Following the code:
TwitterApiClient twitterApiClient = TwitterCore.getInstance().getApiClient();
twitterApiClient.getAccountService().verifyCredentials(false, false, new Callback<User>() {
#Override
public void success(Result<User> userResult) {
String name = userResult.data.name;
String email = userResult.data.email;
// _normal (48x48px) | _bigger (73x73px) | _mini (24x24px)
String photoUrlNormalSize = userResult.data.profileImageUrl;
String photoUrlBiggerSize = userResult.data.profileImageUrl.replace("_normal", "_bigger");
String photoUrlMiniSize = userResult.data.profileImageUrl.replace("_normal", "_mini");
String photoUrlOriginalSize = userResult.data.profileImageUrl.replace("_normal", "");
}
#Override
public void failure(TwitterException exc) {
Log.d("TwitterKit", "Verify Credentials Failure", exc);
}
});
For further information refer to Twitter API Documentation | Profile Images and Banners
To create a custom size pic, for example 90x90 you can use the createScaledBitmap() method.
private final int PROFILE_PIC_SIZE = 90;
Bitmap originalPic = null;
Bitmap resizedPic = null;
try {
InputStream in = new java.net.URL(photoUrlOriginalSize).openStream();
originalPic = BitmapFactory.decodeStream(in);
resizedPic = Bitmap.createScaledBitmap(originalPic, PROFILE_PIC_SIZE, PROFILE_PIC_SIZE, false);
} catch (Exception exc) {
Log.e("Error", exc.getMessage());
exc.printStackTrace();
}
You can use getOriginalProfileImageURL() for example. This is as large as it gets.
Smaller ones are getBiggerProfileImageURL() and getProfileImageURL().
These are the urls you retrieve:
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD_normal.jpeg
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD_bigger.jpeg
http://pbs.twimg.com/profile_images/NUMBER/c62p-cAD.jpeg
I am using this code to download a profile picture (https://graph.facebook.com/19292868552/picture) from Facebook using the Android Facebook SDK:
asyncFacebookRunner.request("19292868552" + "/picture", new BaseRequestListener() {
#Override
public void onComplete(String response, Object state) {
System.out.println(response);
byte[] imageBytes = response.getBytes();
Bitmap bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
System.out.println(bitmap);
}
#Override
public void onException(Exception ex) {
}
});
The problem is, that the bitmap is null. This is the logcat:
11-10 20:15:56.540: I/System.out(20930): ������JFIF����������������;CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 95����C�� ����C������2��2"�������������������������� �����������}��!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������������������������������������������������������������������������������������������� ���������w��!1AQaq"2�B���� #3R�br�$4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������������?������{���(�B�K#UQ�$��l�?�^�/��τV�x�TL�j�X�}A����!��_�u�����f���ɨxW����A9�O����&`É�c��$���G��O���G����=�7;b'���8�F�OZ��xS�������Q�u����Yy�3�f�=GF���_�c뿊�V�3�~�{��7>6���H-"�%�������7�#��1S�e���kS���ߦ]���m�J�O�۴� T0�rJ�V��MX�?g���I�_c��λg����jJ$Dtr�mmFK����`�N�+̾.��_���ioK�/�����e�����y$y��|���9���?P�V�<=v��[z+uQ�C��zШ��{�^���/�*���H��woc>��[LM��F�bu$��P����Gב][M#���Ċ� S�p}8#�������.?fOY�y��_��Ki&����,v�:23q��`1�O85�����������NxSO�_�]F8����z�w31��[��Edl�ʱ�|�k��NUprQ�cv��ڻ~���S��g��ɷ��'o�W���=��QFW��������~���}������,��Uԫ���$�'�5�ľ�.���S3Aye;G$g)є��k��s�w���v�O��?�tԫ���t^c��_��oG�1�?�_����Z��~��G����]G��V��Wx��/�_0��P��O"67���$�_{>Z��^r>���i�>�"�>�t+I%�d���J��˕y$?<�;�B�W���$��=4��?�Y�������4߉��x[�M݆��M�Q��[<� A�7d��^�,e9�o���h��)RN�yw������������+�;"����h�'�4M7���^��� ��1�!`��P�G���ƖD�о��v��K?��5�I���������_��.�.����fQ��R���$�bc���v.���$�{~Ǻq�㧁�+�|g�����yeW6�q�$��$���վ���,e:Q]V��^���D�ޯ�ڊ8��h�ď�������.G�����7A�~j�چ��t���0��;��đN�f��F��0�ߞ+��9����9�<���9�[��qab����p�8��8����_�,���)YP�+¿m��y�����Ho��Y��۷�y������r�ڤ��6�ܭ�_a��^#N�����+�[}�߿K�>3*�^n�>7��Ƙ��_O�i���_u����h���㧅,��1j�^9�H�յij�ƞ�7v�$��%�##Q��2p0{?�+G��?���&��~��-j][7"ԣO��3[�w_1�2�#)�{h��!�����>1|E����o��rt_kZN��j�jb�%��H���$��s�Fp9�����s\��I4��֭'�v�եe��>s��zPK�R����+�U�wt�OW���+1s!���8��ز��������������<[�O�I���4M7V��Y�(H��G*Ɉ��v������_�~)����Gč3⿍�%g{�i_f��O0[)r䪟�>O��Gb+����,b�ª����+��u\GO����Ԥ����
11-10 20:15:56.540: D/skia(20930): --- SkImageDecoder::Factory returned null
11-10 20:15:56.540: I/System.out(20930): null
How can I get a bitmap to show in an ImageView?
Everything looks correct to me, you also get input as the print shows. I found an another examplehere for user picture. The example uses Url and inputstream indstead of byte array, maybe that would work for you.
Using the new Facebook SDK this problem doesn't occur anymore.