安卓 - 获取Facebook个人资料照片

51

我不知道为什么,但每当我尝试获取用户的个人资料图片时,总是得到 null 的返回值。我需要设置某些特定权限才能获取访问权吗?

以下是我的方法:

public static Bitmap getFacebookProfilePicture(String userID) throws SocketException, SocketTimeoutException, MalformedURLException, IOException, Exception
{
   String imageURL;

   Bitmap bitmap = null;
   imageURL = "http://graph.facebook.com/"+userID+"/picture?type=large";
   InputStream in = (InputStream) new URL(imageURL).getContent();
   bitmap = BitmapFactory.decodeStream(in);

   return bitmap;
}

Bitmap bitmap = getFacebookProfilePicture(userId);

我得到了空值。我不知道原因是什么?任何帮助都会受到赞赏。


你在 Facebook 开发者页面设置了应用哈希值吗?其他的 Facebook 调用是否正常工作?你检查了日志吗?可能是因为哈希值不正确(这种情况非常常见)。 - Jeffrey Klardie
1
@JeffreyKlardie,你甚至不需要使用Facebook API就可以获取头像照片。 - user123
你说得对。我之前不知道这一点。我添加了一个略微不同的答案;我使用 URL.openConnection().getInputStream() 而不是 URL.getContent(); - Jeffrey Klardie
28个回答

75

这应该可以工作:

public static Bitmap getFacebookProfilePicture(String userID){
    URL imageURL = new URL("https://graph.facebook.com/" + userID + "/picture?type=large");
    Bitmap bitmap = BitmapFactory.decodeStream(imageURL.openConnection().getInputStream());

    return bitmap;
}

Bitmap bitmap = getFacebookProfilePicture(userId);

编辑:

正如在评论中由@dvpublic建议的那样,使用"https"代替"http"可以解决图片未下载的问题。


2
我觉得最新的SDK似乎导致了这个方法停止工作。有人知道发生了什么吗?BitmapFactory.decodeStream现在总是返回null。 - user2494863
9
我怀疑问题不在于SDK,而是出现了重定向问题。请尝试在浏览器中打开链接“http://graph.facebook.com/USER_UID/picture”,这时将打开“httpS://fbcdn-profile-a.akamaihd.net/…”的链接。当原始协议和重定向后的协议相同时,自动重定向会自动工作。因此,请尝试从“httpS://graph.facebook.com/USER_UID/picture”加载图像,并确保调用了HttpURLConnection.setFollowRedirects(true)或conn.setInstanceFollowRedirects(true)。然后BitmapFactory.decodeStream就能正常工作了。 - dvpublic
获取错误 > SkAndroidCodec::NewFromStream 返回了空值。 - Suresh Parmar

54

使用Facebook的ProfilePictureView替代ImageView

<com.facebook.login.widget.ProfilePictureView
    android:id="@+id/friendProfilePicture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    facebook:preset_size="small"/>

然后你可以在代码中像这样设置 Facebook ID

ProfilePictureView profilePictureView;

profilePictureView = (ProfilePictureView) findViewById(R.id.friendProfilePicture);

profilePictureView.setProfileId(userId);

它可以工作.. 您还可以为ProfilePictureView设置小/正常/大/自定义大小


如何制作圆形ProfilePictureView。 - Sagar Chavada
那么你需要为此创建自定义的ProfilePictureView。 参考链接:https://dev59.com/umAg5IYBdhLWcg3wjbdt - Nikhil Borad
1
哦,谢谢你!你真是救命恩人。我已经挣扎了一个小时了。 - Farrukh Faizy

29

只需使用Picasso。添加Picasso库,然后使用这个简单的代码行:

userpicture = (ImageView) row.findViewById(R.id.postuserid);

Picasso.with(context)
       .load("https://graph.facebook.com/" + userID+ "/picture?type=large")
       .into(userpicture);

1
如果您使用Picasso,则由于缓存,它将加载相同的图像,因此当配置文件更改时,您将无法使用Picasso查看更新的图像。 - Rajesh Jadav

18

获取个人资料图片URL的最佳方式

int dimensionPixelSize = getResources().getDimensionPixelSize(com.facebook.R.dimen.com_facebook_profilepictureview_preset_size_large);
Uri profilePictureUri= Profile.getCurrentProfile().getProfilePictureUri(dimensionPixelSize , dimensionPixelSize);
Uri profilePictureUri = ImageRequest.getProfilePictureUri(Profile.getCurrentProfile().getId(), dimensionPixelSize , dimensionPixelSize );

使用 Glide 显示图像

Glide.with(this).load(profilePictureUri)
                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                .into(profilePictureView);

不再使用硬编码的字符串


2
还有一个内置函数可以获取Profile对象中的个人资料图片:Profile.getCurrentProfile().getProfilePictureUri - Noam a

15

你需要调用GraphRequest API来获取当前个人资料图片的URL。

Bundle params = new Bundle();
params.putString("fields", "id,email,picture.type(large)");
new GraphRequest(AccessToken.getCurrentAccessToken(), "me", params, HttpMethod.GET,
        new GraphRequest.Callback() {
            @Override
            public void onCompleted(GraphResponse response) {
                if (response != null) {
                    try {
                        JSONObject data = response.getJSONObject();
                        if (data.has("picture")) {
                            String profilePicUrl = data.getJSONObject("picture").getJSONObject("data").getString("url");
                            Bitmap profilePic = BitmapFactory.decodeStream(profilePicUrl.openConnection().getInputStream());
                            // set profilePic bitmap to imageview
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
}).executeAsync();

希望这能有所帮助!


1
不要忘记从“String url”创建一个新的URL对象:BitmapFactory.decodeStream(new URL(url)。openConnection()。getInputStream()); - n8yn8

6

注意:从2018年3月26日起,所有与手动链接相关的解决方案均不再适用。

您应该遵循此处的官方指南

private static String FACEBOOK_FIELD_PROFILE_IMAGE = "picture.type(large)";
    private static String FACEBOOK_FIELDS = "fields";

    private void getFacebookData() {
        GraphRequest request = GraphRequest.newMeRequest(
                AccessToken.getCurrentAccessToken(),
                (object, response) -> {
                    updateAvatar(getImageUrl(response));
                });
        Bundle parameters = new Bundle();
        parameters.putString(FACEBOOK_FIELDS, FACEBOOK_FIELD_PROFILE_IMAGE);
        request.setParameters(parameters);
        request.executeAsync();
    }

    private static String FACEBOOK_FIELD_PICTURE = "picture";
    private static String FACEBOOK_FIELD_DATA = "data";
    private static String FACEBOOK_FIELD_URL = "url";
    private String getImageUrl(GraphResponse response) {
        String url = null;
        try {
            url = response.getJSONObject()
                    .getJSONObject(FACEBOOK_FIELD_PICTURE)
                    .getJSONObject(FACEBOOK_FIELD_DATA)
                    .getString(FACEBOOK_FIELD_URL);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return url;
    }

1
谢谢,我一直在想为什么Facebook的个人资料图片突然从应用程序中消失了... - Benjamin Piette

4

我总是收到一个回复,该回复声明了FACEBOOK_NON_JSON_RESULT。因此,回顾Facebook的图形API浏览器,我注意到一个带有“redirect”标签的小复选框被勾选了。一些谷歌搜索向我展示,我需要为我的GraphRequest提供一个参数来禁止重定向。因此,正确的请求应该是:

 Bundle params = new Bundle();
 params.putBoolean("redirect", false);

     new GraphRequest(
     AccessToken.getCurrentAccessToken(),
     "me/picture",
     params,
     HttpMethod.GET,
     new GraphRequest.Callback() {
        public void onCompleted(GraphResponse response) {
            try {
                String picUrlString = (String) response.getJSONObject().getJSONObject("data").get("url");   
                //Load picture url in imageView
                Glide.with(this).load(picUrlString).diskCacheStrategy(DiskCacheStrategy.SOURCE).into(profilePictureView);
            } catch (JSONException | IOException e) {
                e.printStackTrace();
            }
        }
    }
 ).executeAsync();                                      

4
检查用户ID,请使用此网址。
imgurl="https://graph.facebook.com/"+user.getId()+"/picture";

3

Facebook API Graph Version 3.2

我已经做出了这个实现:

首先,在“onStart”或“onCreate”中添加这些权限(这可以避免NetworkOnMainThreadException)。

StrictMode.ThreadPolicy policy = new 
StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

之后您可以使用下一个函数:

//Next lines are Strings used as params
public static String FACEBOOK_FIELD_PROFILE_IMAGE = "picture.type(large)";
public static String FACEBOOK_FIELDS = "fields";

//A function that can be accessed from OnCreate (Or a similar function)
private void setImageProfileFacebook(){

        AccessToken accessToken = AccessToken.getCurrentAccessToken();
        boolean isLoggedIn = accessToken != null && !accessToken.isExpired();            

        if(isLoggedIn) {
        //If the user is LoggedIn then continue
            Bundle parameters = new Bundle();
            parameters.putString(Util.FACEBOOK_FIELDS, Util.FACEBOOK_FIELD_PROFILE_IMAGE);
            /* make the API call */
            new GraphRequest(
                    AccessToken.getCurrentAccessToken(),
                    "me",
                    parameters,
                    HttpMethod.GET,
                    new GraphRequest.Callback() {
                        public void onCompleted(GraphResponse response) {
                            /* handle the result */
                            if (response != null) {
                                try {
                                    JSONObject data = response.getJSONObject();
                                    //Log.w(TAG, "Data: " + response.toString());

                                    if (data.has("picture")) {
                                        boolean is_silhouette = data.getJSONObject("picture").getJSONObject("data").getBoolean("is_silhouette");
                                        if (!is_silhouette) {
                                        //Silhouette is used when the FB user has no upload any profile image
                                            URL profilePicUrl = new URL(data.getJSONObject("picture").getJSONObject("data").getString("url"));
                                            InputStream in = (InputStream) profilePicUrl.getContent();
                                            Bitmap bitmap = BitmapFactory.decodeStream(in);
                                            imageViewProfileFisio.setImageBitmap(bitmap);
                                        }
                                    }

                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            } else {
                                Log.w(TAG, "Response null");
                            }
                        }
                    }
            ).executeAsync();
        }
    }

我的示例是使用官方文档创建的: https://developers.facebook.com/docs/graph-api/reference/profile-picture-source/?locale=es_LA

请注意,此链接指向Facebook开发者文档,其中提供了有关图形API参考资料和个人资料图片来源的信息。

3
new AsyncTask<String, Void, Bitmap>() {
        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bitmap = null;
            try {
                String imageURL = "https://graph.facebook.com/" + mFbUserId +"/picture?width=150&width=150";
                URL imageURI = new URL(imageURL);
                bitmap = BitmapFactory.decodeStream(imageURI.openConnection().getInputStream());

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

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);

        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
    }.execute();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接