过去几天在facebook-sdk-for-android-wall上再次敲打我的脑袋需要帮助。我找不到什么是错的,我应该做什么,或者如何检查一些我缺少的状态。
我的Android应用程序正在录制曲目,对于曲目,用户必须选择将曲目摘要发布到他/她的Facebook时间线。我已经让它作为一个快乐的流程工作,但在测试不同的场景,如没有互联网连接等我现在卡在一个状态,我只得到“会话:尝试重新授权具有待处理请求的会话“ - 尝试重新授权权限时出现异常(即使恢复了互联网连接)。我正在使用facebook SDK for android和SSO。
package com.test;
import java.io.Fil...
...
public class FaceBookUtil {
public interface FacebookPostCallback {
void onComplete(String postId);
void onError(Exception e);
void onError();
}
private static final List<String> PERMISSIONS = Arrays.asList("publish_actions", "publish_stream");
private static final int REAUTH_ACTIVITY_CODE = 100;
public static void postToFaceBook(final Track track, final Activity activity, final FacebookPostCallback postCallback) {
try {
Session session = initFacebookSession(activity.getApplicationContext());
Session.setActiveSession(session);
StatusCallback statusCallback = new StatusCallback() {
@Override
public void call(Session session, SessionState state, Exception exception) {
try {
// Check for publish permissions
List<String> permissions = session.getPermissions();
if (!isSubsetOf(PERMISSIONS, permissions)) {
Session.ReauthorizeRequest reauthRequest = new Session
.ReauthorizeRequest(activity, PERMISSIONS)
.setRequestCode(REAUTH_ACTIVITY_CODE);
session.reauthorizeForPublish(reauthRequest); //Here's where it breaks and the exceptions is thrown.
return;
}
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook post test");
postParams.putString("caption", "Just a test");
postParams.putString("description", "A description");
postParams.putString("link", "http://www.google.com/");
Request.Callback reqCallback = new Request.Callback() {
public void onCompleted(Response response) {
String postId = null;
try {
FacebookException error = response.getError();
if (error != null)
throw error;
JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
postId = graphResponse.getString("id");
if (postId != null)
postCallback.onComplete(postId);
} catch (Exception e) {
postCallback.onError();
}
if (postId == null)
postCallback.onError();
}
};
Request postRequest = new Request(session, "me/feed", postParams, HttpMethod.POST, reqCallback);
RequestAsyncTask task = new RequestAsyncTask(postRequest);
task.execute();
} catch (Exception e) {
postCallback.onError(e);
}
}
};
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED))
session.openForRead(new Session.OpenRequest(activity).setCallback(statusCallback));
else if (!session.isOpened() && !session.isClosed()) {
OpenRequest req = new Session.OpenRequest(activity);
req.setCallback(statusCallback);
session.openForRead(req);
} else {
Session.openActiveSession(activity, true, statusCallback);
}
} catch (Exception e) {
postCallback.onError(e);
}
}
private static boolean isSubsetOf(Collection<String> subset, Collection<String> superset) {
for (String string : subset) {
if (!superset.contains(string)) {
return false;
}
}
return true;
}
private static Session initFacebookSession(Context context) {
Session session = Session.getActiveSession();
if (session != null)
return session;
/*
if (savedInstanceState != null)
session = Session.restoreSession(this, null, sessionStatusCallback, savedInstanceState);
*/
if (session == null)
session = new Session(context);
return session;
}
}
如果我调试到android SDK,我可以看到Session类中的reauthorize方法抛出了异常,因为pendingRequest不是null但是我不明白为什么,它设置的地方或我如何检查它,删除它或磨我应该做什么?
private void reauthorize(ReauthorizeRequest reauthorizeRequest, AuthorizationType authType) {
validatePermissions(reauthorizeRequest, authType);
validateLoginBehavior(reauthorizeRequest);
if (reauthorizeRequest != null) {
synchronized (this.lock) {
if (pendingRequest != null) { //Here's where the pendingRequest is already set and causes the exception...
throw new UnsupportedOperationException(
"Session: an attempt was made to reauthorize a session that has a pending request.");
}
switch (this.state) {
case OPENED:
case OPENED_TOKEN_UPDATED:
pendingRequest = reauthorizeRequest;
break;
default:
throw new UnsupportedOperationException(
"Session: an attempt was made to reauthorize a session that is not currently open.");
}
}
authorize(reauthorizeRequest);
}
}
我用Google搜索了没有任何结果的异常,非常感谢任何帮助。
另一方面,我可以重构整个FacebookUtil.postToFaceBook方法,但在测试时我将其保存在一个方法中以便于阅读。
答案 0 :(得分:8)
在要求更多权限时,您需要在当前Session上调用onActivityResult()方法:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Logger.d(LOGTAG, "onActivityResult");
if (RESULT_CANCELED == resultCode) {
mAuthorizationCanceled = true;
}
**mFacebookSession.onActivityResult(this, requestCode, resultCode, data);**
}
这样再次调用StatusCallback并删除pendingRequest。
答案 1 :(得分:5)
检查以确保在活动中添加了这行代码。
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
UiLifecycleHelper.onActivityResult();
}
答案 2 :(得分:2)
我在登录后询问用户是否有发布权限
这是我的SDK V3.0.1的代码
public class FacebookAccount extends FragmentActivity {
private UserSettingsFragment userSettingsFragment;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.facebook_login);
FragmentManager fragmentManager = getSupportFragmentManager();
userSettingsFragment = (UserSettingsFragment) fragmentManager
.findFragmentById(R.id.login_fragment);
userSettingsFragment.setReadPermissions(Utility.READ_PERMISSIONS);
userSettingsFragment
.setSessionStatusCallback(new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state,
Exception exception) {
if (state == SessionState.OPENED
&& !session.getPermissions().containsAll(
Utility.PUBLISH_PERMISSIONS)) {
session.requestNewPublishPermissions(new Session.NewPermissionsRequest(
FacebookAccount.this,
Utility.PUBLISH_PERMISSIONS));
}
if (session.isOpened()
&& state == SessionState.OPENED_TOKEN_UPDATED) {
//Save session access token
}
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (userSettingsFragment != null)
userSettingsFragment
.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
}
}
答案 3 :(得分:1)
当前一个会话没有关闭且没有正确打开时,就会发生这种情况,只是为了避免这种情况我在onResume中处理它,当状态为notOpend而notClosed然后setActive session null。它为我工作
public void onResume() { super.onResume(); 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); } else { Session.setActiveSession(null); } uiHelper.onResume(); }
答案 4 :(得分:0)
我猜Facebook只是不允许两个开放请求一起运行。
如果您只需要打开具有发布权限的会话(不在读取和发布之间切换),就可以轻松实现此目的。
转到源代码中的Sessions.java
,将此函数private static Session openActiveSession(Context context, boolean allowLoginUI, OpenRequest openRequest)
更改为public
。
使用此功能登录Facebook:
private void loginFacebook() {
Session session = Session.getActiveSession();
if (session == null) {
session = new Session(this);
}
Session.setActiveSession(session);
Session.OpenRequest request = new Session.OpenRequest(this).setCallback(statusCallback);
request.setPermissions(Arrays.asList(publishPermissions));
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
session.openForPublish(request);
} else {
session = Session.openActiveSession(this, true, request);
}
}
并使用此发布:
StatusCallback statusCallback = new StatusCallback() {
@Override
public void call(Session session, SessionState state, Exception exception) {
try {
Bundle postParams = new Bundle();
postParams.putString("name", "Facebook post test");
postParams.putString("caption", "Just a test");
postParams.putString("description", "A description");
postParams.putString("link", "http://www.google.com/");
Request.Callback reqCallback = new Request.Callback() {
public void onCompleted(Response response) {
String postId = null;
try {
FacebookException error = response.getError();
if (error != null)
throw error;
JSONObject graphResponse = response.getGraphObject().getInnerJSONObject();
postId = graphResponse.getString("id");
if (postId != null)
postCallback.onComplete(postId);
} catch (Exception e) {
postCallback.onError();
}
if (postId == null)
postCallback.onError();
}
};
Request postRequest = new Request(session, "me/feed", postParams, HttpMethod.POST, reqCallback);
RequestAsyncTask task = new RequestAsyncTask(postRequest);
task.execute();
} catch (Exception e) {
postCallback.onError(e);
}
}
};
答案 5 :(得分:0)
这很有可能,如果您要求在完成早期请求之前打开Facebook会话,则facebook sdk将抛出“UnsupportedOperationException”。这可能发生在用户发起的事件中,因此始终建议适当地处理该异常。
PS:在大多数情况下,您需要忽略这一点。
答案 6 :(得分:0)
为了在用户实际想要发布某些内容,某些活动以及不使用&#34; UiLifecycleHelper&#34;之前提供发布权限。这个方法对我有用(基于许多试验和本特定教程中的代码: https://developers.facebook.com/docs/games/mobile/android-tutorial/ https://developers.facebook.com/docs/facebook-login/permissions/)
首先创建权限请求(如果用户没有):
Session session = Session.getActiveSession();
if (PostOnFB.isChecked() && session != null && session.isOpened()) {
List<String> permissions = session.getPermissions();
if (!permissions.contains("publish_actions")) {
// if they choose to publish, then we request for publish permissions
Session.NewPermissionsRequest newPermissionsRequest =
new Session.NewPermissionsRequest(GetUserLocationActivity.this, Arrays.asList("publish_actions"))
.setDefaultAudience(SessionDefaultAudience.FRIENDS)
.setCallback(newPermissionsCallback)
.setRequestCode(REAUTH_ACTIVITY_CODE);
session.requestNewPublishPermissions(newPermissionsRequest);
} else {
publishResult();
}
}
where&#34; publishResult()&#34;是用户获得权限后将调用的方法。
接下来,为onActivityResult添加一个案例:
@Override
public void onActivityResult (
int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
case ..
..
..
..
..
case REAUTH_ACTIVITY_CODE :
Session.getActiveSession().onActivityResult(GetUserLocationActivity.this, requestCode, resultCode, data);
}
}
最后实现回调:
private Session.StatusCallback newPermissionsCallback = new Session.StatusCallback() {
@Override
public void call(Session session, SessionState state, Exception exception) {
if (exception != null || !session.isOpened() || !session.getPermissions().contains("publish_actions")) {
// this means the user did not grant us write permissions, so
// do whatever you think
} else {
publishResult();
}
}
};
那就是它。