Adobe Air & Adobe Flex & ActionScript & Mobile Dev & HTML5 & RIA & User Experience
大家好,我是奶綠茶
最近案子的需要,所以會用 Android 和 AIR 來混搭開發 app
遇到的問題有:
1.Android 怎麼啟動另一個 App(Andoird or AIR) ?
2.啟動後,如何帶變數過去?
3.反過來 AIR 啟動 Andoird 且帶值?
先了解 Android 怎麼啟動另一個 App.
使用 Intent 類別, 且指定要啟動的 app package路徑
Intent intent = new Intent( Intent.ACTION_MAIN , null); intent.addCategory( Intent.CATEGORY_LAUNCHER); final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary"); intent.setComponent(cn); startActivity(intent);
如果是要啟動 AIR 的 app. 就要在 package 前加上 air.
new ComponentName(“air.com.android.settings”, “air.com.android.settings.fuelgauge.PowerUsageSummary”);
第二個問題是啟動後,如何帶變數過去?
只要在 intent 使用 putExtra 即可 intent.putExtra(“Key”, “Value”);
接收的 Activity 在 onCreate();
使用 getIntent().getExtras().getString(“Key”);
但在 AIR 的部份,無法修改 onCreate ,所以只好找另外的方法。
好在 Android 的機制裡,可以使用 scheme 的方法呼叫, 像 market:// 這樣,
當遇到這樣的連結時,只要 app 有在 mainfest 設定 intent-filter 的話,就會啟動該 app.
在這我們以:testapp:// 為例 Android 端:
Uri uri = Uri.parse("testapp://com.example/milkmidi/tesetdata"); intent = new Intent( Intent.ACTION_VIEW, uri);
AIR 端:在 application.xml 裡加上 <data android:scheme=”testapp” android:host=”com.example” />
當遇到是 testapp://com.example 這樣的連結時,就可以啟動 AIR 的 app.
<android>
<manifestAdditions><![CDATA[
<manifest android:installLocation="auto">
<application>
<activity >
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="testapp" android:host="com.example" />
</intent-filter>
</activity>
</application>
</manifest>
]]></manifestAdditions>
</android>得到變數可以使用:
NativeApplication.nativeApplication.addEventListener( InvokeEvent.INVOKE, onInvoke); private function onInvoke(e:InvokeEvent):void { log( "onInvoke:" + e.arguments ); }
參考文章:
http://www.riaspace.com/2011/08/defining-custom-url-schemes-for-your-air-mobile-applications
http://stackoverflow.com/questions/5591086/passing-parameters-from-a-java-activity-to-adobe-air-app
http://www.slideshare.net/CodeAndroid/android-intent-intent-filter-broadcast-receivers
大家好,我是奶綠茶
在 Android 裡可以使用 WbeView 來包一個 flash 的網頁
但在 3.0 以上的版本要再多加一些設定,才能讓 flash 順利出現。
在 AndroidManifest.xml 加入這二段即可
uses-sdk android:minSdkVersion=”11″
application android:hardwareAccelerated=”true”
大家好,我是奶綠茶
今天來介紹一下 Adobe AIR ServerSocket
需求:
很多台電腦,在同一個區網,要能彼此溝通,同時 Android 平版也要能傳接值。
解:
本來想如果就只有單 flash 的話, 可以使用 P2P 區網連線就決解了,
但因為 Andriod 平版也要能支援, 所以就改成 Socket 來溝通。
那為什麼不用 Java 架 Socket Server 就好了,因為我是閃客(因為用 Java 做動畫會死人)
AIR 端,使用ServerSocket 類別。
在畫面上就只放所有連線的 Client 列表,一個發送訊息的文字和Button, 一個接收的文字
<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="createComplete(event);" close="appCloseHandler()"> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <fx:Script> <![CDATA[ import flash.display.NativeWindow; import flash.events.Event; import flash.events.ProgressEvent; import flash.events.ServerSocketConnectEvent; import flash.net.ServerSocket; import flash.net.Socket; import flash.utils.ByteArray; import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.events.FlexEvent; private var server :ServerSocket = new ServerSocket(); [Bindable] private var serverActivity:Boolean = false; [Bindable] private var clientSockets:ArrayCollection = new ArrayCollection(); //private var ipAddress :String = "192.168.253.176"; private var ipAddress :String = "127.0.0.1"; private var ipAddressPort :int = 9527; private function createComplete(e:FlexEvent):void { try { server.bind(ipAddressPort, ipAddress); log( "bind:" + ipAddress+":"+ipAddressPort ); server.addEventListener(ServerSocketConnectEvent.CONNECT , clientConnectedHandler); server.listen(); serverActivity = true; }catch (err:Error){ log( err + "" ); serverActivity = false; Alert.show(err.message); } } private function clientConnectedHandler(e:ServerSocketConnectEvent):void { //每當有新的 Client 連該進來, 就會觸發該函式。 var clientSocket:Socket = e.socket; log( clientSocket.localAddress + ":" + clientSocket.localPort ); clientSockets.addItem( clientSocket ); clientSocket.addEventListener(Event.CLOSE , clientDisconnectedHandler); //偵聽當 Client 離線時。 clientSocket.addEventListener(ProgressEvent.SOCKET_DATA, onClientSocketData ); //偵聽 Client 發出的訊息 } private function onClientSocketData(e:ProgressEvent):void { // 讀取 Client 發出的訊息 var buffer:ByteArray = new ByteArray(); var clientSocket:Socket = e.currentTarget as Socket; clientSocket.readBytes( buffer, 0, clientSocket.bytesAvailable ); log( "Received: " + buffer.toString() ); } private function clientDisconnectedHandler(e:Event):void { // 當 Client 離線時。 e.currentTarget.removeEventListener( e.type , arguments.callee ); clientSockets.removeItemAt( clientSockets.getItemIndex(e.target)); } private function log(o:Object):void { textArea.text += o +"\n"; } private function writeDataToSockets(e:Event):void { var msg:String = textInput.text; if (msg == "") { return; } trace( "ServerSocketMain.writeDataToSockets "); // 對所有的 Client 發出訊息。 for each (var socket:Socket in clientSockets) { if (socket.connected) { try { socket.writeUTF(msg); socket.flush(); }catch (err:Error){ log(err); } } } } private function appCloseHandler():void { server.close(); server = null; } ]]> </fx:Script> <s:HGroup width="100%" height="100%" paddingLeft="5"> <s:List width="200" height="100%" dataProvider="{clientSockets}" labelField="localAddress"></s:List> <s:VGroup width="100%" height="100%"> <s:HGroup width="600"> <s:TextInput id="textInput" width="200" text="server send info to all client" /> <s:Button x="130" y="10" label="Send" click="writeDataToSockets(event)" enabled="{textInput.text.length>0}" visible="{clientSockets.length>0}" /> </s:HGroup> <s:Button label="clear" click="{textArea.text=''}" enabled="{serverActivity}"/> <s:TextArea id="textArea" width="200" height="100%" editable="false" /> </s:VGroup> </s:HGroup> </s:WindowedApplication>
在用 flash 寫一個 Client 端測試:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" creationComplete="createSocket(event)"> <s:layout> <s:VerticalLayout /> </s:layout> <fx:Script> <![CDATA[ import flash.events.Event; import flash.events.ProgressEvent; import flash.net.Socket; import mx.events.FlexEvent; protected var socket:Socket; private var ipAddress :String = "127.0.0.1"; private var ipAddressPort :int = 9527; protected function createSocket(event:FlexEvent):void { socket = new Socket(); socket.addEventListener(Event.CONNECT,socketConnected); socket.addEventListener(ProgressEvent.SOCKET_DATA, socketData); socket.connect( ipAddress, ipAddressPort ); } protected function socketConnected(e:Event):void{ log("client - socket connected"); } protected function socketData(e:ProgressEvent):void{ trace("client - socket data"); //trace(socket.readUTF()); log(socket.readUTF()); } private function callServerClickHandler():void { try { socket.writeUTF("callServer"); socket.flush(); }catch (err:Error){ log(err); } } private function log(o:Object):void { textArea.text += o + "\n"; } ]]> </fx:Script> <s:Button label="call Server" click="callServerClickHandler()" /> <s:TextArea id="textArea"></s:TextArea> </s:Application>
Java/Android 端
使用 Socket 類別
因為程式碼落落長,
有需要的朋友就直接下載 Android 端的程式碼,在這就不貼出來了
大家好,我是奶綠茶
最近學生問起了一個 3D 的 Banner 效果要如何製作
寫了一個簡單的 Demo, 程式碼也很短,
只用到 TweenMax , 和 FlashPlayer10 的 3D 即可做到
import com.greensock.TweenMax; var container:Sprite = new Sprite(); container.x = stage.stageWidth >> 1; addChild( container ); addEventListener(Event.ENTER_FRAME , enterFrameHandler); var back:MovieClip = new Back_mc; back.x = stage.stageWidth >>1; back.y = 40; back.visible=false; addChild( back ); back.addEventListener(MouseEvent.CLICK , function(){ showBack(false); }); (function () { for(var i:int = 0 ; i 90 ){ container.visible = false; back.visible = true; } } }else{ _update = function () { if( container.rotationY < 90 ){ container.visible = true; back.visible = false; } } _onComplete = function () { addEventListener(Event.ENTER_FRAME , enterFrameHandler); } } TweenMax.to( container , .7 , { rotationY:_targetV, onUpdate:_update, onComplete:_onComplete }); TweenMax.to( back , .7 , { rotationY:_targetV }); } function enterFrameHandler (e:Event):void { var _value:Number = stage.stageWidth*.5 - mouseX; _value *= 0.05; container.rotationY += (_value - container.rotationY)/10; }
转自 iApp4Me.com创始人 @tinyfool 老师。