回答我的問題
花費幾個小時後想通了。這裏的一步一步的過程,要求讀取和發佈權限
設置 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中選擇回調實例;在不同的Facebook用戶
有趣的是,FB SDK顯示了這個只有當你問的發佈許可。內部FB sdk通過使一個「我」與前一個(現有會話fbid)調用一個比較響應(返回值可以爲null)來驗證fbid,並且如果這兩個SDK之間存在差異,則會顯示此錯誤。
如何避免這種情況? - 確保您已經正確設置了FB應用程序的特殊包名稱。 - 這個讓我瘋了。不要使用代理。而使用代理android手機以某種方式FB SDK的內部「ME」調用來驗證FBID失敗,錯誤com.facebook.FacebookException:無法構造請求正文和圖形用戶變爲空,因此這個錯誤。雖然是有點奇怪,因爲我使用的是正常攔截代理提琴手
我希望這會有所幫助。
最後我想通了。一旦完全測試,我會發布完整的解決方案。 – user2095470