如何检查用户是不是使用 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 登录?的主要内容,如果未能解决你的问题,请参考以下文章