所以我正在开发一个 Android 应用程序(在 AS3 中使用 Adobe AIR),它应该列出公共 Twitter 帐户的时间线。我从来没有任何开发使用互联网请求的应用程序的经验。
我还听说twitter最近改变了他们的api。
任何机构可以帮助我吗?如何获取 json 或 xml 格式的非受保护帐户的时间线?以及身份验证如何在 AS3 中工作?
提前致谢
所以我正在开发一个 Android 应用程序(在 AS3 中使用 Adobe AIR),它应该列出公共 Twitter 帐户的时间线。我从来没有任何开发使用互联网请求的应用程序的经验。
我还听说twitter最近改变了他们的api。
任何机构可以帮助我吗?如何获取 json 或 xml 格式的非受保护帐户的时间线?以及身份验证如何在 AS3 中工作?
提前致谢
https://github.com/susisu/Twitter-for-AS3 使用它,就我可以测试而言,它工作得很好。
如果您需要它,这是我的实现示例,它可能会有所帮助:
package com.company.social {
import com.company.AppConst;
import com.company.IDestroyable;
import com.company.Main;
import com.company.displayassets.WebViewCloseStripe;
import com.company.events.TwitterControllerEvent;
import flash.display.BitmapData;
import flash.display.PNGEncoderOptions;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.LocationChangeEvent;
import flash.events.MouseEvent;
import flash.events.SecurityErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.utils.clearInterval;
import flash.utils.clearTimeout;
import flash.utils.setInterval;
import flash.utils.setTimeout;
import isle.susisu.twitter.Twitter;
import isle.susisu.twitter.TwitterRequest;
import isle.susisu.twitter.TwitterTokenSet;
import isle.susisu.twitter.events.TwitterErrorEvent;
import isle.susisu.twitter.events.TwitterRequestEvent;
public class TwitterController extends EventDispatcher implements IDestroyable {
private var _destroyed:Boolean;
private var _twitter:Twitter;
private var _token:TwitterTokenSet;
private var _twitterReq:TwitterRequest;
private var _stage:Stage;
private var _topStripe:WebViewCloseStripe;
private var _webView:StageWebView;
private var _pinExtractable:Boolean;
private var _activity:String;
private var _timeoutID:uint;
private var _pinTimeoutID:uint;
private static const ACTIVITY_LOGIN:String = "login";
private static const ACTIVITY_TWEET:String = "tweet";
private static const FILENAME:String = AppConst.TWITTER_FILE;
private static const CONSUMER_KEY:String = AppConst.TWITTER_CONSUMER_KEY;
private static const CONSUMER_SECRET:String = AppConst.TWITTER_CONSUMER_SECRET;
public function TwitterController(stage:Stage) {
_stage = stage;
init();
}
private function init():void {
var complete:Function;
checkForSettings();
_activity = ACTIVITY_LOGIN;
if (_token && _token.oauthToken.length) {
trace("token");
_twitter = new Twitter(CONSUMER_KEY, CONSUMER_SECRET, _token.oauthToken, _token.oauthTokenSecret);
_twitterReq = _twitter.account_verifyCredentials();
complete = verifyCompleteHandler;
}
else {
trace("no token");
_twitter = new Twitter(CONSUMER_KEY, CONSUMER_SECRET);
_twitterReq = _twitter.oauth_requestToken();
complete = tokenCompleteHandler;
}
setHandlersForRequest(complete);
startTimeout();
}
private function startTimeout():void {
trace("timeout start");
clearTimeout(_timeoutID);
_timeoutID = setTimeout(timeout, AppConst.TIMEOUT_TIME);
}
private function timeout():void {
trace("timed out");
clearTimeout(_timeoutID);
if(_twitterReq) {
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, tokenCompleteHandler);
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, verifyCompleteHandler);
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, pinRequestCompleteHandler);
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, tweetCompleteHandler);
_twitterReq.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
_twitterReq.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
_twitterReq.removeEventListener(TwitterErrorEvent.CLIENT_ERROR, errorHandler);
_twitterReq.removeEventListener(TwitterErrorEvent.SERVER_ERROR, errorHandler);
}
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.TIMEOUT));
}
private function stopTimeout():void {
trace("timeout stop");
clearTimeout(_timeoutID);
}
private function setHandlersForRequest(completeHandler:Function):void {
trace("set");
_twitterReq.addEventListener(TwitterRequestEvent.COMPLETE, completeHandler);
_twitterReq.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
_twitterReq.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
_twitterReq.addEventListener(TwitterErrorEvent.CLIENT_ERROR, errorHandler);
_twitterReq.addEventListener(TwitterErrorEvent.SERVER_ERROR, errorHandler);
}
private function removeHandlersForRequest(completeHandler:Function):void {
trace("remove");
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, completeHandler);
_twitterReq.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
_twitterReq.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
_twitterReq.removeEventListener(TwitterErrorEvent.CLIENT_ERROR, errorHandler);
_twitterReq.removeEventListener(TwitterErrorEvent.SERVER_ERROR, errorHandler);
}
private function verifyCompleteHandler(e:TwitterRequestEvent):void {
stopTimeout();
removeHandlersForRequest(verifyCompleteHandler);
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.LOGIN_COMPLETE));
}
private function tokenCompleteHandler(e:TwitterRequestEvent):void {
stopTimeout();
removeHandlersForRequest(tokenCompleteHandler);
var request:URLRequest = new URLRequest(_twitter.getOAuthAuthorizeURL());
_topStripe = new WebViewCloseStripe();
_topStripe.getCloseButton().addEventListener(MouseEvent.CLICK, closeClickHandler);
_stage.addChild(_topStripe);
_webView = new StageWebView();
_webView.addEventListener(LocationChangeEvent.LOCATION_CHANGE, locationChangeHandler);
_webView.addEventListener(Event.COMPLETE, locationCompleteHandler);
_webView.viewPort = new Rectangle(0, _topStripe.height, _stage.fullScreenWidth, _stage.fullScreenHeight - _topStripe.height);
_webView.stage = _stage;
_webView.assignFocus();
_webView.loadURL(request.url);
}
private function locationChangeHandler(e:LocationChangeEvent):void {
if (e.location.search("oauth_token") >= 0) {
trace("loc change outath_token, returning: "+e.location);
return;
}
else {
_pinExtractable = true;
trace("the magic should happen here: "+e.location);
}
}
private function locationCompleteHandler(e:Event):void {
if(_pinExtractable) {
_webView.loadURL("javascript:document.title=document.documentElement.innerHTML;");
_pinTimeoutID = setTimeout(extractPin, 16);
}
}
private function extractPin():void {
clearTimeout(_pinTimeoutID);
var pin:String = String(_webView.title.split('<kbd aria-labelledby="code-desc"><code>')[1]).split("<")[0];
trace("pin: "+pin);
if (pin && pin.toString() != "undefined") {
_webView.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, locationChangeHandler);
_webView.removeEventListener(Event.COMPLETE, locationCompleteHandler);
_webView.dispose();
_webView = null;
_topStripe.getCloseButton().removeEventListener(MouseEvent.CLICK, closeClickHandler);
_topStripe.destroy();
_stage.removeChild(_topStripe);
_topStripe = null;
_twitterReq = _twitter.oauth_accessToken(pin);
//request.addEventListener(TwitterRequestEvent.COMPLETE, pinRequestCompleteHandler);
setHandlersForRequest(pinRequestCompleteHandler);
startTimeout();
}
else {
_pinTimeoutID = setTimeout(extractPin, 100);
}
}
private function pinRequestCompleteHandler(e:Event):void {
stopTimeout();
removeHandlersForRequest(pinRequestCompleteHandler);
_token = _twitter.accessTokenSet;
saveSettings();
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.LOGIN_COMPLETE));
trace("tokens: "+_token.oauthToken, _token.oauthTokenSecret);
}
private function checkForSettings():void {
var file:File = File.applicationStorageDirectory.resolvePath(FILENAME);
var fileStream:FileStream = new FileStream();
if(file.exists) {
fileStream.open(file, FileMode.READ);
var data:Object = fileStream.readObject() as Object;
fileStream.close();
_token = new TwitterTokenSet(CONSUMER_KEY, CONSUMER_SECRET, data.oauthToken, data.oauthTokenSecret);
}
else {
_token = null
}
}
private function saveSettings():void {
var file:File = File.applicationStorageDirectory.resolvePath(FILENAME);
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeObject({oauthToken: _token.oauthToken, oauthTokenSecret: _token.oauthTokenSecret});
fileStream.close();
}
private function errorHandler(e:Event):void {
var request:TwitterRequest = e.currentTarget as TwitterRequest;
request.removeEventListener(TwitterRequestEvent.COMPLETE, tokenCompleteHandler);
request.removeEventListener(TwitterRequestEvent.COMPLETE, verifyCompleteHandler);
request.removeEventListener(TwitterRequestEvent.COMPLETE, pinRequestCompleteHandler);
request.removeEventListener(TwitterRequestEvent.COMPLETE, tweetCompleteHandler);
request.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
request.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
request.removeEventListener(TwitterErrorEvent.CLIENT_ERROR, errorHandler);
request.removeEventListener(TwitterErrorEvent.SERVER_ERROR, errorHandler);
if(_activity == ACTIVITY_LOGIN) {
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.LOGIN_ERROR));
}
else if(_activity == ACTIVITY_TWEET) {
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.TWEET_ERROR));
}
if(e is TwitterErrorEvent) {
trace(TwitterErrorEvent(e).statusCode.toString());
}
}
private function tweetCompleteHandler(e:Event):void {
trace("Tweet complete.");
stopTimeout();
removeHandlersForRequest(tweetCompleteHandler);
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.TWEET_COMPLETE));
}
private function closeClickHandler(e:MouseEvent):void {
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.CLOSE));
}
public function reset():void {
_token = new TwitterTokenSet("", "", "", "");
saveSettings();
dispatchEvent(new TwitterControllerEvent(TwitterControllerEvent.RESET));
}
public function tweet(message:String):void {
startTimeout();
_activity = ACTIVITY_TWEET;
_twitterReq = _twitter.statuses_update(message);
setHandlersForRequest(tweetCompleteHandler);
}
public function tweetWithImage(message:String, imageData:BitmapData):void {
startTimeout();
var byteArray:ByteArray = imageData.encode(new Rectangle(0, 0, imageData.width, imageData.height), new PNGEncoderOptions());
_twitterReq = _twitter.statuses_updateWithMedia(message, byteArray);
setHandlersForRequest(tweetCompleteHandler);
}
public function destroy():void {
if (_destroyed) return;
clearTimeout(_pinTimeoutID);
if(_twitterReq) {
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, tokenCompleteHandler);
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, verifyCompleteHandler);
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, pinRequestCompleteHandler);
_twitterReq.removeEventListener(TwitterRequestEvent.COMPLETE, tweetCompleteHandler);
_twitterReq.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
_twitterReq.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
_twitterReq.removeEventListener(TwitterErrorEvent.CLIENT_ERROR, errorHandler);
_twitterReq.removeEventListener(TwitterErrorEvent.SERVER_ERROR, errorHandler);
}
_twitterReq = null;
if(_webView) {
_webView.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, locationChangeHandler);
_webView.removeEventListener(Event.COMPLETE, locationCompleteHandler);
_webView.dispose();
_webView = null;
}
if(_topStripe) {
_topStripe.getCloseButton().removeEventListener(MouseEvent.CLICK, closeClickHandler);
_topStripe.destroy();
_stage.removeChild(_topStripe);
_topStripe = null;
}
_stage = null;
if(_twitter) _twitter = null;
if(_token) _token = null;
_destroyed = true;
}
public function isDestroyed():Boolean {
return _destroyed;
}
}
}