在Air上面使用 FB Mobile Api遇到一個問題...
就是預設的 FB 登入畫面並沒有取消登入的按鈕 所以就自己加了一顆按鈕在 FB 登入視窗的 StageWebView 外面(右上角X)
本想要讓 USER 點了按鈕後可以將 StageWebView 給拿掉 不管是改變 viewport 或是直接 dispose
所以一開始就先宣告了一個 StageWebView 使用這個 StageWebView 來處理有關 FB 的部分
private var _swv:StageWebView;
當點了取消登入 就去
_swv.viewport=new Rectangle();
不過有時要做這動作時 都會發生錯誤 錯誤原因是原本給 FB 用的 StageWebView 已經變成 null 當然就沒法進行操作
看了一下 當登入成功或失敗 在 MobileLoginWindow.as 的 handleLocationChange() 會將原本的 StageWebView 給 dispose
所以這時就不能再對餵給 FB 的 StageWebView 進行操作 看起來似乎沒有問題 不過 如果這時 USER 執行登出 並再次登入
因為原本的 _swv 已經被 dispose 所以當要再重新指定 viewport 或餵給 FB 就會發生錯誤
所以改了一下 FB 的 API
MobileLoginWindow.as
protected function handleLocationChange(event:Event):void
{
var location:String = webView.location;
if (location.indexOf(FacebookURLDefaults.LOGIN_FAIL_URL) == 0 || location.indexOf(FacebookURLDefaults.LOGIN_FAIL_SECUREURL) == 0)
{
webView.removeEventListener(Event.COMPLETE, handleLocationChange);
webView.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, handleLocationChange);
loginCallback(null, FacebookDataUtils.getURLVariables(location).error_reason);
userClosedWindow = false;
//webView.dispose();
//webView=null;
}
else if (location.indexOf(FacebookURLDefaults.LOGIN_SUCCESS_URL) == 0 || location.indexOf(FacebookURLDefaults.LOGIN_SUCCESS_SECUREURL) == 0)
{
webView.removeEventListener(Event.COMPLETE, handleLocationChange);
webView.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, handleLocationChange);
loginCallback(FacebookDataUtils.getURLVariables(location), null);
userClosedWindow = false;
//webView.dispose();
//webView=null;
}
}
另外在 FacebookMobile.as 的 login() 不知WHY要每次呼叫登入都會產生一個新的 MobileLoginWindow
((可能是 FB 認為每次 StageWebView 都是全新的))
protected function login(callback:Function, stageRef:Stage, extendedPermissions:Array, webView:StageWebView = null, display:String = 'touch'):void {
this.loginCallback = callback;
this.stageRef = stageRef;
if (!webView) {
this.webView = this.createWebView();
} else {
this.webView = webView;
this.webView.stage = this.stageRef;
}
this.webView.assignFocus();
if (applicationId == null) {
throw new Error(
'FacebookMobile.init() needs to be called first.'
);
}
//開過了就不再多開了
if (loginWindow == null) {
loginWindow = new MobileLoginWindow(handleLogin);
loginWindow.open(this.applicationId,
this.webView,
FacebookDataUtils.flattenArray(extendedPermissions),
display
);
}else {
loginWindow.directShowWindow();
}
}
還有
protected function handleLogin(result:Object, fail:Object):void {
//loginWindow.loginCallback = null; //因為不重複開LOGINWINDOW所以不清掉CALLBACK
....
回到 MobileLoginWindow.as 加上
public function directShowWindow():void {
showWindow(loginRequest);
}
這樣就 OK 了~
之後要關閉 FB 登入視窗 就直接 _swv.viewport=new Rectangle();
記得原本登入成功或失敗 都會去 call 的 loginCallback 自己加上 _swv 的後續處理
不太確定這方法對不對 還是有誤會 FB 原本的用法 但至少目前用起來還蠻 OK 的~

沒有留言:
張貼留言