回答我自己的问题
花了好几个小时才弄明白。这里分步询问读取和发布权限的过程
设置 Eclipse、Android、Facebook SDK 3.6
程序 MainActivity 和静态片段
想要实现?请求读取权限,然后发布权限。
MainActivity
public class YourFragmentActivity extends FragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Static Fragment
setContentView(R.layout.fragment_layout);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
}
}
YourFragment.java
public class YourFragment extends Fragment {
public static String TAG = YourFragment.class.getSimpleName();
private static final List<String> PERMISSIONS = Arrays.asList("publish_stream, publish_actions");
// Flag to represent if we are waiting for extended permissions
private Session.StatusCallback statusCallback = new SessionStatusCallback();
private Session.StatusCallback publishCallback = new PublishCallback();
private Button publish;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
buttonLoginLogout = (Button) view.findViewById(R.id.buttonLoginLogout);
publish = (Button) view.findViewById(R.id.publish);
//Make Sure you have session when you instantiate fragment
Session session = Session.getActiveSession();
if (session == null) {
if (savedInstanceState != null) {
session = Session.restoreSession(getActivity(), null, statusCallback, savedInstanceState);
}
if (session == null) {
session = new Session(getActivity());
}
Session.setActiveSession(session);
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
}
}
onSessionStateChange();
return view;
}
@Override
public void onStart() {
super.onStart();
Session.getActiveSession().addCallback(statusCallback);
}
@Override
public void onStop() {
super.onStop();
Session.getActiveSession().removeCallback(statusCallback);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Session session = Session.getActiveSession();
Session.saveSession(session, outState);
}
private void onSessionStateChange() {
Session session = Session.getActiveSession();
if(session.getPermissions().contains("publish_actions")){
//You got you updated token here with extended permissions
}
if (session.isOpened()) {
//Do you stuff here. e.g Getting accessToken, expiry etc.
}
else {
}
}
public void requestPublishPermissions(Activity activity, Session session, List<String> permissions, int requestCode) {
if (session != null) {
Session.NewPermissionsRequest reauthRequest = new Session.NewPermissionsRequest(activity, permissions).setRequestCode(requestCode);
reauthRequest.setCallback(publishCallback);
session.requestNewPublishPermissions(reauthRequest);
}
}
//Set this on onclick call of some button in you fragment
private void openForRead() {
Session session = Session.getActiveSession();
if (!session.isOpened() && !session.isClosed()) {
session.openForRead(new Session.OpenRequest(this).setCallback(statusCallback));
}
else {
Session.openActiveSession(getActivity(), this, true, statusCallback);
}
}
//Set this on onclick call of some logout button in you fragment
private void logMeOut() {
Session session = Session.getActiveSession();
if (!session.isClosed()) {
session.closeAndClearTokenInformation();
}
}
private class SessionStatusCallback implements Session.StatusCallback {
@Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange();
Debug.waitForDebugger();
if (exception != null){
//Handel your exception case here
Log.i(TAG, exception.getMessage());
}
}
}
private class PublishCallback implements Session.StatusCallback {
@Override
public void call(Session session, SessionState state, Exception exception) {
Debug.waitForDebugger();
onSessionStateChange();
if (exception != null){
//Handel your exception case here
Log.i(TAG, exception.getMessage());
}
}
}
}
您可能遇到的错误
这是最烦人的。当用户授予发布权限回调永远不会返回但相同
如果您的用户在 FB 中看到其应用设置页面,则表明该用户已授予发布权限
给你的应用程序。在这种情况下,从技术上讲,我们可以使用我们在 readForOpen 调用中收到的相同 accessToken,因为大多数时候即使在成功回调后 accessToken 也不会改变(这不是一个缺陷)。但是我们不能依赖这个,因为 FB 可以随时更改 accessToken。
如何避免这种情况?
-- 确保 onActivityResult 在您的 Fragment 和主 Activity 中都存在。并调用 Session.onActivityResult
-- 确保您正在为 newRequest 设置发布回调。 FB 使用 addCallback(newPermissionsRequest.getCallback()); 从 NewPermissionsRequest 中取回回调实例;
- 2) 用户以不同的 Facebook 用户身份登录
有趣的是,FB SDK 仅在您请求发布许可时才会显示此内容。在内部,FB sdk 通过“me”调用与之前的(现有会话 fbid)比较响应(返回可能为 null)来验证 fbid,如果这两个 SDK 之间存在差异,则会显示此错误。
如何避免这种情况?
-- 确保您已正确设置您的 FB 应用程序,特别是包名称。
——这让我发疯了。不要使用代理。在以某种方式使用代理 android 手机时,FB SDK 的内部“ME”调用以验证 FBID 失败,并出现错误 com.facebook.FacebookException: could not construction request body and graph user become null,因此出现此错误。虽然有点奇怪,因为我使用的是普通拦截代理的提琴手
我希望这会有所帮助。