在我的应用中,我首先询问用户第一个基本权限,并在需要时发布。客户端本身不会对accessToken做任何事情,只是将它传递给服务器。
1)获得基本权限后,客户端立即将其发送到服务器。 2)当客户端请求发布权限时问题开始。用户授予发布权限后,我的会话仍会显示旧的基本权限。但是,如果我同时检查fb上的用户设置,则表明应用已授予发布权限。但不知何故在应用程序中我没有得到 更新了accessToken。
这就是我为发布权限所做的事情
private void requestPublishPermissions(Session session) {
if (session != null) {
Session.NewPermissionsRequest newPermissionsRequest = new Session.NewPermissionsRequest(this, PERMISSION)
// demonstrate how to set an audience for the publish permissions,
// if none are set, this defaults to FRIENDS
.setDefaultAudience(SessionDefaultAudience.FRIENDS)
.setRequestCode(REAUTH_ACTIVITY_CODE);
session.requestNewPublishPermissions(newPermissionsRequest);
}
}
一旦用户授予权限(当调用此方法时),此方法调用之后的下一个Session.StatusCallback仍会显示旧的会话权限。
我的问题: 1)如何在发布permisison批准后立即刷新accessToken? 2)如果(1)不可能,那么正确的做法是什么?因为来自客户的电话必须与 更新了accessToken。是否让用户等到我们获得更新的accessToken?如果是的如何?
感谢。
答案 0 :(得分:2)
回答我自己的问题
花了几个小时后想出来了。这里一步一步询问读取和发布权限
设置 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。并调用Session.onActivityResult
- 确保您要为newRequest设置发布回调。 FB使用addCallback(newPermissionsRequest.getCallback())从NewPermissionsRequest返回回调实例;
有趣的是,只有当您要求发布权限时,FB SDK才会显示此信息。内部FB sdk通过使用“my”调用比较响应(返回可以为null)与之前的(现有会话fbid)之一来验证fbid,如果这两个SDK之间存在差异则显示此错误。
如何避免这种情况? - 确保您已正确设置FB应用程序包名称。 - 这个让我疯了。不要使用代理。而使用代理Android手机不知何故FB SDK的内部“ME”调用验证FBID失败,错误com.facebook.FacebookException:无法构造请求体和图形用户变为null,因此这个错误。虽然是有点奇怪,因为我使用的是正常拦截代理的小提琴手
我希望这会有所帮助。