14

我试图弄清楚新 API 是如何工作的,所以我设法理解了这个概念,并设法做我自己的“hello world”,登录到 facebook,注销并尝试上传图像。

现在在 HelloFacebookSample 和 SessionLoginSimple 中,都有一个简单的 facebook 登录,在 HelloFacebookSample 中,当您单击“发布照片”时,会出现一个新的登录对话框,因为没有设置权限。

这是来自 HelloFacebookSample 的代码:

 private void performPublish(PendingAction action) {
    Session session = Session.getActiveSession();
    if (session != null) {
        pendingAction = action;
        if (session.getPermissions().contains("publish_actions")) {
            // We can do the action right away.
            handlePendingAction();
        } else {
            // We need to reauthorize, then complete the action when we get called back.
            Session.ReauthorizeRequest reauthRequest = new Session.ReauthorizeRequest(this, PERMISSIONS).
                    setRequestCode(REAUTHORIZE_ACTIVITY).
                    setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
            session.reauthorizeForPublish(reauthRequest);
        }
    }
}

因此,由于我们没有“publish_actions”,我们需要重新授权。

在 SimpleSessionLogin 中,登录看起来像这样:

private void onClickLogin() {
    Session session = Session.getActiveSession();
    if (!session.isOpened() && !session.isClosed()) {
        session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
    } else {
        Session.openActiveSession(this, true, statusCallback);
    }
}

所以,我不知道如何在登录期间请求权限。在几秒钟内使用完全相同的对话框登录服务两次,这有点奇怪,或者说是多余的。

对用户来说,这听起来有些不对劲或很奇怪。

我想用想要的权限登录 facebook 一次,但使用 API 3.0 会话调用,而不是已弃用的调用。

谁能解释一下如何?

4

5 回答 5

8

Session.OpenRequest有一个可以设置权限的方法。但是,对于 3.0 SDK,Facebook 现在要求开发人员分别请求“读取”和“发布”权限。因此,如果您的应用需要读取用户信息并代表他们发布,那么您需要调用 reauthorize。

于 2012-10-24T17:00:32.873 回答
6

好的,这是我使用 Facebook 的 3.0 SDK for Android 制作的对话框片段。它是封装的,这意味着所有 Facebook 功能都包含在片段中。这是一个对话框片段,因此它会在您正在运行的活动中弹出。此片段允许您登录,然后在您使用 Facebook 中包含的 UiHelper 类登录后启用某些视图。

public class FFragment extends DialogFragment {

private static final String TAG = "FacebookFragment";
private UiLifecycleHelper uiHelper;
private String mFilePath;
private Button shareButton, cancelButton;
private EditText mMessageText;
private TextView mMessageTitle;
private ProgressBar pBar;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.facebook_login, container, false);
    LoginButton authButton = (LoginButton) view
            .findViewById(R.id.authButton);
    authButton.setFragment(this);
    authButton.setPublishPermissions(Arrays.asList("publish_stream"));

    shareButton = (Button) view.findViewById(R.id.shareButton);
    mMessageText = (EditText) view.findViewById(R.id.facebook_post_text);
    mMessageTitle = (TextView) view.findViewById(R.id.facebook_post_title);
    cancelButton = (Button) view.findViewById(R.id.cancelButton);
    pBar = (ProgressBar) view.findViewById(R.id.facebook_pbar);
    cancelButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            FFragment.this.dismiss();

        }

    });
    shareButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            publishPhoto();

        }

    });
    return view;
}

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

    mFilePath = getArguments().getString("file_path");

    uiHelper = new UiLifecycleHelper(getActivity(), callback);
    uiHelper.onCreate(savedInstanceState);

}

/**
 * After user selects to upload photo
 */
private void publishPhoto() {
    pBar.setVisibility(View.VISIBLE);
    GraphObject graphObject;
    Bitmap bmap = BitmapFactory.decodeFile(mFilePath);

    ByteArrayOutputStream stream = new ByteArrayOutputStream();

    bmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);

    byte[] byteArray = stream.toByteArray();

    Bundle params = new Bundle();

    params.putByteArray("picture", byteArray);
    params.putString("message", mMessageText.getText() + " " + 
            getActivity().getResources().getString("String goes here"));

    Request request = new Request(Session.getActiveSession(), "me/photos",params, 
             HttpMethod.POST);

    request.setCallback(new Request.Callback() {

        @Override
        public void onCompleted(Response response) {
            if (response.getError()==null) {
                Toast.makeText(getActivity(), "Successfully posted photo", Toast.LENGTH_SHORT).show();
                FlurryAgent.logEvent(Globals.EVENT_FACEBOOK);
            } else {
                Toast.makeText(getActivity(), response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
            }
            pBar.setVisibility(View.GONE);
            FFragment.this.dismiss();

        }
    });
    request.executeAsync();




}
private void onSessionStateChange(Session session, SessionState state,
        Exception exception) {
    if (state.isOpened()) {
        Log.i(TAG, "Logged in...");
        // Check for reading user_photos permission  
        shareButton.setVisibility(View.VISIBLE);
        mMessageText.setVisibility(View.VISIBLE);
        mMessageTitle.setVisibility(View.VISIBLE);


    } else if (state.isClosed()) {
        Log.i(TAG, "Logged out...");
        shareButton.setVisibility(View.GONE);
        mMessageText.setVisibility(View.GONE);
        mMessageTitle.setVisibility(View.GONE);
    }

}


private Session.StatusCallback callback = new Session.StatusCallback() {
    @Override
    public void call(Session session, SessionState state,
            Exception exception) {
        onSessionStateChange(session, state, exception);

    }
};

@Override
public void onResume() {
    super.onResume();
    uiHelper.onResume();
    // For scenarios where the main activity is launched and user
    // session is not null, the session state change notification
    // may not be triggered. Trigger it if it's open/closed.
    Session session = Session.getActiveSession();
    if (session != null && (session.isOpened() || session.isClosed())) {
        onSessionStateChange(session, session.getState(), null);
    }
}

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

@Override
public void onPause() {
    super.onPause();
    uiHelper.onPause();
}

@Override
public void onDestroy() {
    super.onDestroy();
    uiHelper.onDestroy();
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    uiHelper.onSaveInstanceState(outState);
}

}

以下代码行是您将在活动中用于显示对话框的代码。

FFragment mFacebookFragment = new FFragment();
        Bundle args = new Bundle();
        args.putString("file_path", mFilePath);
        mFacebookFragment.setArguments(args);
        mFacebookFragment.show(getSupportFragmentManager(), "tag");

无论如何,如果您查看 onCreate 我们正在设置发布权限。默认情况下,片段启动时已经设置了读取权限。

也让你在清单中有这个。

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

其中@string/app_id 是您在开发者网站上创建 facbeook 应用程序时创建的应用程序 ID。还要确保下载新的 sdk facebook 项目并将其作为库项目引用。用于对话框布局的 XML 文件。

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >



<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical" >

    <com.facebook.widget.LoginButton
        android:id="@+id/authButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:layout_gravity="center_horizontal|top" />

    <TextView
        android:id="@+id/facebook_post_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:text="Message to post with photo"
        android:textColor="@android:color/white"
        android:textSize="18dp"
        android:textStyle="bold"
        android:visibility="gone" />

    <EditText
        android:id="@+id/facebook_post_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minLines="3"
        android:visibility="gone" />

    <Button
        android:id="@+id/shareButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:gravity="center"
        android:text="Post"
        android:textStyle="bold"
        android:visibility="gone" />

    <Button
        android:id="@+id/cancelButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Cancel"
        android:textStyle="bold" />
</LinearLayout>

<ProgressBar 
    android:id="@+id/facebook_pbar"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_gravity="center"
    android:visibility="gone"
    />

于 2012-12-02T05:48:32.237 回答
4

首次授权/登录应用程序时,您只能请求读取权限。我之前也尝试过这个新的 SDK,也有点困惑。

Facebook 希望用户对您的应用程序的发布能力更有信心,因此您必须在首次发布 OG 操作时重新授权发布权限。如果您查看 Foursquare 或 Instagram 发布 OG 的方式,他们有一个 Facebook 复选框或按钮,表示您想在 FB 上分享操作。您可以实现与此类似或我最终做的事情,即在用户授权应用程序后显示一个按钮,要求他们单击以启用向 Facebook 发布操作。

于 2012-10-24T22:52:26.333 回答
2

@Ming Li,当我使用创建会话时

public static final List<String> ALL_PERMISSIONS = Arrays.asList(       
            "read_friendlists",
            "publish_stream",
            "offline_access",
            "email",
            "read_stream",
            "user_location" ); 

session.openForPublish(new Session.OpenRequest(this).setPermissions(ALL_PERMISSIONS).setCallback(statusCallback).setRequestCode(100));

获得的会话具有(读取和发布)权限。所以我觉得想要同时获得读取和发布会话的用户可以使用 openForPublish() api。有用...!!

于 2013-04-09T03:43:05.167 回答
2

Facebook 3.0 api 确实存在限制,不能同时请求读取和发布。我确实找到了解决方法,但是您必须修改库。

只需将其添加到 Session.java:

public final void openForReadAndPublish(OpenRequest openRequest) {
        open(openRequest, null);
    }

这将导致它跳过引发异常的验证检查。当然,您现在可能需要做更多手动操作。您也可以在 Session 中注释掉 validatePermissions(openRequest, authType) 调用,这样您就可以传递您想要的任何权限。

于 2013-01-11T00:30:07.717 回答