Adobe AIR移動App的互相調用實現方式


在使用Adobe AIR進行移動應用開發的時候,我們或許會有這樣的需求:假如我們開發的是兩個應用(A和B),同時安裝到手機上,那么能否在A中呼叫B並傳遞參數呢(或者反過來B操作后,再把參數返回給A)。目前AIR還沒有直接呼叫某個APP的API,但我們可以使用手機特有的特性來實現。

第一種方式:使用ANE

假如我們的目標平台是Android,那么可以確定的是,Java是可以呼叫一個APP並傳遞參數的,所以我們可以借助Java實現的ANE來調用另一個APP(只要知道另一個APP的ID就可以了)。

首先打開Eclipse,創建一個Android項目,引入FlashRuntimeExtensions.jar,編寫Extension,Context和Function(具體過程不再細述了,可以參閱創建ANE的初級教程),也可以在稍后的鏈接中下載Java部分的代碼。主要是實現callApp這個Function,代碼如下:

package com.techmx.extensions;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;
 
public class CallAppFunction implements FREFunction {
 
    @Override
    public FREObject call(FREContext arg0, FREObject[] arg1) {
        FREObject result = null;
        String appPackage;
        String appID;
        Intent myIntent = new Intent();
        try {
            Activity currentActivity = arg0.getActivity();
            appPackage = arg1[0].getAsString();
            appID = arg1[1].getAsString();
            myIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            myIntent.setAction(Intent.ACTION_MAIN);
            myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            myIntent.setData(Uri.parse(arg1[2].getAsString()));
            myIntent.setClassName(appPackage, appID);
            currentActivity.startActivity(myIntent);
        } catch (Exception e) {
            // TODO: handle exception
        }
        return result;
    }
}

然后打開Flash Builder,創建一個庫項目,和Java部分的接口相對應:

package com.techmx.extensions
{
    import flash.events.EventDispatcher;
    import flash.events.IEventDispatcher;
    import flash.external.ExtensionContext;
 
    /**
     * 通過一個傳遞的ID,啟動另外一個應用
     */
    public class CallAppExtension extends EventDispatcher
    {
        public static const CALL_APP:String = "callApp";
        public static const EXTENSION_ID:String = "com.techmx.extensions.CallAppExtension";
        private var extContext:ExtensionContext;
 
        public function CallAppExtension(target:IEventDispatcher=null)
        {
            extContext = ExtensionContext.createExtensionContext(EXTENSION_ID,"");
        }
 
        public function callApp(appPackage:String,appID:String,customURI:String):void
        {
            if(extContext)
            {
                extContext.call(CALL_APP,appPackage,appID,customURI);
            }
        }
    }
}

然后就可以拿出SWC,和Java項目導出的JAR一起,打包為ANE文件。整個項目工程(包括ANE文件)可以點擊這里下載:ANEPack2

然后我們就可以創建兩個測試項目:MobileA和MobileB,類型都是ActionScript手機項目。在MobileA中,引入剛才創建的ANE文件,並調用擴展的方法來呼叫另一個應用,也就是MobileB。

MobileA的主體代碼:

package
{
    import com.techmx.extensions.CallAppExtension;
 
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.net.*;
 
    public class MobileA extends Sprite
    {
        public function MobileA()
        {
            super();
            var btn:Sprite = new Sprite();
            btn.graphics.beginFill(0x000000,1);
            btn.graphics.drawCircle(50,50,50);
            btn.graphics.endFill();
            addChild(btn);
            btn.addEventListener(MouseEvent.CLICK,clickHandler);
        }
 
        protected function clickHandler(event:MouseEvent):void
        {
            var extension:CallAppExtension = new CallAppExtension();
            //注意ID的規則,AIR會自動補上"air."和".AppEntry"
            extension.callApp("air.MobileB","air.MobileB.AppEntry","myarguments://me=neo&you=jack");
        }
    }
}

注意擴展方法的第三個參數,我們可以用自定義URI的方式傳遞參數,這里寫的是myarguments,實際上你寫成其它的值也沒有關系,都可以傳遞過去。

在MobileB中,則可以生成一個文本對象,來顯示收到的參數:

package
{
    import flash.desktop.NativeApplication;
    import flash.display.Sprite;
    import flash.events.InvokeEvent;
    import flash.text.TextField;
    import flash.text.TextFormat;
 
    [SWF(width="320",height="480")]
    public class MobileB extends Sprite
    {
        private var label:TextField;
 
        public function MobileB()
        {
            super();
            label = new TextField();
            var format:TextFormat = new TextFormat(null,28);
            label.width = 320;
            label.height = 480;
            label.defaultTextFormat = format;
            addChild(label);
            NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke);
        }
 
        private function onInvoke(event:InvokeEvent):void
        {
            label.text = "Reason: "+event.reason;
            label.appendText("\n"+"Arguments: " + event.arguments);
        }
    }
}

將兩個應用全部安裝到手機上,然后打開MobileA,就可以點擊黑色的圓圈呼叫MobileB。

 

第二種方式:使用自定義URI

使用ANE的方式,可以最大程度的使用底層API的便利,但對於項目還是不太方便。如果只是呼叫另一個APP的話,所幸我們還有另一個選擇,就是使用自定義的URI。

這種方式就要求我們對那個需要被調用的應用(在這個例子中就是MobileB),在配置文件中注冊一個自定義的URI,比如我們要注冊一個“todoair”的URI,需要在配置文件中同時更改Android部分的定義和iOS部分的定義(如果您還要部署到iOS的話)。

<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="todoair"/>
                     </intent-filter>
                 </activity>
              </application>
              <uses-permission android:name="android.permission.INTERNET"/>
            </manifest>
 
        ]]></manifestAdditions>
</android>
<iPhone>
        <InfoAdditions><![CDATA[
            <key>UIDeviceFamily</key>
            <array>
                <string>1</string>
                <string>2</string>
            </array>
            <key>CFBundleURLTypes</key>
            <array>
                <dict>
                    <key>CFBundleURLSchemes</key>
                    <array>
                        <string>todoair</string>
                    </array>
                    <key>CFBundleURLName</key>
                    <string>MobileB</string>
                </dict>
            </array>
        ]]></InfoAdditions>
        <requestedDisplayResolution>high</requestedDisplayResolution>
</iPhone>

然后先把MobileB打包安裝到手機,接着來修改MobileA的代碼,將調用方式修改為:

protected function clickHandler(event:MouseEvent):void
{
    //URL方式
    //navigateToURL(new URLRequest("todoair://me=neo&you=jack"));
}

這就可以了,打包MobileA到手機,運行效果和剛才基於ANE的方式是類似的:

 

這個方式不需要編寫原生代碼來配合,使用簡單,但是一定要在配置文件中注冊URI才會生效。另外您應該也注意到了,它使用navigateToURL來調用,說明這個方式用網頁也是可行的。您可以在您的WEB網站上,用HTML中的A鏈接,結合注冊的自定義URI,來啟動您的應用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM