RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1144289
Accepted
V.March
V.March
Asked:2020-06-22 21:06:01 +0000 UTC2020-06-22 21:06:01 +0000 UTC 2020-06-22 21:06:01 +0000 UTC

Facebook 登录在 Android 应用程序中停止工作。(这又是 Facebook SDK 中的错误吗?)

  • 772

无法通过按钮登录安卓应用facebook。

在模拟器上,登录没问题。点击按钮后,出现输入登录名和密码的表格,输入数据并点击“登录”。将打开第二个窗口,其中显示“您以前使用此帐户登录过,您想继续吗?” 我单击继续,然后我从服务器收到带有数据的响应。

在真实设备上,当您单击按钮时,会打开一个用于在 facebook 中输入登录名和密码的表单。

我输入我的用户名和密码,然后单击“登录”按钮。

脸书登录表格

但点击后,按钮闪烁,没有其他反应。反复点击是没有用的。窗户本身并没有冻结。单击后控制台中不会出现错误。

AndroidStudio 日志中的最后几行:

2020-06-22 13:03:48.252 1603-1603/com.example.buttonlogintest I/Timeline: Timeline: Activity_launch_request time:3019160 intent:Intent { cmp=com.example.buttonlogintest/com.facebook.CustomTabMainActivity (has extras) } 
2020-06-22 13:03:48.279 1603-1603/com.example.buttonlogintest I/Timeline: Timeline: Activity_launch_request time:3019187 intent:Intent { act=android.intent.action.VIEW dat=https://m.facebook.com/... flg=0x40000000 pkg=com.android.chrome (has extras) }

清单代码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.buttonlogintest">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:screenOrientation="portrait"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:icon">

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

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

        <activity android:name=".MainActivityLoginFB">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

活动代码:

package com.example.buttonlogintest;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;

import androidx.appcompat.app.AppCompatActivity;

import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.login.LoginBehavior;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;

import java.util.Arrays;


public class MainActivityLoginFB extends AppCompatActivity implements View.OnClickListener {

    CallbackManager callbackManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_fb_btn);

        ImageButton loginImgBtn = (ImageButton) findViewById(R.id.buttonLoginFB);
        loginImgBtn.setOnClickListener(this);

        initFacebookSdk();

    }

    public void initFacebookSdk() {
        Log.e("MYTAG", "InComeActivity. initFacebookSdk");
//        FacebookSdk.sdkInitialize(this);
        callbackManager = CallbackManager.Factory.create();

        LoginManager.getInstance().registerCallback(callbackManager,
                new FacebookCallback<LoginResult>() {
                    @Override
                    public void onSuccess(LoginResult loginResult) {
                        Log.d("MYTAG", "Login");
                        Log.d("MYTAG", "Facebook getUserId: " + loginResult.getAccessToken().getUserId());
                    }

                    @Override
                    public void onCancel() {
                        Log.e("MYTAG", "InComeActivity. initFacebookSdk: onCancel");
                    }

                    @Override
                    public void onError(FacebookException exception) {
                        Log.e("MYTAG", "InComeActivity. initFacebookSdk: onError");
                    }
                });

    }

    @Override
    public void onClick(View view) {
        LoginManager loginManager = LoginManager.getInstance();
        loginManager.setLoginBehavior(LoginBehavior.NATIVE_WITH_FALLBACK);
        loginManager.logInWithReadPermissions(this, Arrays.asList("email"));
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        callbackManager.onActivityResult(requestCode, resultCode, data);
        super.onActivityResult(requestCode, resultCode, data);
    }
}

标记代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.buttonlogintest.MainActivity">

    <ImageButton
        android:id="@+id/buttonLoginFB"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginTop="32dp"
        android:elevation="4dp"
        android:padding="4dp"
        android:scaleType="fitXY"
        android:src="@drawable/ic_fb_logo"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

在生产应用程序上的行为相同。发布版本的开发版本 - 不适用于真实设备,但在模拟器上 - 它们可以工作。

如何解决这个问题呢?

android
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    V.March
    2020-07-02T14:36:37Z2020-07-02T14:36:37Z

    试错结果:

    事实证明,问题在于,在我智能手机上的 Chrome 浏览器中,禁止保存 cookie(以及许多不太渴望左右摸索数据的人)。而通过 Facebook 打开授权的表单只是基于 Chrome 的 WebView。除非您授予在 Chrome 中存储和读取 cookie 的权限,否则您将无法登录。好吧,原因找到了,facebook 想要访问 cookie。这有点离谱(但这是我个人的看法)。

    寻找解决方案。(不幸事件和来自facebook客户关注的“积极”海洋)

    事实上,现在有 2 个选项用于通过 Facebook 进行授权。通过系统(通常,此功能由提供WebView的系统接管)或通过 facebook 的应用程序。以下行负责启动登录过程时的这些选项:WebViewChrome-браузером

    LoginManager.getInstance().setLoginBehavior(LoginBehavior.NATIVE_WITH_FALLBACK);
    

    NATIVE_WITH_FALLBACK此标志表示“首先尝试使用 facebook 应用程序登录,如果没有应用程序则使用 登录WebView。”

    这正是障碍所在。如果没有应用程序,并且浏览器禁止 cookie,那么预计会出现一个错误,在CallbackManager该错误中可以对其进行处理并向用户显示,例如,一个请求访问 cookie 的弹出窗口。但是 facebook 已经接管了错误的处理,开发人员不会从服务器获得任何响应来处理。相反,登录表单将在屏幕顶部以小字体显示文本,例如:“您无权访问 cookie,但我们真的想存储 cookie。”

    我立刻想到的是:好吧,如果你想存储饼干,好吧,想要更进一步!我想通过只输入我帐户中的用户名和密码来登录。

    因此,通常会忽略此横幅。我已经成功完成了几次。如果您单击此文本中的链接,它会将您重定向到 chrome 中有关“cookie 是什么以及它们吃什么”的页面。也许在大量“有用且信息丰富”的信息中,一个勤奋的用户会找到有关如何在 chrome 中启用 cookie 的建议或说明,如果有这样做的愿望的话。事实上,在这段时间内,用户可以按照通常的方式进入应用程序 50 次,这通常是提供的第一个应用程序。

    因此,口号“两次点击授权!比以往任何时候都更容易!” 变成了多次尝试登录、重启手机、拆除和重新安装应用程序的史诗(这对 GooglePlay 统计数据有非常负面的影响)。有一种自然的感觉,他们想欺骗你。

    解决方案本身:

    除了SDK facebookflag 之外NATIVE_WITH_FALLBACK,还有几个。其中2个在这里派上了用场。

    WEB_VIEW_ONLY- 通过 WebView 登录,跳过检查应用程序是否已安装的时间。这样,您将始终通过 WebView 登录。但不是来自 Chrome,而是来自系统。

    NATIVE_ONLY- 仅通过应用程序登录。没有应用程序 - 登录将不起作用。

    使用这些标志,我们onError() CallbackManager将在 -a 中得到可以自己处理的错误。

    通过组合这些选项并进行分叉if-else,您可以获得解决方案。

    public class MainActivityLoginFB extends AppCompatActivity implements View.OnClickListener {
    
        private CallbackManager callbackManager;
        private LoginManager loginManager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main_fb_btn);
    
            initFacebookSdk();
            ImageButton loginImgBtn = (ImageButton) findViewById(R.id.buttonLoginFB);
            loginImgBtn.setOnClickListener(this);
    
        }
    
        public void initFacebookSdk() {
            Log.e("MYTAG", "InComeActivity. initFacebookSdk");
            // FacebookSdk.sdkInitialize(this); //В обновленном facebook-SDK это не нужно.
    
            callbackManager = CallbackManager.Factory.create();
    
            getLoginManager().registerCallback(callbackManager,
                    new FacebookCallback<LoginResult>() {
                        @Override
                        public void onSuccess(LoginResult loginResult) {
                            Log.d("MYTAG", "Login: onSuccess.");
                            Log.d("MYTAG", "Facebook getUserId: " + loginResult.getAccessToken().getUserId());
                        }
    
                        @Override
                        public void onCancel() {
                            Log.e("MYTAG", "Login: onCancel");
                        }
    
                        @Override
                        public void onError(FacebookException exception) {
                            Toast.makeText(getApplicationContext(), "onError: " + exception.toString(), Toast.LENGTH_LONG).show();
                            Log.e("MYTAG", "Login: onError. Error: " + exception.toString());
                            loginWithoutApp();
                        }
                    });
        }
    
        @Override
        public void onClick(View view) {
            loginWithApp();
        }
    
        LoginManager getLoginManager() {
            if (loginManager == null) {
                loginManager = LoginManager.getInstance();
            }
            return loginManager;
        }
    
        private void loginWithApp() {
            LoginManager.getInstance().setLoginBehavior(LoginBehavior.NATIVE_ONLY);
            loginManager.logInWithReadPermissions(this, Arrays.asList("email"));
        }
    
        private void loginWithoutApp() {
    
            getLoginManager().setLoginBehavior(LoginBehavior.WEB_VIEW_ONLY);
            loginManager.logInWithReadPermissions(this, Arrays.asList("email"));
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            callbackManager.onActivityResult(requestCode, resultCode, data);
        }
    }
    

    PS:我很乐意对代码优化提出建设性的批评和建议,或者问题的替代解决方案。

    • 2

相关问题

  • 来自片段的列表落后于 BottomNavigationView

  • 无法将变量从 Activity 传递到 Fragment

  • 构建与完成的片段略有不同的片段的最佳方法是什么?

  • 如何更改来自服务器的响应中的日期格式?

  • 谷歌地图在应用程序的发布版本中不起作用

  • 材料设计按钮。单击按钮上的可选区域!

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5