Adobe AIRのパッケージングについて

Adobe AIRのパッケージングですが
できるものはzip圧縮で拡張子airのファイルです。
でもAdobe AIR SDKをつかってairファイルを作成します。
何故かというと署名を付加しているからです。
署名ファイルは自己署名でもOKとなっています。

署名ファイルの作成はAntで行うとすると
下記のようにタスクを書いてあげます。
 <target name = “convAIRKey”>
  <java jar         = “${bin.dir}/adt.jar”
        fork        = “true”
        failonerror = “true”
        maxmemory   = “64m”
        timeout     = “300000”
  >
   <jvmarg value = “-Xms16m” />
   <jvmarg value = “-Xmx64m” />

   <arg value = “-certificate” />
   <arg value = “-cn” />
   <arg value = “SelfSign” />
   <arg value = “-ou” />
   <arg value = “<部署名>” />
   <arg value = “-o” />
   <arg value = “<会社名>” />
   <arg value = “-c” />
   <arg value = “JP” />
   <arg value = “2048-RSA”/>
   <arg value = “<自己署名ファイル名>” />
   <arg value = “<自己署名パスワード>” />
  </java>
 </target>

それを元にパッケージングを行います。
 <target name   = “convAIRWin”
         unless = “mac”
 >
  <java jar         = “${bin.dir}/adt.jar”
        fork        = “true”
        failonerror = “true”
        maxmemory   = “64m”
        timeout     = “300000”
  >
   <jvmarg value = “-Xms16m” />
   <jvmarg value = “-Xmx64m” />

   <arg value = “-package” />
   <arg value = “-storetype” />
   <arg value = “pkcs12” />
   <arg value = “-keystore” />
   <arg value = “<自己署名ファイル名>” />
   <arg value = “-storepass” />
   <arg value = “<自己署名パスワード>” />
   <arg value = “<作成するairファイル名>” />
   <arg value = “<マニフェストファイル名>”/>

   <arg value = “-C” />
   <arg value = “<ベースディレクトリ>” />
   <arg value = “AIRAliases.js”   />
   <arg value = “AIRLocalizer.js” />
   <arg value = “<airファイルに含めるファイル名…>” />
  </java>
 </target>

ちなみにAdobe AIR SDKのbinディレクトリにある
adl.exeを使うと現状の確認、テストが行えます。
下記のコマンドです。
 adl.exe <マニフェストファイル名>

各ガジェットのパッケージングについて

各ガジェットプラットフォーム向けにガジェットを作成したら
パッケージングして配布できるようにします。
ではそのファイルフォーマットというと
拡張子はそれぞれ異なりますが
大体がzip圧縮されたファイルとなっています。

なので作ったガジェットはAntなどを使って
zip圧縮して指定された拡張子を付けてあげます。
どうなっているかというと。
 Windows サイドバーガジェット:
  拡張子”gadget”でのzip圧縮

 Opera ウィジェット:
  拡張子”wgt”でのzip圧縮

 Mac OS X Dashboard ウィジェット
  拡張子”zip”でのzip圧縮

 Adobe AIR
  拡張子”air”でのzip圧縮 (Adobe AIR SDKのadtコマンドを使用)

 iGoogle ガジェット
  そのままサイトにアップロード

 Google デスクトップ ガジェット
  拡張子”gg”でのzip圧縮

 Yahoo!ウィジェット
  拡張子”widget”での独自のフラットファイル形式 (Converter.exeを使用)

Adobe AIRでのガジェットの移動

Adobe AIRでマニフェストファイルを下記のようにして
をクロムモードをなしにすると
当然ながらタイトルバーがないです。
タイトルバーがないので移動もできません。
 <systemChrome>none</systemChrome>
 <transparent>true</transparent>

そのときには動かしたいエレメントに対して
下記のイベントを追加してあげると移動することができます。
  $(“foo”).onmousedown = function(){ window.nativeWindow.startMove(); };

そして現在の表示位置は下記のように取得することができるので
この値を保存しておいて起動時に設定してあげれば
前回の表示位置を再現できます。
 x = window.nativeWindow.x;
 y = window.nativeWindow.y;

音の再生

今回は各ガジェットにて音の再生と停止についてです。

Opera ウィジェット、Mac OS X Dashboard ウィジェット、
iGoogle ガジェットに関しては拡張APIが用意されていません。
なのでFlash経由などで行う方法しかないようです。

また、音源ファイルにはいろいろとフォーマットがありますが
Adobe AIRはmp3のみサポートしていますので
要注意です。

ではその他のガジェットに関しては下記のように行います。
 Windows サイドバーガジェット:
  <再生>
   System.Sound.playSound(“foo.mp3”);

  <停止> 引数にから文字を設定します
   System.Sound.playSound(“”);

 Adobe AIR:
  <再生>
   if(airSoundChannel != null){
    airSoundChannel.stop();
   }
   var sound = new air.Sound(
    new air.URLRequest(“foo.map3”)
   );
   airSoundChannel = sound.play(0);

  <停止>
   if(airSoundChannel != null){
    airSoundChannel.stop();
   }

 Google デスクトップ ガジェット:
  <再生>
   if(curAudioClip == null){
    curAudioClip = framework.audio.play(“foo.mp3”, onAudioStateChange);
   } else {
    curAudioClip.currentPosition = 0;
   }

  <停止>
   if(curAudioClip != null){
    curAudioClip.stop();
    curAudioClip = null;
   }

 Yahoo!ウィジェット:
  <再生>
   play(“foo.mp3”, true);

  <停止> 引数にnullを設定
   play(null, true);

Adobe AIRでのローカライズについて

Adobe AIRでは専用の拡張APIを持っていますので
今までとはちょっと違います。
まずベースディレクトリの下に”locale”ディレクトリを作成します。
“locale”ディレクトリの下に”ja”などの
言語ディレクトリを作成します。
言語ディレクトリの下には”localizedStrings.properties”のように
ローカライズ毎のプロパティファイルを置いておきます。

なのでプロパティファイルの中身は下記のようになります。
 foo =bar

そして取得の方法は下記のように行います。
getStringメソッドの第1引数に”言語”、
第2引数にプロパティファイルで記述したキーを指定します。
 var msg = air.Localizer.localizer.getString(“ja”, “foo”);

クリップボードへのコピー

クリップボードへのコピーを行い時に
Windows サイドバーガジェット、Mac OS X Dashboard ウィジェット、
Adobe AIR、iGoogle ガジェット(IEでみたときのみ)、
Yahoo!ウィジェットでは拡張APIをつかって行えます。
iGoogle ガジェット(IEでみたときのみ)は
Windows サイドバーガジェットと同じ方法なんだけれどもね。

Mac OS X Dashboard ウィジェットは拡張APIというよりも
シェルにアクセスできるのでシェルを通じてのアクセスになります。
もちろんマニフェストファイルに
 <key>AllowSystem</key>
 <true />
と記述しておかないとセキュリティエラーで動かないです。

それ以外ではそのくらいの拡張API作っておいてもよさそうなんだけれども
やるのであればFlash経由で
クリップボードへアクセスするしかないようです。

そのやり方は下記です。
 Windows サイドバーガジェット:
  clipboardData.setData(“Text”, value);

  clipboardData.getData(“Text”);

 Mac OS X Dashboard ウィジェット:
  widget.system(“/bin/echo -n ‘” + value + “‘ | /usr/bin/pbcopy”, null);

  value = widget.system(“/usr/bin/pbpaste”, null).outputString;

 Adobe AIR:
  var copyObj = air.Clipboard.generalClipboard;
  copyObj.clear();
  copyObj.setData(air.ClipboardFormats.TEXT_FORMAT, value);

  var pasteObj = air.Clipboard.generalClipboard;
  value = pasteObj.getData(air.ClipboardFormats.TEXT_FORMAT);

 Yahoo!ウィジェット:
  system.clipboard = value;

  value = system.clipboard;

 

設定ファイルへの読み書込み

今回は各種ガジェットでの設定ファイルへの読み書込みについてです。
キーに対して値の書込みを行い、キーを指定して値の読込みを行います。
なのでいっぱいキーを作っても面倒なので
値をJSONにしておくと便利です。
そしてOpera ウィジェット、Mac OS X Dashboard ウィジェットでは
書き込みを行う際に通常、キーと値なところが
値、キーの順番で設定しますのでちょっと紛らわしいです。

こんな感じで行います。
 Windows サイドバーガジェット:
  value = System.Gadget.Settings.readString(key);

  System.Gadget.Settings.writeString(key, value);

 Opera ウィジェット:
  value = widget.preferenceForKey(key);

  widget.setPreferenceForKey(value, key);

 Mac OS X Dashboard ウィジェット:
  value = widget.preferenceForKey(key);

  widget.setPreferenceForKey(value, key);

 Adobe AIR:
  var dir  = air.File.applicationStorageDirectory;
  var file = dir.resolvePath(key);
  if (file.exists) {
   var fileStream = new air.FileStream();
   fileStream.open(file, air.FileMode.READ);
   value = fileStream.readUTFBytes(fileStream.bytesAvailable);
   fileStream.close();
  }

  var dir        = air.File.applicationStorageDirectory;
  var file       = dir.resolvePath(key);
  var fileStream = new air.FileStream();
  fileStream.open(file, air.FileMode.WRITE);
  fileStream.writeUTFBytes(value);
  fileStream.close();

 iGoogle ガジェット:
  var pref = new _IG_Prefs(__MODULE_ID__); // new gadgets.Prefs();
  value = pref.getString(key);

  pref.set(key, value);

 Google デスクトップ ガジェット:
  value  = options.getValue(key);

  options.putValue(key, value);

 Yahoo!ウィジェット:
  value = preferences.key.value;

  preferences.key.value = value;

ガジェットでのAjaxセキュリティ

ガジェットからのAjax使っての外部通信ですが
ローカルからのブラウザアクセスと同様に結構バラバラです。
基本はマニフェストファイルに接続先ドメインを記述します。

まあ、下記のようになっています。
 Windows サイドバーガジェット: (特になし、今後かかりそう)

 Opera ウィジェット: 下記のようにconfig.xmlに接続先ドメインを記述
  <security>
   <access>
    <protocol>http</protocol>
    <port>80</port>
    <host>www.aaoh.co.jp</host>
    <host>aaoh.co.jp</host>
   </access>
  </security>

 Mac OS X Dashboard ウィジェット: 下記のように Info.plistに
  外部通信を許可することを記述
  <key>AllowNetworkAccess</key>
  <true />

 Adobe AIR: (特になし)

 iGoogle ガジェット: _IG_FetchXmlContentメソッドを使用すれば問題なし

 Google デスクトップ ガジェット: (特になし)

 Yahoo!ウィジェット: 下記のようにIwidget.xmlにに接続先ドメインを記述
  <security>
   <http name=”aaoh_co_jp”>www.aaoh.co.jp</http>
  </security>

Silverlightはちょっと特殊で通信を行うサーバー側に
このクライアントと通信してもよいという
マニフェストファイルを置きます。
こんな感じで。
 <cross-domain-policy>

  <!– すべてのクライアントからのアクセスを許可する –>
  <allow-http-request-headers-from
   domain=”*”
   headers=”*”
  />
 </cross-domain-policy>

リンクをブラウザで開く

ガジェット作成していてリンクをクリックしたら
ブラウザでそのURLを開きたいとき。
Mac OS X Dashboard ウィジェット、Adobe AIRだけは
拡張APIを呼んであげなければいけません。
JavaScriptからブラウザを開きたいときにはわかるんだけれども
“aタグ”で記述しているんだからそれを解釈してよと思います。

ちなみにリンクをブラウザで開く拡張APIは下記となっております。
 Windows サイドバーガジェット: <aタグ> または System.Shell.execute(url);

 Opera ウィジェット: <aタグ> または window.open(url);

 Mac OS X Dashboard ウィジェット: widget.openURL(url);

 Adobe AIR: air.navigateToURL(new air.URLRequest(url));

 iGoogle ガジェット: <aタグ> または window.open(url);

 Google デスクトップ ガジェット: <aタグ> またはframework.openUrl(url);

 Yahoo!ウィジェット: openURL(url);