Facebook Android SDK 4.14使用详解(2016.8)

原创 2016年08月18日 19:05:55

作为一名东南亚APP开发者,Facebook登录和分享是绕不过去的一个功能,最近将APP里的Facebook登录和分享SDK升级到2016年8月的版本,代码改动挺大,现在把具体的代码贴出来供后来者升级SDK方便

首先看一下实现效果:

    


Facebook SDK 的部署方法:

首先,你需要去注册一个开发账号,然后用app的包名和SHA1获得一个app_id

好了现在可以开始正式部署了,首先引用官网的初始化方案:(以下内容来自https://developers.facebook.com/docs/android/getting-started)

Android Studio 设置

要在项目中使用 Facebook SDK,请将其添加为构建依赖项,然后导入。

1.前往 Android Studio | New Project(新项目)| Minimum SDK(最低 SDK)

2.选择 API 15: Android 4.0.3 或更高版本,然后创建新项目。

3.创建新项目后,打开 your_app | build.gradle(您的应用 | build.gradle)

4.将以下字串添加至模块级 /app/build.gradle 的 dependencies 之前:(注:这里可以不写)

repositories {
	mavenCentral() 
}

5.将配置最新版本 Facebook SDK 的 compile 依赖项添加到 build.gradle 文件(注:这里我用的是4.14.1 2016年8月18日新版):

dependencies { 
  compile 'com.facebook.android:facebook-android-sdk:4.+'
}

6.构建项目,然后即可将 com.facebook.FacebookSdk 导入应用。

使用 Facebook SDK 之前,需要先进行初始化。添加调用 FacebookSdk.sdkInitialize 或onCreate 内 Activity 中的 Application

// Add this to the header of your file:
import com.facebook.FacebookSdk;

// Updated your class body:
@Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     FacebookSdk.sdkInitialize(getApplicationContext());
     // Initialize the SDK before executing any other operations,
     // especially, if you're using Facebook UI elements.
}

添加 Facebook 应用编号(注:这个编号一般为15位左右)

然后向项目的 strings 文件添加您的 Facebook 应用编号,并更新 Android 清单:

1.打开 strings.xml 文件。示例路径:/app/src/main/res/values/strings.xml

2.添加新的字符串(名称为 facebook_app_id,值为 Facebook 应用编号)

3.打开 AndroidManifest.xml

4.将 uses-permission 元素添加到清单:

<uses-permission android:name="android.permission.INTERNET"/>

5.将 meta-data 元素添加到 application 元素内:

<application android:label="@string/app_name" ...>
    ...
    <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
    ...
</application>

使用登录或分享功能

要使用 Facebook 登录或分享功能,还需要将 FacebookActivity 添加到清单:

<activity android:name="com.facebook.FacebookActivity"
          android:configChanges=
                 "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
          android:theme="@android:style/Theme.Translucent.NoTitleBar"
          android:label="@string/app_name" />

发送图片或视频

如果要通过 Android 版 Facebook 应用分享链接、图片或视频,还需要在清单文件中声明FacebookContentProvider

在 authorities 值的末尾添加您的应用编号。例如,如果 Facebook 应用编号是 1234(注:实际为15位左右的数字),则声明应如下图所示:

<provider android:authorities="com.facebook.app.FacebookContentProvider1234"
          android:name="com.facebook.FacebookContentProvider"
          android:exported="true" />

好了,基本的环境现在已经配置好了,可以开始着手做登录功能了。

首先需要在xml布局中添加一个facebook按钮

注:这个facebook按钮不一定要放在xml里,我一般都自定义一个带有点击事件的控件,然后再点击事件中 new一个facebook按钮,然后调用它的callonClick()方法,实现出来和点击原生按钮一样,但是自定义按钮可以实现更多的点击事件和设置背景图片等。


/**
     * 初始化facebook的SDK自带按钮
     * 这里会把点击事件拦住,不会向下层的facebook button传递,然后先执行自定义的点击事件,再执行facebook button的原生点击事件
     * 可以在自定义点击事件里写一些记录追踪或者动画的代码
     * @param clickView 用来代替原生facebook按钮的自定义View,用来拦截点击事件,可以传null
     * @param lbFacebook facebook原生登录按钮
     * @param addtionalClickEvent  拦截facebook原生按钮点击事件,并附加一个点击事件,可以传null
     */
    public void initFBLoginButton(View clickView, final LoginButton lbFacebook, Fragment fragment,FacebookCallback<LoginResult> facebookCallback,final Runnable addtionalClickEvent){
        initFBLoginButton(lbFacebook,fragment,facebookCallback);
        if(clickView == null)return;
        clickView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                JLogUtils.i("AlexFB","点击了facebook上面的按钮");
                signOut();//点击登录按钮先登出
                if(addtionalClickEvent != null)addtionalClickEvent.run();//先执行自定义点击事件
                lbFacebook.callOnClick();//再执行facebook登录按钮原生点击事件
            }
        });
    }

    /**
     * 初始化facebook登录按钮,需要自己写一个登录回调传进来
     * @param lbFacebook
     * @param fragment 可以传null
     * @param facebookCallback
     */
    public void initFBLoginButton(LoginButton lbFacebook, Fragment fragment, FacebookCallback<LoginResult> facebookCallback){
        lbFacebook.setReadPermissions("public_profile", "email", "user_birthday", "user_status");
        // 如果你把登陆按钮放在一个fragment里面,就用这个方法,用来使用fragment启动facebook的activity并调用fragment的onActivityResult
        if(fragment != null)lbFacebook.setFragment(fragment);
        // Other app specific specialization
        facebookCallbackManager = CallbackManager.Factory.create();
        // z注册登录回调
        lbFacebook.registerCallback(facebookCallbackManager,facebookCallback);
    }

布局文件可以这么设置

 <RelativeLayout
            android:id="@+id/ll_facebook"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="41dp"
            android:layout_marginRight="41dp"
            android:layout_below="@id/llHeader"
            android:layout_marginTop="20dp"
            >

            
            <TextView
                android:id="@+id/tv_facebook"
                android:layout_width="match_parent"
                android:textColor="@color/white"
                android:background="@drawable/sign_up_facebook"
                android:textSize="50dp"
                android:layout_height="52dp" />
        </RelativeLayout>

这里并没有像官网说的那样使用原生com.facebook.login.widget.LoginButton按钮,而是用了一个TextView代替,好处是TextView可以自由设定大小,背景图片,点击事件,而原生按钮不行。java中这样部署:

lbFacebook = new LoginButton(getContext());
        facebookHelper.initFBLoginButton(tv_facebook, lbFacebook, this, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                JLogUtils.i("AlexFB","facebook登录成功");
                if(loginResult == null) return;
                JLogUtils.i("AlexFB","token是"+loginResult.getAccessToken());
                JViewUtils.showProgressBar(loginRegisterActivity);
                for(String s:loginResult.getRecentlyGrantedPermissions()){
                    JLogUtils.i("AlexFB","被授予的权限是::"+s);
                }
                getUserFacebookBasicInfo();//获取facebook登录用户的基本信息的方法
            }

            @Override
            public void onCancel() {
                // App code
                JLogUtils.i("AlexFB","facebook登录被取消");
            }

            @Override
            public void onError(FacebookException exception) {
                // App code
                JLogUtils.i("AlexFB","facebook登录出现异常",exception);
            }
        }, new Runnable() {
            @Override
            public void run() {
                JLogUtils.i("Alex","点击了tv");
                //写一些其他的点击事件,比如动画,事件追踪等
            }
        });

此时用户点击了我的TextView之后会获得和点击原生登录按钮一样的效果,如果用户手机上装了Facebook的客户端,那么就会开启客户端,然后马上返回此页面,用facebook APP上的登录用户进行登录;如果用户没有安装Facebook APP,那么就开启一个WebView 的Activity让用户通过网页登陆,并在登录完成后返回此页面。

因为两种方式最后都会返回点击登录按钮的页面,会调用该页面的onActivityResult的方法,所以要在onActivityResult()中使用SDK提供的CallbackManager这个类接收facebook的登录回调,代码如下:

if(facebookHelper != null && facebookHelper.facebookCallbackManager!= null)facebookHelper.facebookCallbackManager.onActivityResult(requestCode, resultCode, data);
       
这里的facebookHelper是我自己写的一个管理类,是fragment的一个成员,facebookHelper把CallbackManager作为自己的成员进行调用

注意只有接收了onActivityResult()的回调才会登录调用登录回调的方法。


好了登录步骤结束了,我们可以获得一个和用户有关的token字段,但是有这个还不够啊,我们还需要一些基本的用户信息,比如用户的名字,性别,年龄,头像等等,才能完成一套登录注册流程。

下面就需要使用刚刚获得的token去联网异步的获取用户的基本信息了,这里我们拿着上一步的token,开启异步网络线程,从facebook那里拿到一个json字符串,然后用json解析得到我们想要的数据,通过接口回调将获得数据回调给UI界面,方法如下

/**
     *  获取用户的基本信息,比如姓名,年龄,userId,性别等等
     * @param callback
     */
    public static void getUserFacebookBasicInfo(final FacebookUserInfoCallback callback) {
        // 获取基本文本信息
        JLogUtils.i("AlexFB", "准备获取facebook用户基本信息");
        if(callback == null)return;
        GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
            @Override
            public void onCompleted(JSONObject object, GraphResponse response) {
                if (response == null) {
                    callback.onFailed("无法获取用户基本信息");
                    return;
                }
                JLogUtils.i("AlexFB", "获取用户基本信息完毕,object是" + object);
                JSONObject responseJsonObject = response.getJSONObject();
                JLogUtils.i("AlexFB", "而response 的object是" + responseJsonObject);//这两个jsonObject是一样的
                if (responseJsonObject == null) {
                    callback.onFailed("无法获取用户基本信息2" + response.getError().getErrorType() + "   " + response.getError().getErrorMessage());
                    return;
                }
                FaceBookUserInfo userInfo = new FaceBookUserInfo();
                userInfo.id = getFacebookGraphResponseString(responseJsonObject, "id");
                userInfo.firstName = getFacebookGraphResponseString(responseJsonObject, "first_name");
                userInfo.lastName = getFacebookGraphResponseString(responseJsonObject, "last_name");
                userInfo.userName = getFacebookGraphResponseString(responseJsonObject, "name");
                userInfo.birthday = getFacebookGraphResponseString(responseJsonObject, "birthday");
                userInfo.updateTime = getFacebookGraphResponseString(responseJsonObject, "updated_time");
                userInfo.email = getFacebookGraphResponseString(responseJsonObject, "email");
                userInfo.gender = getFacebookGraphResponseString(responseJsonObject, "gender");
                callback.onCompleted(userInfo);
            }
        });
        Bundle parameters = new Bundle();
        parameters.putString("fields", "id,name,link,email,first_name,last_name,gender,locale,timezone,updated_time,verified");
        request.setParameters(parameters);
        request.executeAsync();
    }

    /**
     * 获取用户的token之后,根据此token联网获取该用户详细信息的回调函数
     */
    public interface FacebookUserInfoCallback{
        void onCompleted(FaceBookUserInfo userInfo);//成功回调
        void onFailed(String reason);//失败回调
    }
    public interface FacebookUserImageCallback{
        void onCompleted(String imageUrl);//成功回调
        void onFailed(String reason);//失败回调
    }

    /**
     * 用于存储Facebook用户基本信息的类
     */
    public static class FaceBookUserInfo {
        public String id;
        public String firstName;
        public String lastName;
        public String userName;
        public String birthday;
        public String location;
        public String updateTime;
        public String email;
        public String gender;
        public String avatar;//头像url
    }

    private static String getFacebookGraphResponseString(JSONObject graphResponse, String flag) {
        String value = "";
        try {
            value = graphResponse.getString(flag);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        JLogUtils.i("AlexFB","获取用户信息 flag="+flag+"   结果是"+value);
        return value;
    }

在UI界面调用方法:

AlxFacebookHelper.getUserFacebookBasicInfo(new AlxFacebookHelper.FacebookUserInfoCallback() {
            @Override
            public void onCompleted(AlxFacebookHelper.FaceBookUserInfo userInfo) {
                if (loginRegisterActivity.facebookUser == null) loginRegisterActivity.facebookUser = new ThirdPartyFacebookUserInfoEntity();<span style="white-space:pre">		</span>//下面是一些执行登录记录的代码
                loginRegisterActivity.facebookUser.setId(userInfo.id);
                loginRegisterActivity.facebookUser.setFirstName(userInfo.firstName);
                loginRegisterActivity.facebookUser.setLastName(userInfo.lastName);
                loginRegisterActivity.facebookUser.setUserName(userInfo.userName);
                loginRegisterActivity.facebookUser.setBirthday(userInfo.birthday);
                loginRegisterActivity.facebookUser.setUpdateTime(userInfo.updateTime);
                loginRegisterActivity.facebookUser.setEmail(userInfo.email);
                loginRegisterActivity.facebookUser.setGender(userInfo.gender);
                //用户基本信息获取完毕,准备根据用户id获取用户头像
                fbGetFacebookUserPictureInfoFromFB(loginRegisterActivity.facebookUser.getId());
            }

            @Override
            public void onFailed(String reason) {
                JLogUtils.i("AlexFB","获取facebook用户信息失败::"+reason);
                AlxFacebookHelper.signOut();
            }
        });

获取用户头像的url在刚才步骤拿不到,必须再开一个异步请求向facebook请求用户头像的url,在这个过程中我们还可以指定我们想要的头像的分辨率,保证拿到的头像清晰,这一步需要用到上一步得到的userId,然后异步获得一个json串,解析出我们想要的头像url,并通过接口将获得结果回调给ui界面,代码如下

/**
     * 通过facebook的userId,联网异步获取用户的头像url
     * @param facebookUserId
     */
    public static void getFacebookUserPictureAsync(String facebookUserId, final FacebookUserImageCallback callback) {
        JLogUtils.i("AlexFB","准备获取用户头像");
        if(callback == null || facebookUserId == null || facebookUserId.length()==0)return;
        Bundle parameters = new Bundle();
        parameters.putBoolean("redirect", false);
        parameters.putString("height", "200");
        parameters.putString("type", "normal");
        parameters.putString("width", "200");
        GraphRequest graphRequest= new GraphRequest(AccessToken.getCurrentAccessToken(), "/" + facebookUserId + "/picture", parameters, HttpMethod.GET, new GraphRequest.Callback() {
            public void onCompleted(GraphResponse response) {
                if (response == null) {
                    callback.onFailed("获取用户facebook头像失败");
                    return;
                }

                if (response.getError() != null) {
                    FacebookRequestError facebookRequestError = response.getError();
                    callback.onFailed("获取用户facebook头像失败2::" + facebookRequestError.getErrorMessage());
                    return;
                }

                JSONObject responseJsonObject = response.getJSONObject();
                if (responseJsonObject == null) {
                    callback.onFailed("获取用户facebook头像失败3");
                    return;
                }
                JLogUtils.i("AlexFB", "facebook直接返回的头像信息是" + responseJsonObject.toString());
                String avatarUrl = "";
                try {
                    JSONObject dataJsonObject = responseJsonObject.getJSONObject("data");
                    avatarUrl = dataJsonObject.getString("url");
                    avatarUrl = URLEncoder.encode(avatarUrl, "UTF-8");
                    JLogUtils.i("AlexFB", "用户头像获取完毕 avatarUrl:" + avatarUrl);
                } catch (Exception e) {
                    callback.onFailed("获取用户facebook头像失败4"+e.getStackTrace().toString());
                }
                callback.onCompleted(avatarUrl);
            }
        }
        );
        JLogUtils.i("AlexFB","version:"+graphRequest.getVersion()+"");
        graphRequest.executeAsync();
    }

UI界面调用代码:

AlxFacebookHelper.getFacebookUserPictureAsync(facebookUserId,new AlxFacebookHelper.FacebookUserImageCallback() {
            @Override
            public void onCompleted(String imageUrl) {
                //成功获取到了头像之后
                loginRegisterActivity.facebookUser.setAvatar(imageUrl);
                //用户的头像和基本信息都获取完毕,现在可以向我们自己的服务器注册facebook用户了
                ...
                
            }

            @Override
            public void onFailed(String reason) {
                AlxFacebookHelper.signOut();//如果获取失败了,别忘了将整个登录结果回滚
                JLogUtils.i("AlexFB",reason);
            }
        });


好了,基本的登录过程现在就完成了,下面说一下分享的代码:

因为有了SDK,在使用分享功能呢的时候会在自己的APP上面压一个cardView,相对于旧版SDK将一个Activity直接压在自己APP上来说,这样的用户体验更好一点


下面说一下具体的代码实现:

/**
     * 通过facebook sdk的默认弹出框进行分享
     * @param activity
     */
    public static void showFacebookShareDialog(Activity activity,String link,String description,String caption,String imageUrl,ShareFacebookCallback callback) {
        if (activity == null) {
            if(callback!=null)callback.onFailure("activity 为空");
            return;
        }
        if (!ShareDialog.canShow(ShareLinkContent.class)) {
            if(callback!=null)callback.onFailure("现在不能分享");
            return;
        }
        try {
            ShareDialog shareDialog = new ShareDialog(activity);
            ShareLinkContent.Builder builder = new ShareLinkContent.Builder();
            if(!TextUtils.isEmpty(caption)) builder.setContentTitle(caption);
            if(!TextUtils.isEmpty(description)) builder.setContentDescription(description);
            if(!TextUtils.isEmpty(link))builder.setContentUrl(Uri.parse(link));
            if(!TextUtils.isEmpty(imageUrl)) builder.setImageUrl(Uri.parse(imageUrl));
            ShareLinkContent linkContent= builder.build();
            shareDialog.show(linkContent);
            if(callback!=null)callback.onSuccess();
        } catch (Exception ex) {
            if(callback!=null)callback.onFailure(ex.getStackTrace().toString());
        }
    }

UI界面调用方法

public static void publishFacebookStoryByNativeApp(Activity activity, FacebookStoryEntity entity, final Handler handler) {
        //将要飞翔的数据传过来,发送到工具类的方法里
            String link = entity.getLink();
            String applicationname = entity.getApplicationName();
            String description = entity.getDescription();
            String name = entity.getName();
            String caption = entity.getCaption();
            String picture = entity.getPicture();
        AlxFacebookHelper.showFacebookShareDialog(activity, link, description, caption, picture, new AlxFacebookHelper.ShareFacebookCallback() {
            @Override
            public void onSuccess() {
                JLogUtils.i("AlexFB","share fb弹窗框建立成功");
            }

            @Override
            public void onFailure(String reason) {
                JLogUtils.i("AlexFB",reason);
                //执行一些分享失败的动作
            }
        });
    }


这样一个分享就ok了。

最后把我自己写的工具类的全部代码都贴出来,里面设置了很多回调用的接口,不要和facebook SDK中的接口搞混了

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.View;

import com.facebook.AccessToken;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookRequestError;
import com.facebook.GraphRequest;
import com.facebook.GraphResponse;
import com.facebook.HttpMethod;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.facebook.share.model.ShareLinkContent;
import com.facebook.share.widget.ShareDialog;
import com.imaginato.qravedconsumer.utils.JLogUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.net.URLEncoder;


/**
 * Created by Administrator on 2016/8/16.
 */
public class AlxFacebookHelper {
    public CallbackManager facebookCallbackManager;

    /**
     * 初始化facebook的SDK自带按钮
     * 这里会把点击事件拦住,不会向下层的facebook button传递,然后先执行自定义的点击事件,再执行facebook button的原生点击事件
     * 可以在自定义点击事件里写一些记录追踪或者动画的代码
     * @param clickView 压在facebook原生登录按钮上面的View,用来拦截点击事件,可以传null
     * @param lbFacebook facebook原生登录按钮
     * @param addtionalClickEvent  拦截facebook原生按钮点击事件,并附加一个点击事件,可以传null
     */
    public void initFBLoginButton(View clickView, final LoginButton lbFacebook, Fragment fragment,FacebookCallback<LoginResult> facebookCallback,final Runnable addtionalClickEvent){
        initFBLoginButton(lbFacebook,fragment,facebookCallback);
        if(clickView == null)return;
        clickView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                JLogUtils.i("AlexFB","点击了facebook上面的按钮");
                signOut();//点击登录按钮先登出
                if(addtionalClickEvent != null)addtionalClickEvent.run();//先执行自定义点击事件
                lbFacebook.callOnClick();//再执行facebook登录按钮原生点击事件
            }
        });
    }

    /**
     * 初始化facebook登录按钮,需要自己写一个登录回调传进来
     * @param lbFacebook
     * @param fragment 可以传null
     * @param facebookCallback
     */
    public void initFBLoginButton(LoginButton lbFacebook, Fragment fragment, FacebookCallback<LoginResult> facebookCallback){
        lbFacebook.setReadPermissions("public_profile", "email", "user_birthday", "user_status");
        // 如果你把登陆按钮放在一个fragment里面,就用这个方法,用来使用fragment启动facebook的activity并调用fragment的onActivityResult
        if(fragment != null)lbFacebook.setFragment(fragment);
        // Other app specific specialization
        facebookCallbackManager = CallbackManager.Factory.create();
        // z注册登录回调
        lbFacebook.registerCallback(facebookCallbackManager,facebookCallback);
    }

    /**
     *  获取用户的基本信息,比如姓名,年龄,userId,性别等等
     * @param callback
     */
    public static void getUserFacebookBasicInfo(final FacebookUserInfoCallback callback) {
        // 获取基本文本信息
        JLogUtils.i("AlexFB", "准备获取facebook用户基本信息");
        if(callback == null)return;
        GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
            @Override
            public void onCompleted(JSONObject object, GraphResponse response) {
                if (response == null) {
                    callback.onFailed("无法获取用户基本信息");
                    return;
                }
                JLogUtils.i("AlexFB", "获取用户基本信息完毕,object是" + object);
                JSONObject responseJsonObject = response.getJSONObject();
                JLogUtils.i("AlexFB", "而response 的object是" + responseJsonObject);//这两个jsonObject是一样的
                if (responseJsonObject == null) {
                    callback.onFailed("无法获取用户基本信息2" + response.getError().getErrorType() + "   " + response.getError().getErrorMessage());
                    return;
                }
                FaceBookUserInfo userInfo = new FaceBookUserInfo();
                userInfo.id = getFacebookGraphResponseString(responseJsonObject, "id");
                userInfo.firstName = getFacebookGraphResponseString(responseJsonObject, "first_name");
                userInfo.lastName = getFacebookGraphResponseString(responseJsonObject, "last_name");
                userInfo.userName = getFacebookGraphResponseString(responseJsonObject, "name");
                userInfo.birthday = getFacebookGraphResponseString(responseJsonObject, "birthday");
                userInfo.updateTime = getFacebookGraphResponseString(responseJsonObject, "updated_time");
                userInfo.email = getFacebookGraphResponseString(responseJsonObject, "email");
                userInfo.gender = getFacebookGraphResponseString(responseJsonObject, "gender");
                callback.onCompleted(userInfo);
            }
        });
        Bundle parameters = new Bundle();
        parameters.putString("fields", "id,name,link,email,first_name,last_name,gender,locale,timezone,updated_time,verified");
        request.setParameters(parameters);
        request.executeAsync();
    }

    /**
     * 获取用户的token之后,根据此token联网获取该用户详细信息的回调函数
     */
    public interface FacebookUserInfoCallback{
        void onCompleted(FaceBookUserInfo userInfo);//成功回调
        void onFailed(String reason);//失败回调
    }
    public interface FacebookUserImageCallback{
        void onCompleted(String imageUrl);//成功回调
        void onFailed(String reason);//失败回调
    }

    /**
     * 用于存储Facebook用户基本信息的类
     */
    public static class FaceBookUserInfo {
        public String id;
        public String firstName;
        public String lastName;
        public String userName;
        public String birthday;
        public String location;
        public String updateTime;
        public String email;
        public String gender;
        public String avatar;//头像url
    }

    private static String getFacebookGraphResponseString(JSONObject graphResponse, String flag) {
        String value = "";
        try {
            value = graphResponse.getString(flag);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        JLogUtils.i("AlexFB","获取用户信息 flag="+flag+"   结果是"+value);
        return value;
    }

    /**
     * 通过facebook的userId,联网异步获取用户的头像url
     * @param facebookUserId
     */
    public static void getFacebookUserPictureAsync(String facebookUserId, final FacebookUserImageCallback callback) {
        JLogUtils.i("AlexFB","准备获取用户头像");
        if(callback == null || facebookUserId == null || facebookUserId.length()==0)return;
        Bundle parameters = new Bundle();
        parameters.putBoolean("redirect", false);
        parameters.putString("height", "200");
        parameters.putString("type", "normal");
        parameters.putString("width", "200");
        GraphRequest graphRequest= new GraphRequest(AccessToken.getCurrentAccessToken(), "/" + facebookUserId + "/picture", parameters, HttpMethod.GET, new GraphRequest.Callback() {
            public void onCompleted(GraphResponse response) {
                if (response == null) {
                    callback.onFailed("获取用户facebook头像失败");
                    return;
                }

                if (response.getError() != null) {
                    FacebookRequestError facebookRequestError = response.getError();
                    callback.onFailed("获取用户facebook头像失败2::" + facebookRequestError.getErrorMessage());
                    return;
                }

                JSONObject responseJsonObject = response.getJSONObject();
                if (responseJsonObject == null) {
                    callback.onFailed("获取用户facebook头像失败3");
                    return;
                }
                JLogUtils.i("AlexFB", "facebook直接返回的头像信息是" + responseJsonObject.toString());
                String avatarUrl = "";
                try {
                    JSONObject dataJsonObject = responseJsonObject.getJSONObject("data");
                    avatarUrl = dataJsonObject.getString("url");
                    avatarUrl = URLEncoder.encode(avatarUrl, "UTF-8");
                    JLogUtils.i("AlexFB", "用户头像获取完毕 avatarUrl:" + avatarUrl);
                } catch (Exception e) {
                    callback.onFailed("获取用户facebook头像失败4"+e.getStackTrace().toString());
                }
                callback.onCompleted(avatarUrl);
            }
        }
        );
        JLogUtils.i("AlexFB","version:"+graphRequest.getVersion()+"");
        graphRequest.executeAsync();
    }

    /**
     * 解绑facebook
     */
    public static void signOut(){
        JLogUtils.i("AlexFB","准备正式解绑本地的facebook登录信息");
        try {
            if (AccessToken.getCurrentAccessToken() != null) LoginManager.getInstance().logOut();//登出facebook
        }catch(Exception ex){
            JLogUtils.i("AlexFB","登出出现异常");
        }

    }

    /**
     * 使用facebook弹出框进行分享的代码
     */
    public interface ShareFacebookCallback{
        void onSuccess();
        void onFailure(String reason);
    }

    /**
     * 通过facebook sdk的默认弹出框进行分享
     * @param activity
     */
    public static void showFacebookShareDialog(Activity activity,String link,String description,String caption,String imageUrl,ShareFacebookCallback callback) {
        if (activity == null) {
            if(callback!=null)callback.onFailure("activity 为空");
            return;
        }
        if (!ShareDialog.canShow(ShareLinkContent.class)) {
            if(callback!=null)callback.onFailure("现在不能分享");
            return;
        }
        try {
            ShareDialog shareDialog = new ShareDialog(activity);
            ShareLinkContent.Builder builder = new ShareLinkContent.Builder();
            if(!TextUtils.isEmpty(caption)) builder.setContentTitle(caption);
            if(!TextUtils.isEmpty(description)) builder.setContentDescription(description);
            if(!TextUtils.isEmpty(link))builder.setContentUrl(Uri.parse(link));
            if(!TextUtils.isEmpty(imageUrl)) builder.setImageUrl(Uri.parse(imageUrl));
            ShareLinkContent linkContent= builder.build();
            shareDialog.show(linkContent);
            if(callback!=null)callback.onSuccess();
        } catch (Exception ex) {
            if(callback!=null)callback.onFailure(ex.getStackTrace().toString());
        }
    }
}



版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

Facebook SDK 的添加基本流程(Android)

1.首先你要打开 Android Studio 创建一个新的工程 出来后就是这样的,如下图 2.然后我们要添加 FaceBook 的一些依赖,主要是 Gradle Scripts -- bui...

Facebook SDK 登录分享

Facebook SDK typedef void (^FacebookLogin)(); - (void)facebookCompletion:(FacebookLogin)completi...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

Facebook官方sdk对接

facebook原生的登陆和分享及超链接跳转功能
  • byxyrq
  • byxyrq
  • 2015-12-23 22:26
  • 1424

FacebookSDK接入的那些坑

1,使用aar代替jar,对Android Studio熟悉的同学建议直接看第4步 1)首先需要开发工具使用Android studio而不是Eclipse; 一个Android studio M...

Android下使用最新FaceBook SDK 3.0(一)集成FacebookSDk到项目中

简单介绍一下: 大家都知道,FaceBook在国外很多人使用,而国内就比较少人使用。我们做程序员的就应该不断的去学习再学习,这样才能充实自己,谁又说不是呢!好吧,废话不多说了,下面就让我们一起进入F...

Eclipse facebook 第三方登录 获取用户信息 附demo

1 、Eclipse 项目接入 Facebook 第三方登录 首先引用facebook
  • jin290
  • jin290
  • 2016-06-30 18:53
  • 1732

android Facebook登陆获取用户信息

第一步:准备工作 注册facebook开发者获取ApplicationId,老样子翻墙用蓝灯,可能会被facebook冻结账号,需要上传个人信息验证。 第二步:在Module中添加依赖compil...

Android之Fresco(facebook的强大Android图片加载的框架)

摘要: Fresco是Facebook最新推出的一款用于Android应用中展示图片的强大图片库,可以从网络、本地存储和本地资源中加载图片。其中的Drawees可以显示占位符,直到图片加载完成。而当图...

Facebook Android SDK 4.14使用详解(2016.8)

本文主要介绍了2016年8月facebook Android SDK 4.14.1在Android Studio中的部署方法,包括登录登出功能,分享功能,获得用户基本信息,头像的功能等。并指出了易错点...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)