Facebook android SDK重新打开会话

Posted

技术标签:

【中文标题】Facebook android SDK重新打开会话【英文标题】:Facebook android SDK reopens session 【发布时间】:2013-01-17 09:33:35 【问题描述】:

我正在开发一个集成 facebook 的应用程序,但遇到了一个非常奇怪的问题。

我正常登录,但是当我即将注销时,SDK 会强制再次登录...

package com.machinarius.facebook;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.facebook.Request;
import com.facebook.Request.GraphUserCallback;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.Session.NewPermissionsRequest;
import com.facebook.Session.StatusCallback;
import com.facebook.SessionState;
import com.facebook.model.GraphUser;

public class MainActivity extends Activity implements StatusCallback, GraphUserCallback 
    private TextView statusText;
    private Button loginButton;
    private Boolean loggedIn;
    private Session actualSession;

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

        loggedIn = false;
        statusText = (TextView)findViewById(R.id.statusText);
        loginButton = (Button)findViewById(R.id.loginButton);
    

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

    public void toggleFacebookLogin(View source) 
        if(!loggedIn) 
            actualSession = Session.openActiveSession(this, true, this);
        
        else 
            if(actualSession == null)
                return;
            else 
                actualSession.close();
                statusText.setText("Please login");
                loggedIn = false;
            
    

    @Override
    public void call(Session session, SessionState state, Exception exception) 
        if(state.equals(SessionState.OPENED)) 
            loggedIn = true;
            List<String> permissions = getNewPermissions(actualSession.getPermissions(), 
                    new LinkedList<String>(Arrays.asList("user_about_me", "user_birthday", "user_hometown", "user_relationships", "user_location", "user_relationships", "email")));
            Session.NewPermissionsRequest permissionsRequest = new NewPermissionsRequest(this, permissions);
            actualSession.requestNewReadPermissions(permissionsRequest);
            populateInterface();
         else 
            loggedIn = false;
        
    

    private void populateInterface() 
        Request.executeMeRequestAsync(Session.getActiveSession(), this);
    

    @Override
    public void onCompleted(GraphUser user, Response response) 
        if(response.getError() != null) 
            statusText.setText("There was an error fetching your info");
            Log.e(getClass().getName(), response.getError().toString());
            return;
        
        if(user != null) 
            statusText.setText("Hello " + user.getName() + "\n"
                    + "Your user ID is " + user.getId() + "\n"
                    + "Your birthday is " + user.getBirthday());
            loginButton.setText("Log out");
         else 
            statusText.setText("There was an error fetching your info");
        
    

    private List<String> getNewPermissions(List<String> actualPermissions, List<String> desiredPermissions) 
        ArrayList<String> permissionsGranted = new ArrayList<String>();
        for(String nPermission : desiredPermissions)
            for(String aPermission : actualPermissions)
                if(nPermission.equals(aPermission))
                    permissionsGranted.add(nPermission);
        for(String gPermission : permissionsGranted)
            desiredPermissions.remove(gPermission);
        return desiredPermissions;
    

toggleFacebookLogin 由 loginButton 上的 XML onClick 处理程序调用。

还有一个问题,我如何将权限请求集成到 session.open 调用中,这样我就不必让用户看到两次 Facebook 对话框?

【问题讨论】:

【参考方案1】:

这里的问题是你只检查

state.equals(SessionState.OPENED)

在您的 call 方法中,而不是

state.isOpened()

因此,当您请求其他权限时,状态实际上会转换为 OPENED_TOKEN_UPDATED,现在您的已登录状态为 false(即使它应该为 true)。因此,当您单击该按钮时,您将再次调用 openActiveSession,因为您的已登录状态不正确。如果您切换到检查state.isOpened(),它应该可以解决您的问题。

要回答您的第二个问题,由于您只请求读取权限,因此您可以在打开会话时一次性请求所有权限(而如果您还想请求发布权限 - 例如 publish_stream,那么您需要分开请求)。要一次完成所有操作,您需要将 Session.openActiveSession(this, true, this) 替换为以下内容:

Session actualSession = new Session(this);
Session.setActiveSession(actualSession);
actualSession.openForRead(new Session.OpenRequest(this).setPermissions(Arrays.asList("some", "read", "permissions")).setCallback(this));

注意:以上是我写的,所以可能有语法错误。

【讨论】:

以上是关于Facebook android SDK重新打开会话的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式清除 Android 上的 Facebook SDK 4.0 会话

使用 Facebook Android SDK 在 Facebook 墙上发帖,无需打开对话框

Facebook Android SDK & java.lang.NullPointerException

通过 facebook android sdk 分享墙帖

在 Android 上使用 facebook SDK 会给出“用户以不同的 Facebook 用户身份登录”。错误

Facebook Android SDK 注销监听器