1

I am trying to get the album's cover photo url using the Facebook sdk.

I am looking at how to query it here, but, I'm confused as to how to handle it in the response.

This is what I've got thus far:

      public void getAlbumCoverPhoto(String id){

    Bundle params = new Bundle();
    params.putString("type", "small"); //You use this to get a pre-specified size of picture.
    params.putBoolean("redirect", false);
    new GraphRequest(
            AccessToken.getCurrentAccessToken(),
            "/" + id + "/picture",
            params,
            HttpMethod.GET,
            new GraphRequest.Callback() {
                public void onCompleted(GraphResponse response) {

                    try {
                        if (response.getError() == null) {
                            JSONObject joMain = response.getJSONObject();
                            if (joMain.has("data")) {

                             System.out.println(joMain);
                              //How can I get the photo source from here?
                            }

                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }).executeAsync();

}

But it doesn't seem to be doing anything when I'm trying to handle the Graph Response in the onCompleted method.

How can I handle the response properly so I can get the cover photo for the particular album I am querying. Thank you.

Jack
  • 2,043
  • 7
  • 40
  • 69
  • First of all, you need to _ask_ for the `cover_photo` field using the `fields` parameter. – CBroe Mar 10 '16 at 12:06
  • I would suggest you to use this library for getting cover photo and may more.. It provides many way. try this: https://github.com/sromku/android-simple-facebook – Nitesh Mar 10 '16 at 12:41
  • 1
    @NiteshKumar I've tried this before and it's poorly documented. Lots of other people want to know how they can retrieve the cover photo urls etc with that library if you read the "issues tab" and none of them seem to be addressed. – Jack Mar 10 '16 at 12:43
  • @CBroe I've updated the question with what I've amended my code to. My code now returns the correct information in the response but I don't know how to get the photo source(the direct url). I'm going to keep on looking, but, if you could give me some guidance that would be extremely useful. – Jack Mar 10 '16 at 13:40
  • 1
    The url is included by default when you ask for the "picture" edge. If you aren't getting it, you can try specifically requesting the field by using `"/" + id + "/picture?fields=url"` Then, you should be able to get the url by doing this: `String url = joMain.getJSONObject("data").getString("url");` – QuotidianVoid Mar 14 '16 at 20:06

1 Answers1

0

The issue is that a call made to that endpoint ("/" + id + "/picture") -- Documentation here

Is that this returns an actual photo. Note, it doesn't return the URL of a photo or a JSON object (Not content-type application/json), but an actual photo (content-type image/jpeg). Most standard parsing code will have no clue how to handle that, which is the problem you are running into.

First, if you have the album id, you can change the endpoint being called to this one here. (If you have the photo id or the cover_photo id, you can skip this step) This endpoint returns a parseable object structured like this:

//JSON

{
  "id": "101012345368815924",
  "can_upload": false,
  "count": 32,
  "cover_photo": "10101123455127214",
  "created_time": "2010-12-31T02:06:45+0000",
  "from": {
    "name": "Bob Bobson",
    "id": "10103912345123454"
  },
  "link": "https://www.facebook.com/album.php?fbid=10100099323315924&id=10103924111095954&aid=2622251",
  "name": "Mobile Uploads",
  "privacy": "everyone",
  "type": "mobile",
  "updated_time": "2014-10-17T01:11:18+0000"
}

From there, you have 2 ways you can go.

The absolute easiest way to do it is to simply take the URL that you would be sending the request to and append the cover_photo id (IE - https://graph.facebook.com/10101123455127214/picture )

And make that the URL for the photo you are setting. So, for example, if you were using picasso to set that photo, it would look like this:

Picasso.with(mContext).load("https://graph.facebook.com/10101123455127214/picture").into(imageView);

The problem with this approach is that you will get a fairly low quality photo that will look rather pixelated. The super simple fix is to append "?type=large" to the end of the url

https://graph.facebook.com/10101123455127214/picture?type=large

And you will have one with better quality to work with. (See this answer for more options other than just large)

The second way (far more work, but more options in the end) is to parse out the cover_photo id number (10101123455127214) and make a separate call to this endpoint and it will return JSON formatted like this:

//Return data from photo endpoint

{
  "id": "10101123123027214",
  "created_time": "2013-04-14T03:41:17+0000",
  "from": {
    "name": "Bob Bobson",
    "id": "10101231235095954"
  },
  "height": 720,
  "icon": "https:\/\/static.xx.fbcdn.net\/rsrc.php\/v2\/yz\/r\/StEh333Pvjk.gif",
  "images": [
    {
      "height": 1632,
      "source": "https:\/\/scontent.xx.fbcdn.net\/t31.0-8\/891691_101015391232137214_536409052_o.jpg",
      "width": 1224
    },
    {
      "height": 1280,
      "source": "https:\/\/scontent.xx.fbcdn.net\/t31.0-8\/p960x960\/891691_1123155327214_536409052_o.jpg",
      "width": 960
    },
    {
      "height": 960,
      "source": "https:\/\/scontent.xx.fbcdn.net\/v\/t1.0-9\/69013_10101539155123127214_536409052_n.jpg?oh=079600f24b8c9923891232134f9ccb5fce&oe=57CFF2C5",
      "width": 720
    },
    {
      "height": 800,
      "source": "https:\/\/scontent.xx.fbcdn.net\/t31.0-0\/p600x600\/891691_1010112313155327214_536409052_o.jpg",
      "width": 600
    },
    {
      "height": 640,
      "source": "https:\/\/scontent.xx.fbcdn.net\/v\/t1.0-0\/p480x480\/69013_1010100031235327214_536409052_n.jpg?oh=b582ff84568f5ac523132156a7ab0a735&oe=57CC1B81",
      "width": 480
    },
    {
      "height": 426,
      "source": "https:\/\/scontent.xx.fbcdn.net\/v\/t1.0-0\/p320x320\/69013_10101520000139155327214_536409052_n.jpg?oh=b0ca4c70ce79574664a28223134c993&oe=5801544D",
      "width": 320
    },
    {
      "height": 540,
      "source": "https:\/\/scontent.xx.fbcdn.net\/v\/t1.0-0\/p180x540\/69013_10101539000333355327214_536409052_n.jpg?oh=2f403ed6447da8caa22222aaf00754ee&oe=5809FD06",
      "width": 405
    },
    {
      "height": 173,
      "source": "https:\/\/scontent.xx.fbcdn.net\/v\/t1.0-0\/p130x130\/69013_10101533339005327214_536409052_n.jpg?oh=cc05c51315d409222227a62d7356&oe=58089B0C",
      "width": 130
    },
    {
      "height": 225,
      "source": "https:\/\/scontent.xx.fbcdn.net\/v\/t1.0-0\/p75x225\/69013_101015322200327214_536409052_n.jpg?oh=0d05a9718fafc27c33336fce7acb69f&oe=57D1C45D",
      "width": 168
    }
  ],
  "link": "https:\/\/www.facebook.com\/photo.php?fbid=1010153000005327214&set=a.1013330000008815924.20000351.3300000005&type=3",
  "name": "info from the picture will appear here",
  "picture": "https:\/\/scontent.xx.fbcdn.net\/v\/t1.0-0\/s130x130\/69013_10101400044327214_536400052_n.jpg?oh=01ff46df0000641d2a954444000004bd873&oe=57C8A768",
  "source": "https:\/\/scontent.xx.fbcdn.net\/t31.0-8\/s720x720\/891691_10101539444427214_5000409052_o.jpg",
  "updated_time": "2013-04-14T03:41:17+0000",
  "width": 540
}

From here, you can see how you now have multiple photo URLs to choose from (size-wise) depending on what you need. One last trick I use here that I have a static method in place for getting the photo that fits best. Here is the code for it:

//Static method / enum:

public enum PHOTO_QUALITY {LOW, MEDIUM, HIGH}
    /**
     * Takes in a parsed object from a facebook return and gets the image URL out of it
     * @param photoObject The parsed object returned from FB
     * @param quality Quality to return. If null, will set to low
     * @return String url to the actual photo
     */
    public static String getImageUrlFromObject(FacebookDataObject.FacebookPhotoObject photoObject,
                                               PHOTO_QUALITY quality){
        if(photoObject == null){
            return null;
        }
        if(quality == null){
            quality = PHOTO_QUALITY.LOW;
        }

        String urlToReturn = null;

        FacebookDataObject.FacebookImage[] images = photoObject.getImages();
        if(images == null){
            return  null;
        }
        int size = images.length;
        if(size == 0){
            return null;
        }
        if(size == 1){
            urlToReturn = images[0].getSource();
            return urlToReturn;
        }
        if(size > 1){ 

            try{
                //This switch assumes that FB will keep sending back photos in reducing quality (high to low)
                switch (quality){
                    case HIGH:
                        urlToReturn = images[0].getSource(); //Top of the lsit
                        break;

                    case MEDIUM:
                        int pickme1 = size / 2; //Middle of the list
                        urlToReturn = images[pickme1].getSource();
                        break;

                    case LOW:
                        int pickme2 = size - 1 ; //End of the list
                        urlToReturn = images[pickme2].getSource();
                        break;
                }
            } catch (Exception e){
                urlToReturn = images[0].getSource();
                return urlToReturn;
            }

        }
        return urlToReturn;
    }

That should do it for ya. Good luck.

-PGMac

Community
  • 1
  • 1
PGMacDesign
  • 6,092
  • 8
  • 41
  • 78
  • The easiest way with the url doesn't work, because we don't have a permission to access that image. – Starwave Aug 17 '21 at 08:52