如何检查用户是不是使用 FB SDK 4.0 for Android 登录?

Posted

技术标签:

【中文标题】如何检查用户是不是使用 FB SDK 4.0 for Android 登录?【英文标题】:How to check if user is logged in with FB SDK 4.0 for Android?如何检查用户是否使用 FB SDK 4.0 for Android 登录? 【发布时间】:2015-05-31 09:18:04 【问题描述】:

几天前我在我的APP上实现了FB登录,今天我发现我已经实现的大部分东西现在已经被弃用了。

之前,我使用Session 来查看用户是否已登录。但是,这不适用于新的 SDK。

根据他们的文档,我们可以使用AccessToken.getCurrentAccessToken()Profile.getCurrentProfile() 来检查用户是否已经登录,但我无法使用它们。

我试过这样的:

if(AccessToken.getCurrentAccessToken() == null)

我想知道如果我可以在这个内部使用它是否会起作用(FB也提供了):

LoginManager.getInstance().registerCallback(callbackManager, new LoginManager.Callback() ...);

但是,我得到一个“无法解析符号'回调'”。

编辑!!!!!!

好的,所以我可以使用以下命令检查用户是否已登录:

在 onCreate:

accessTokenTracker = new AccessTokenTracker() 
        @Override
        protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken newAccessToken) 
            updateWithToken(newAccessToken);
        
    ;

然后,调用我的updateWithToken 方法:

private void updateWithToken(AccessToken currentAccessToken) 
    if (currentAccessToken != null) 

            LOAD ACTIVITY A!

     else 

            LOAD ACTIVITY B!
    

现在,问题是:如果用户使用过该应用程序并且之前没有登录过,我可以检查一下!但如果这是用户第一次使用该应用程序,我的 AccessTokenTracker 永远不会调用 updateWithToken

如果有人能提供帮助,我将不胜感激。

谢谢!

【问题讨论】:

你试过 Session.getActiveSession() 方法了吗? 会话已从 SDK 4.0 中删除。 =/ 您可以根据更新的文档尝试使用 AccessTokenTracker 我知道我必须使用访问令牌,但正如我在问题中提到的那样:我不知道如何。 如果用户是新用户,您解决问题了吗?想知道如果你这样做了:) 【参考方案1】:

一个更简单的解决方案适用于我的情况(我不知道这是否是更优雅的方式):

public boolean isLoggedIn() 
    AccessToken accessToken = AccessToken.getCurrentAccessToken();
    return accessToken != null;

【讨论】:

这应该是公认的解决方案。另外,我已经仔细检查过它没有过期 (.isExpired())。 这似乎对我不起作用——即使我已登录,它也是null 即使我也登录了也为空 AccessToken.getCurrentAccessToken() 有时为 null 的原因是 onCurrentAccessTokenChanged 被称为异步。您必须第一次等待它。然后你可以使用 AccessToken.getCurrentAccessToken() 如果为null,则需要Track Access Tokens developers.facebook.com/docs/facebook-login/android/v2.2【参考方案2】:

我明白了!

首先,确保您已初始化您的 FB SDK。其次,添加以下内容:

accessTokenTracker = new AccessTokenTracker() 
        @Override
        protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken newAccessToken) 
            updateWithToken(newAccessToken);
        
    ;

当当前访问令牌发生更改时,将调用此方法。这意味着,这只会在用户已经登录时对您有所帮助。

接下来,我们将其添加到 onCreate() 方法中:

updateWithToken(AccessToken.getCurrentAccessToken());

那么当然是我们的updateWithToken() 方法:

private void updateWithToken(AccessToken currentAccessToken) 

    if (currentAccessToken != null) 
        new Handler().postDelayed(new Runnable() 

            @Override
            public void run() 
                Intent i = new Intent(SplashScreen.this, GeekTrivia.class);
                startActivity(i);

                finish();
            
        , SPLASH_TIME_OUT);
     else 
        new Handler().postDelayed(new Runnable() 

            @Override
            public void run() 
                Intent i = new Intent(SplashScreen.this, Login.class);
                startActivity(i);

                finish();
            
        , SPLASH_TIME_OUT);
    

这对我有用! =]

【讨论】:

我使用不同的片段进行登录,使用不同的片段进行发布,我想知道是否必须将访问令牌保存为全局状态。 这对我不起作用。我正在使用LoginButton但收不到任何FB回调。 @sirvon 通过将 FB 登录活动设置为启动活动解决的问题 谢谢 - 我在尝试让 fb 登录 accessToken 正确粘贴时遇到了一点问题,这段代码让它记住我已经登录。 accessTokenTracker 代码必须在 onCreate() 之前添加,FB SDK 必须在 onCreate() 的 setContectView() 之前初始化?【参考方案3】:

我使用 AccessToken 和 AccessTokenTracker 检查登录状态的困境是,当 AccessToken 准备好并且调用了跟踪器的回调函数但配置文件可能还没有准备好,因此我无法获取或显示 Facebooker 的名字。

我的解决方案是检查当前个人资料 != null 并使用其跟踪器同时获取 Facebooker 的姓名:

    ProfileTracker fbProfileTracker = new ProfileTracker() 
        @Override
        protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) 
            // User logged in or changed profile
        
    ;

检查登录状态,然后获取用户名:

Profile profile = Profile.getCurrentProfile();
if (profile != null) 
    Log.v(TAG, "Logged, user name=" + profile.getFirstName() + " " + profile.getLastName());

【讨论】:

谢谢,Profile.getCurrentProfile();对我来说工作得很好:)【参考方案4】:

您可以使用 Felipe 在他的回答中提到的相同方式,也可以使用其他两种方式。但似乎 AccessTokenTracker 是一种方便的方式,因为它可以帮助您跟踪访问令牌(与 ProfileTracker 类一起使用)

    如果您使用自定义按钮进行登录,请使用 LoginManager 回调

例如

在您的布局 xml 中

    <Button
        android:id="@+id/my_facebook_button"
        android:background="@drawable/btnfacebook"
        android:onClick="facebookLogin"/>

在你的活动中

    //Custom Button
    Button myFacebookButton = (Button) findViewById(R.id.my_facebook_button);

按钮 onclick 监听器

public void facebookLogin(View view) 
        LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "user_friends"));
    

最后 LoginManager 回调

 //Create callback manager to handle login response
        CallbackManager callbackManager = CallbackManager.Factory.create();

       LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() 
           @Override
           public void onSuccess(LoginResult loginResult) 
               Log.i(TAG, "LoginManager FacebookCallback onSuccess");
               if(loginResult.getAccessToken() != null) 
                   Log.i(TAG, "Access Token:: " + loginResult.getAccessToken());
                   facebookSuccess();
               
           

           @Override
           public void onCancel() 
               Log.i(TAG, "LoginManager FacebookCallback onCancel");
           

           @Override
           public void onError(FacebookException e) 
               Log.i(TAG, "LoginManager FacebookCallback onError");
           
       );
    如果您使用 SDK 中提供的按钮 (com.facebook.login.widget.LoginButton),请使用 LoginButton 回调(这在他们的参考文档中非常详细 - https://developers.facebook.com/docs/facebook-login/android/v2.3)

例如

在您的布局 xml 中

<com.facebook.login.widget.LoginButton
                android:id="@+id/login_button"
                android:layout_
                android:layout_
                android:layout_gravity="center_horizontal"/>

在你的活动中

    //Facebook SDK provided LoginButton
    LoginButton loginButton = (LoginButton) findViewById(R.id.login_button);
    loginButton.setReadPermissions("user_friends");
    //Callback registration
    loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() 
        @Override
        public void onSuccess(LoginResult loginResult) 
            // App code
            Log.i(TAG, "LoginButton FacebookCallback onSuccess");
            if(loginResult.getAccessToken() != null)
                Log.i(TAG, "Access Token:: "+loginResult.getAccessToken());
                facebookSuccess();
            

        

        @Override
        public void onCancel() 
            // App code
            Log.i(TAG, "LoginButton FacebookCallback onCancel");
        

        @Override
        public void onError(FacebookException exception) 
            // App code
            Log.i(TAG, "LoginButton FacebookCallback onError:: "+exception.getMessage());
            Log.i(TAG,"Exception:: "+exception.getStackTrace());
        
    );

别忘了在你的Activity onActivityResult() 中调用callbackManager.onActivityResult(requestCode, resultCode, data);

【讨论】:

我已经完成了选项 2 中的所有操作。单击 FB 登录按钮并在他们的活动上单击确定后,我的应用程序将重新启动。它首先击中了我的启动屏幕,这将我移动到登录按钮所在的活动。 FB 登录按钮仍然显示使用 Facebook 登录。有什么想法吗? 但是当我从 Facebook 注销后尝试隐藏按钮时它不起作用。 @RogerSmith 也无法获得任何 FB 回调 别忘了调用 callbackManager.onActivityResult(requestCode, resultCode, data);在你的活动 onActivityResult()【参考方案5】:

根据facebook documentation,您可以这样做:

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

【讨论】:

【参考方案6】:

回复晚了,不过现在Facebook SDK4.25.0版本有一个方法:

public void retrieveLoginStatus(Context context,
                                LoginStatusCallback responseCallback)

其中规定:

检索用户的登录状态。这将返回一个访问 如果用户登录 Android 版 Facebook,则应用的令牌 同一设备上的应用程序,并且该用户之前已登录 应用程序。如果检索到访问令牌,则会显示 toast 告诉用户他们已经登录。

并且可以像这样使用:

LoginManager.getInstance().retrieveLoginStatus( this, new LoginStatusCallback()

    @Override
    public void onCompleted( AccessToken accessToken )
    
        GraphRequest request = GraphRequest.newMeRequest( accessToken, new GraphRequest.GraphJSONObjectCallback()
        
            @Override
            public void onCompleted( JSONObject object, GraphResponse response )
            
                Log.e( TAG, object.toString() );
                Log.e( TAG, response.toString() );

                try
                
                    userId = object.getString( "id" );
                    profilePicture = new URL( "https://graph.facebook.com/" + userId + "/picture?width=500&height=500" );
                    Log.d( "PROFILE_URL", "url: " + profilePicture.toString() );
                    if ( object.has( "first_name" ) )
                    
                        firstName = object.getString( "first_name" );
                    
                    if ( object.has( "last_name" ) )
                    
                        lastName = object.getString( "last_name" );
                    
                    if ( object.has( "email" ) )
                    
                        email = object.getString( "email" );
                    
                    if ( object.has( "birthday" ) )
                    
                        birthday = object.getString( "birthday" );
                    
                    if ( object.has( "gender" ) )
                    
                        gender = object.getString( "gender" );
                    

                    Intent main = new Intent( LoginActivity.this, MainActivity.class );
                    main.putExtra( "name", firstName );
                    main.putExtra( "surname", lastName );
                    main.putExtra( "imageUrl", profilePicture.toString() );
                    startActivity( main );
                    finish();
                
                catch ( JSONException e )
                
                    e.printStackTrace();
                
                catch ( MalformedURLException e )
                
                    e.printStackTrace();
                

            
         );
        //Here we put the requested fields to be returned from the JSONObject
        Bundle parameters = new Bundle();
        parameters.putString( "fields", "id, first_name, last_name, email, birthday, gender" );
        request.setParameters( parameters );
        request.executeAsync();
    

    @Override
    public void onFailure()
    
        Toast.makeText( LoginActivity.this, "Could not log in.", Toast.LENGTH_SHORT ).show();
    

    @Override
    public void onError( Exception exception )
    
        Toast.makeText( LoginActivity.this, "Could not log in.", Toast.LENGTH_SHORT ).show();
    
 );

【讨论】:

根据提供的文档,这似乎只在“用户在同一设备上登录 Facebook for Android 应用程序”时才有效。恐怕我们不能依赖这个事实。

以上是关于如何检查用户是不是使用 FB SDK 4.0 for Android 登录?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Facebook SDK 4.0 进行 Android 登录

FB PHP SDK 将未读消息状态更改为已读和计数未读消息

如何使用android fb sdk请求私人组

Facebook iOS SDK 4.0“App Invites”在没有 iOS 通知的情况下发送

如何使用 Facebook iOS SDK 4.0 获取包含用户名和 ID 的用户好友列表

如何在 Facebook Android sdk 4.0 中使用 Graph Request 获取登录用户的电子邮件地址