没有登录按钮的 Facebook 身份验证

Posted

技术标签:

【中文标题】没有登录按钮的 Facebook 身份验证【英文标题】:Facebook authentication without login button 【发布时间】:2013-08-10 17:57:01 【问题描述】:

我学习了一些 Facebook API 3.0 教程,包括登录/注销和发布到 Feed 示例。所以登录是这样工作的:

    应用打开,显示一个显示登录按钮的片段 用户点击登录,身份验证通过引用的 FacebookSDK 库 (com.facebook.widget.LoginActivity) 和使用会话提供的代码完成。 用户被重定向到下一个屏幕

我不想让用户以这种方式登录。我希望他们在没有任何登录/注册的情况下使用我的应用程序,然后如果他们点击 facebook 特定功能,例如在 Facebook 上分享一条笔记,然后应用程序应该询问他们是否让 Facebook 使用他们的应用程序或其他什么,你知道通常的东西。如果没有这个,我会在 publishFeedDialog() 函数中得到一个空指针,因为会话为空,因为没有进行登录。

所以我的问题是,我怎样才能忽略带有登录按钮的 SplashFragment,所以当用户单击我的应用程序中的 Facebook 功能时,不会显示带有登录按钮的新屏幕,而只会显示默认的 Facebook 身份验证窗口用户习惯了吗?

【问题讨论】:

您找到解决方案了吗?我也面临同样的问题。 我来,@erdomester 这里有什么消息吗? 我想我们做了一些变通办法,但我不再从事那个项目了。 【参考方案1】:

@erdomester, @sromku

Facebook 推出新的 sdk 版本 4.x,其中 Session 已弃用,

来自facebook的登录新概念

LoginManager and AccessToken - 这些新类执行 Facebook 登录

所以,现在您可以在没有登录按钮的情况下访问 Facebook 身份验证

layout.xml

    <Button
            android:id="@+id/btn_fb_login"
            .../>

MainActivity.java

private CallbackManager mCallbackManager;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    FacebookSdk.sdkInitialize(this.getApplicationContext());

    mCallbackManager = CallbackManager.Factory.create();

    LoginManager.getInstance().registerCallback(mCallbackManager,
            new FacebookCallback<LoginResult>() 
                @Override
                public void onSuccess(LoginResult loginResult) 
                    Log.d("Success", "Login");

                

                @Override
                public void onCancel() 
                    Toast.makeText(MainActivity.this, "Login Cancel", Toast.LENGTH_LONG).show();
                

                @Override
                public void onError(FacebookException exception) 
                    Toast.makeText(MainActivity.this, exception.getMessage(), Toast.LENGTH_LONG).show();
                
            );

    setContentView(R.layout.activity_main);

    Button btn_fb_login = (Button)findViewById(R.id.btn_fb_login);

    btn_fb_login.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
              LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "user_friends"));
        
    );


编辑

如果您不添加以下内容,它将无法正常工作(@Daniel Zolnai 在下面的评论中正确指出):

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    if(mCallbackManager.onActivityResult(requestCode, resultCode, data)) 
        return;
    

【讨论】:

几天前我发现了新的 sdk,我不得不说,Facebook 的人终于创造了可以使用的东西,这让我松了一口气。每个人都应该更新到新的 sdk。 这对我来说很好用。如果您的回调没有被调用,请检查您是否添加了以下行:@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) super.onActivityResult(requestCode, resultCode, data); callbackManager.onActivityResult(requestCode, resultCode, data); 您可以添加完整的代码,包括登录、注销和获取个人资料信息。我需要那个。 谢谢@Sufian。现在我的回答完成了。 注意将MainActivity.this 设置为logInWithReadPermissions() 的属性。或者this 将意味着View.OnClickListener 而不是Activity【参考方案2】:

类似的东西

private void performFacebookLogin()

    Log.d("FACEBOOK", "performFacebookLogin");
    final Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, Arrays.asList("email"));
    Session openActiveSession = Session.openActiveSession(this, true, new Session.StatusCallback()
    
        @Override
        public void call(Session session, SessionState state, Exception exception)
        
            Log.d("FACEBOOK", "call");
            if (session.isOpened() && !isFetching)
            
                Log.d("FACEBOOK", "if (session.isOpened() && !isFetching)");
                isFetching = true;
                session.requestNewReadPermissions(newPermissionsRequest);
                Request getMe = Request.newMeRequest(session, new GraphUserCallback()
                
                    @Override
                    public void onCompleted(GraphUser user, Response response)
                    
                        Log.d("FACEBOOK", "onCompleted");
                        if (user != null)
                        
                            Log.d("FACEBOOK", "user != null");
                            org.json.JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
                            String email = graphResponse.optString("email");
                            String id = graphResponse.optString("id");
                            String facebookName = user.getUsername();
                            if (email == null || email.length() < 0)
                            
                                Logic.showAlert(
                                        ActivityLogin.this,
                                        "Facebook Login",
                                        "An email address is required for your account, we could not find an email associated with this Facebook account. Please associate a email with this account or login the oldskool way.");
                                return;
                            
                        
                    
                );
                getMe.executeAsync();
            
            else
            
                if (!session.isOpened())
                    Log.d("FACEBOOK", "!session.isOpened()");
                else
                    Log.d("FACEBOOK", "isFetching");

            
        
    );

其实就是这样。它对我来说非常好用。

【讨论】:

我有我的自定义按钮“在 Facebook 上分享”。当用户单击它时,它会检查用户日志状态。如果用户已登录,则将文本发布在墙上,否则提示登录。我想添加 publish_stream 权限。请帮助我。你是如何做到这一点的。 你能解释一下如何定义isFetching吗? 布尔 isFetching = false;将其声明为成员变量,除非在获取时,否则保持为 false。 这会打开一个黑色背景的进度条,我怎么能用我自己的进度条呢? 你能添加完整的登录、注销和获取个人资料信息的代码吗?使用没有 FB 登录按钮的最新 Sdk,我尝试了一些示例但无法正常工作。或者请建议我一个工作示例。 @WIllJBD【参考方案3】:

这对我有用

    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Intent;
    import android.widget.TextView;
    import com.facebook.*;
    import com.facebook.model.*;

    public class MainActivity extends Activity 

      @Override
      public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // start Facebook Login
        Session.openActiveSession(this, true, new Session.StatusCallback() 

          // callback when session changes state
          @Override
          public void call(Session session, SessionState state, Exception exception) 
            if (session.isOpened()) 

              // make request to the /me API
              Request.newMeRequest(session, new Request.GraphUserCallback() 

                // callback after Graph API response with user object
                @Override
                public void onCompleted(GraphUser user, Response response) 
                  if (user != null) 
                    TextView welcome = (TextView) findViewById(R.id.welcome);
                    welcome.setText("Hello " + user.getName() + "!");
                  
                
              ).executeAsync();
            
          
        );
      

      @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) 
          super.onActivityResult(requestCode, resultCode, data);
          Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
      

    

如果您需要在验证会话打开后获得授权,请按以下方式添加:

List<String> permissions = session.getPermissions();             
                 Session.NewPermissionsRequest newPermissionsRequest = new         Session.NewPermissionsRequest(getActivity(), Arrays.asList("read_mailbox"));
                 session.requestNewReadPermissions(newPermissionsRequest);

【讨论】:

你的permissions 变量是干什么用的?在下一个语句中似乎没有使用它。 @KonradMorawski 有点晚了,但它用于您想要从 facebook 个人资料中获取的数据类型(如 public_profile、user_friends、电子邮件)【参考方案4】:

这个简单的库可以帮助你:https://github.com/sromku/android-simple-facebook 只需将此库添加到您的项目中,并从此库中引用 Facebook SDK 3.0.x,然后将应用中的引用添加到此库中。

然后您可以在不使用LoginButton 的情况下登录并执行简单的操作,例如发布提要、获取个人资料/朋友、发送邀请等。

这是登录的样子:

OnLoginOutListener onLoginOutListener = new SimpleFacebook.OnLoginOutListener()


    @Override
    public void onFail()
    
        Log.w(TAG, "Failed to login");
    

    @Override
    public void onException(Throwable throwable)
    
        Log.e(TAG, "Bad thing happened", throwable);
    

    @Override
    public void onThinking()
    
        // show progress bar or something to the user while login is happening
        Log.i(TAG, "In progress");
    

    @Override
    public void onLogout()
    
        // change the state of the button or do whatever you want
        Log.i(TAG, "Logged out");
    

    @Override
    public void onLogin()
    
        // change the state of the button or do whatever you want
        Log.i(TAG, "Logged in");
    
;

// set login/logut listener
mSimpleFacebook.setLogInOutListener(onLoginOutListener);

// do the login action
mSimpleFacebook.login(MainActivity.this);

然后,在onLogin() 回调方法中,您可以像这样发布提要:

// build feed
Feed feed = new Feed.Builder()
    .setMessage("Clone it out...")
    .setName("Simple Facebook for Android")
    .setCaption("Code less, do the same.")
    .setDescription("The Simple Facebook library project makes the life much easier by coding less code for being able to login, publish feeds and open graph stories, invite friends and more.")
    .setPicture("https://raw.github.com/sromku/android-simple-facebook/master/Refs/android_facebook_sdk_logo.png")
    .setLink("https://github.com/sromku/android-simple-facebook")
    .build();

// publish the feed
mSimpleFacebook.publish(feed);

希望对你有帮助。

【讨论】:

SimpleFacebook 现已弃用【参考方案5】:

无需使用 LoginButton 即可访问 FB 详细信息的 Turnaroubd 是

1)隐藏您的登录按钮 UI

2)添加您的自定义按钮

Button signup = (Button) view.findViewById(R.id.btn_signup);
        signup.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                loginButton.performClick();//Where loginButton is Facebook UI
            
        );

但我建议使用 LoginManager

【讨论】:

【参考方案6】:

您可以使用 Node 驱动的 facebook-proxy 模块绕过登录对话框。使用一键部署按钮在 Heroku 上创建您自己的实例。

它的基本作用:

    从 Facebook 请求 access_token 使用express-http-proxy 打开代理服务器 让我们请求 API 的所有端点

【讨论】:

【参考方案7】:

您可以更改放置 Facebook 按钮并更改可见性。例如:

<FrameLayout
            android:id="@+id/frameLayout_facebook"
            android:layout_
            android:layout_>

            <com.google.android.material.button.MaterialButton
                android:id="@+id/button_continue_facebook"
                android:layout_
                android:layout_
                android:text="@string/continue_with_facebook" />

            <com.facebook.login.widget.LoginButton
                android:id="@+id/loginButton_facebook"
                android:visibility="gone"
                android:layout_
                android:layout_ />

 </FrameLayout>

之后,在您的代码中(此处为 Kotlin),当有人点击您的 Button 时,您可以调用 Facebook SDK 的 onClick() 方法:

 button_continue_facebook.setOnClickListener 
            binding.loginButton_facebook.callOnClick()

【讨论】:

以上是关于没有登录按钮的 Facebook 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中单击 Facebook 登录按钮后未显示 Facebook 身份验证对话框

Facebook Open Graph 操作前身份验证

作为 iOS 上 FaceBook 身份验证的一部分登录我们的网站

使用 Passport 通过 Facebook 进行身份验证不起作用

facebook怎么验证?

我可以使用啥密钥来验证 Facebook 登录生成的 Firebase 身份验证令牌