作成日

28 August 2008

はじめに

この記事の発端は、 2008 年に行われた第 1 回 Adobe AIR コンテストに著者がエントリーした AIR アプリケーション『 AIR ThermoHygrometer 』です。

コンテスト終了後日、Flex User Group の勉強会で開発手法を紹介した縁で、本記事を公開するに至ります。

開発環境

AIR ThermoHygrometer の紹介

開発手法を解説する前に、AIR ThermoHygrometer の紹介をします。AIR ThermoHygrometer は、Adobe Flex Builder 3 Professional を使って開発した、温湿度計デバイス連動 AIR アプリケーションです。1 秒ごとに温度と湿度を計測し、Flex 3 の AreaChart コンポーネントを用いて、リアルタイムに描画更新される「過去 60 秒間の温度と湿度の推移グラフ」を作成します。

使用デバイス

AIR ThermoHygrometer は、ストロベリーリナックス社の『 USB 温度・湿度計モジュール』を使用しています。プラグアンドプレイで動作するので、ドライバのインストールなどは一切不要で、USB ポートに接続したらすぐ使用できるというお手軽デバイスです。

AIR アプリケーション (SWF) とデバイス間の通信方式を選定する

AIR アプリケーション (SWF) とデバイス間は直接通信できないので、間を取り持つブリッジアプリケーションを開発する必要があります。ブリッジアプリケーションを開発するにあたり、いくつかの手段の中から通信方式を選択することができます。

ソケットを用いたり、LocalConnection を直接ハックしたりと、さまざまな実現方法がありますが、「工期を短くする」「アプリケーションの配布を容易にする」などの事柄を踏まえて、AIR ThermoHygrometer では「 Visual C# のShockwaveFlashObject に SWF を読み込ませて、AIR アプリケーション (SWF) とLocalConnection で通信させる」という方法を採用しました。

ここで肝になるのが、LocalConnecton と ExternalInterfaceProxy です。それぞれについて、押さえるべきポイントを説明します。

LocalConnection 使用上の注意

AIR アプリケーション (SWF) と AIR アプリケーション以外の SWF 間をLocalConnection で通信させる場合には、LocalConnection.connect() メソッドや、LocalConnection.send() メソッドで使用する connectionName パラメータに対して、以下の注意が必要です。

■ AIR → SWF の場合

AIR (送信側)の connectionName パラメータ

localhost:connectionName

注意: connectionName は任意の接続名です。

例: AIR (送信側)の ActionScript

const SENDER_NAME:String = "localhost:ThermoHygrometer"; var senderLC:LocalConnection = new LocalConnection(); var functionName:String = "getData"; var appID:String = nativeApplication.applicationID; var pubID:String = nativeApplication.publisherID; senderLC.send(SENDER_NAME, functionName, appID, pubID);

相互通信する場合、AIR アプリケーションは通信先の SWF に、自身の applicationID と publisherIDを渡す必要があります。(詳しい説明は後述します)

SWF (受信側)の connectionName パラメータ

connectionName

注意:connectionNameは任意の接続名です。

例: SWF (受信側)の ActionScript

const RECEIVER_NAME:String = " ThermoHygrometer"; var recieveLC:LocalConnection = new LocalConnection(); recieveLC.allowDomain('*'); try { recieveLC.connect(RECEIVER_NAME); } catch (error:ArgumentError) { //TODO:任意のエラー処理 }

■ SWF → AIR の場合

SWF (送信側)の connectionName パラメータ( AIR アプリケーションをインストールして実行する場合)

app#applicationID.publisherID:connectionName

SWF (送信側)の connectionName パラメータ(開発ツールなどを使用して実行する場合)

app#applicationID:connectionName

注意:applicationIDpublisherID は、事前に AIR アプリケーションから受け取る必要があります。
AIR アプリケーションを ADL(AIR Debug Launcher) または Flash CS3、Flex Builder、Dreamweaver などの開発ツールなどを使用して実行する場合、publisherID は null になり、ドメインストリングから省く必要があります。AIR アプリケーションをインストールして実行する場合は、publisherID をドメインストリングに含めます。 connectionName は任意の接続名です。

例:AIR から LocalConnection 経由で呼び出される SWF 内の関数

//AIR に接続するとき使用する LocalConnection の connectionName private var _senderName:String; //AIR から LocalConnection 経由で呼び出される関数 public function getData(...args):void { var appID:String = args[0]; var pubID:String = args[1]; _senderName = "app#" + appID; //開発ツールなどを使用して実行する場合の対策 if(null != pubID && 0 < pubID.length) { _senderName += "." + pubID; } _senderName += ":ThermoHygrometer"; }

AIR (受信側)の connectionName パラメータ

connectionName

注意: connectionName は任意の接続名です。

例: AIR (受信側)の ActionScript

const RECEIVER_NAME:String = "ThermoHygrometer"; var recieveLC:LocalConnection = new LocalConnection(); recieveLC.allowDomain('*'); try { recieveLC.connect(RECEIVER_NAME); } catch (error:ArgumentError) { //TODO: 任意のエラー処理 }

AIR で使用する LocalConnection についての詳しい説明は、『アプリケーション間通信』を参照してください。

ExternalInterfaceProxy の使用

Visual C# アプリケーションの ShockwaveFlashObject で読み込む SWF と Visual C# アプリケーションとを通信させるためには、ExternalInterfaceProxy を使用します。( ActionScript から Visual C# の関数を呼び出すには、ExternalInterface クラスを使用します。)

ExternalInterfaceProxy は、『 Adobe Flash サンプル』で配布されている C# のクラスライブラリです。各クラスの詳しい説明は、『例 : ActiveX コンテナに対する External API の使用』を参照してください。

例: Visual C# のソース

using Flash.External; ... private ExternalInterfaceProxy proxy; private AxShockwaveFlashObjects.AxShockwaveFlash IntrovertSWF; ... proxy = new ExternalInterfaceProxy(IntrovertSWF); proxy.ExternalInterfaceCall += new ExternalInterfaceCallEventHandler(proxy_ExternalInterfaceCall); ... private object proxy_ExternalInterfaceCall(object sender, ExternalInterfaceCallEventArgs e) { switch (e.FunctionCall.FunctionName) { // SWF から実行される関数名を判別 … case "newTempHumid": getTempHumidTrue(); return null; } } private void getTempHumidTrue() { double j = 0; double k = 0; … proxy.Call(“newTempHumid”, j, k); //SWF から登録されているコールバック関数の実行 }

例: Visual C# の関数を呼び出している ActionScript

if (ExternalInterface.available) { … //コールバック関数の登録 ExternalInterface.addCallback("newTempHumid", newTempHumidHandler); } … public function getTempHumidTrue():void { //Visual C# アプリケーションの関数呼び出し ExternalInterface.call("newTempHumid"); } … private function newTempHumidHandler(...args):void { //Visual C# アプリケーションの ExternalInterfaceProxy.Call() から実行されるコールバック関数 … }

LocalConnecton と ExternalInterfaceProxy が導通できれば、あとはデバイスにアクセスするのみです。(デバイスにアクセスすることについては、完全に C# の話になってしまうため割愛します。)

最後に

今回紹介した内容は、デバイス連携 AIR アプリケーション開発手法としては、かなりトリッキーかつマニアックな部類に該当すると思いますが、大部分を Adobe が公開しているサンプルソースに頼ることができるので、ある程度のプログラミングスキルがあれば、割と容易に手を出せるのではないかと思います。