如何在 Facebook SDK 4.0 中重新请求被拒绝的权限 (android)

How to re-ask declined permissions in Facebook SDK 4.0 (android)

我在下面查看了。它非常相似,但它不是我的问题。

How to re-request permissions in Facebook SDK 4.0

我获得了此代码的权限。

LoginManager.getInstance().logInWithReadPermissions(*fragment*, "user_friends");

如果用户拒绝 "user_friends" 权限,我无法在上面的代码中重新请求 "user_friends" 权限。因为在下次身份验证时自动拒绝。

我应该执行什么操作才能以编程方式获取 "user_friends"?

使用起来很简单

LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {
            Log.e(TAG, "LoginManager FacebookCallback onSuccess");

            if (loginResult.getAccessToken() != null) {
                Set<String> deniedPermissions = loginResult.getRecentlyDeniedPermissions();

                if (deniedPermissions.contains("user_friends")) {

                    LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("user_friends"));

                }
            }
        }

        @Override
        public void onCancel() {
            Log.e(TAG, "LoginManager FacebookCallback onCancel");
        }

        @Override
        public void onError(FacebookException e) {
            Log.e(TAG, "LoginManager FacebookCallback onError");
        }
    });

并且不要忘记在调用 setContentView(R.layout.main) 之前初始化 fb SDK 即

// Create callback manager to handle login response
    FacebookSdk.sdkInitialize(getApplicationContext());
    callbackManager = CallbackManager.Factory.create();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    fb = (ImageView) findViewById(R.id.authFacebook);
    setFacebookData(savedInstanceState);

    fb.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            LoginManager.getInstance().logInWithReadPermissions(MainActivity.this, Arrays.asList("public_profile", "email"));
        }
    });
}

private void setFacebookData(Bundle savedInstanceState) {
    FacebookSdk.sdkInitialize(MainActivity.this);
    callbackManager = CallbackManager.Factory.create();
    LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {

        @Override
        public void onSuccess(LoginResult result) {
            Log.i("LoginActivity","onSuccess Facebook Login"+result);
            GraphRequest request = GraphRequest.newMeRequest(
                    AccessToken.getCurrentAccessToken(), 
                    new GraphRequest.GraphJSONObjectCallback() { 
                        @Override 
                        public void onCompleted(JSONObject jsonObject, GraphResponse response) {
                            Log.d("","onCompleted jsonObject: "+jsonObject);
                            Log.d("","onCompleted response: "+response);
                        } 
                    }); 
            Bundle parameters = new Bundle();
            parameters.putString("fields", "id,name,link,cover,email");
            request.setParameters(parameters);
            request.executeAsync();
        }

        @Override
        public void onCancel() {
            // TODO Auto-generated method stub
        }

        @Override
        public void onError(FacebookException e) {
            // TODO Auto-generated method stub
            Log.e("LoginActivity","ERROR: "+e.getMessage());
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d("FbLogin", "Result Code is = " + resultCode +"");
    callbackManager.onActivityResult(requestCode, resultCode, data);
}

在清单文件中添加这些行

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

     <provider
        android:name="com.facebook.FacebookContentProvider"
        android:authorities="com.facebook.app.FacebookContentProvider355198514515820"
        android:exported="true" />
            <receiver android:name="laddu.fbexample.HelloFacebookBroadcastReceiver" >
        <intent-filter>
            <action android:name="com.facebook.platform.AppCallResultBroadcast" />
        </intent-filter>
    </receiver>

user2403096 的解决方案效果很好,但我遇到了一些问题并花了一些时间来解决它。如果用户通过控制台或其他方式撤销了某些权限,并且您在登录期间在您的应用程序中需要它(例如,我需要电子邮件权限),我使用 user2403096 的代码:

LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
    @Override
    public void onSuccess(LoginResult loginResult) {
      if (loginResult.getRecentlyDeniedPermissions().contains("email")) {
        LoginManager.getInstance().logInWithReadPermissions(
                this, (Collections.singletonList("email")));
         } else {
             performGraphRequest();
         }
    }

    @Override
    public void onCancel() {
        Log.e(TAG, "LoginManager FacebookCallback onCancel");
    }

    @Override
    public void onError(FacebookException e) {
        Log.e(TAG, "LoginManager FacebookCallback onError");
    }
});

performGraprhRequest() 只是通过 GraphRequest.newMeRequest(token, callback) 获取配置文件信息。因此,当您重新请求权限时,将回调到 onActivityResult,但不会再次调用 onSuccess()、onCancel() 或 onError()。我的做法是:

    @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    boolean processed = mCallbackManager.onActivityResult(requestCode, resultCode, data);
    if (!processed) {
        performGraphRequest();
    }
}

如果您登录 facebook 并输入您的凭据 - onActivityResult 将由 CallbackManager 处理,并且 return 为真。 CallbackManager 在后台检查您当前的 AccessToken 是否为空,如果您已经登录,然后您重新请求许可 - 您将拥有令牌和 callbackManager.onActivityResult return 错误。然后您可以调用 performGraphRequest 并将用户登录到您的应用程序。

只是对@Naveedumar 的回答的改进

你也可以

    LoginManager.getInstance()
.logInWithReadPermissions(MainActivity.this, 
new ArrayList<String>(AccessToken.getCurrentAccessToken().getDeclinedPermissions()) );