2008年9月24日 (水)

AIRでシステムトレイにアイコン表示

AIRでシステムトレイにアイコンを表示させる方法。(AIR1.1)

アイコンはBitmapDataを使えます。setSystemTrayに引数で渡す形にしてます。
本当は16x16とか128x128とか複数用意するほうがいいんだろうけど、気にならなければ1つ用意すれば大丈夫です。
複数のサイズを用意した場合は一番近い大きさのを自動で伸縮して表示してくれるっぽいです。

↓これでWin/Mac両方に対応します。

public function setSystemTray(icon:BitmapData):void {
	if (NativeApplication.supportsSystemTrayIcon || NativeApplication.supportsDockIcon) {
		NativeApplication.nativeApplication.autoExit = true;
		if (NativeApplication.supportsSystemTrayIcon) {
			systemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon;
			systemTrayIcon.tooltip = "テストアプリ";
			setIconMenu();
			systemTrayIcon.menu = systemTrayMenu; // Configure of menu
		} else {
			systemDockIcon = NativeApplication.nativeApplication.icon as DockIcon;
			this.setIconMenu();
			systemDockIcon.menu = systemTrayMenu;
		}
		NativeApplication.nativeApplication.icon.bitmaps = [icon];
	}
}

右クリックで出てくるメニューを設定できます。

private function setIconMenu():void{
	systemTrayMenu = new NativeMenu();

	var frontMenuItem:NativeMenuItem = new NativeMenuItem("常に前に表示/非表示");
	frontMenuItem.addEventListener(Event.SELECT, alwaysFront);

	var miniMenuItem:NativeMenuItem = new NativeMenuItem("最小化");
	miniMenuItem.addEventListener(Event.SELECT, minimize);

	var maxMenuItem:NativeMenuItem = new NativeMenuItem("元に戻す");
	maxMenuItem.addEventListener(Event.SELECT, maximize);

	var sep1MenuItem:NativeMenuItem = new NativeMenuItem("セパレータ", true);

	var exitMenuItem:NativeMenuItem = new NativeMenuItem("終了");
	exitMenuItem.addEventListener(Event.SELECT, close);

	systemTrayMenu.addItem(frontMenuItem);
	systemTrayMenu.addItem(miniMenuItem);
	systemTrayMenu.addItem(maxMenuItem);
	systemTrayMenu.addItem(sep1MenuItem);
	systemTrayMenu.addItem(exitMenuItem);
}
private function minimize(e:Event):void {
	stage.nativeWindow.minimize();
}
private function maximize(e:Event):void {
	stage.nativeWindow.restore();
	nativeWindow.activate();
}
private function close(e:Event):void {
	nativeWindow.close();
	stage.nativeWindow.close();
}
private function alwaysFront(e:Event):void {
	nativeWindow.activate();
	nativeWindow.alwaysInFront = !nativeWindow.alwaysInFront;
}

ここに書く用にちょっと書き換えたのでどっかおかしいかも。

もうCS4出るのか。。

| | コメント (0) | トラックバック (0)

AIRでスタートアップ登録

AIRでアプリをスタートアップに登録する方法。(AIR1.1)

NativeApplication.nativeApplication.startAtLoginの値をtrueにするとスタートアップフォルダ内にショートカットが作成されます。falseにすると消えます。
変更する際は下記のようにtry..catchを使います。
Macでもこれでいけると思うんだけど、未確認。

public function setStartUp(b:Boolean):void {
	try{
		NativeApplication.nativeApplication.startAtLogin = b;
	} catch (err:Error) {
	} finally {
	}
}

ショートカット作成したままアンストールするとショートカットだけ残るような。。

| | コメント (0) | トラックバック (0)

2008年9月19日 (金)

AIRでSQLを使う

案件でデスクトップアプリ(ガジェット?)を作ることになったので
AIRで試しに作ってみました。結局mProjectorになっちゃったけど。
その時にSQLを使ったのでそのへんを書いてみます。
バージョンは1.1です。

AIRではSQLiteが使えます。
基本的なところは他のSQLと同じかと。

必要なクラスをimport。

import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.data.SQLResult;
import flash.data.SQLTableSchema;
import flash.data.SQLSchemaResult;
import flash.events.SQLEvent;
import flash.events.SQLErrorEvent;
import flash.filesystem.File;

変数はこうなってます。

private var sqlCon:SQLConnection;
private var sql:SQLStatement;

まずはデータベースを開きます。
データベースはメモリ内で作成することもできるし、ファイルを作成してそこに保存することもできます。今回のはローカルのファイルに保存するやつです。
ファイル名を「user.db」としてます。
保存場所は「applicationStorageDirectory」を指定してるので「Local Settings」の「Application Data」以下のどっかです。
「SQLEvent.OPEN」をaddEventListenerして、データベースが開かれたら「openedDataBase」が呼ばれるようにします。

private function init():void {
    sqlCon = new SQLConnection();
    sqlCon.addEventListener(SQLEvent.OPEN, openedDataBase);
    var dbFile:File = File.applicationStorageDirectory.resolvePath("user.db");
    sqlCon.open(dbFile);
}
private function openedDataBase(e:SQLEvent):void {
    sqlCon.removeEventListener(SQLEvent.OPEN, openedDataBase);
    createTable();
}

データベースが開かれたらテーブルを作成します。
すでに作成済みの場合は新たに作成する必要はないのですが、そのテーブルが存在するかどうかの確認方法が分からなかったので、SQLのほうで「IF NOT EXISTS」を付け加えて「テーブルが存在してなければ作る」というふうにしました。

SQLを実行する場合はまず「new SQLStatement()」でSQLStatementインスタンスを作成します。
SQL文をそのtextプロパティに入れます。
execute()で実行されます。

private function createTable():void {
    sql = new SQLStatement();
    sql.sqlConnection = sqlCon;
    sql.text=
        "CREATE TABLE IF NOT EXISTS table_name ("+
        " date TEXT,"+
        " comment TEXT"+
        ")";
    sql.addEventListener(SQLEvent.RESULT, createdTable);
    sql.addEventListener(SQLErrorEvent.ERROR,errorCreateTable);
    sql.execute();
}
private function createdTable(e:SQLEvent):void {
    sql.removeEventListener(SQLEvent.RESULT, createdTable);
    sql.removeEventListener(SQLErrorEvent.ERROR,errorCreateTable);
}
private function errorCreateTable(e:SQLErrorEvent):void {
    sql.removeEventListener(SQLEvent.RESULT, createdTable);
    sql.removeEventListener(SQLErrorEvent.ERROR,errorCreateTable);
}

下記のはISNERTする場合です。
SELECTやUPDATE、DELETEをする場合やり方はも同じです。
SQLはSQL文中に「?」を入れて、それに対応するパラメータを配列で指定できます。
「parameters」が配列になってるので、出てくる順番に入れればOKです。

public function insertDayData():void {
    var dt:Date = new Date();
    var date:String = String(dt.time);
    var comment:String = obj.comment;

    sql = new SQLStatement();
    sql.sqlConnection = sqlCon;
    sql.text = "INSERT INTO table_name(date,comment) values(?,?);";
    sql.parameters[0] = date;
    sql.parameters[1] = comment;
    sql.addEventListener(SQLEvent.RESULT, insertedDayData);
    sql.addEventListener(SQLErrorEvent.ERROR,errorInsertDayData);
    sql.execute();
}
private function insertedDayData(e:SQLEvent):void {
    sql.removeEventListener(SQLEvent.RESULT, insertedDayData);
    sql.removeEventListener(SQLErrorEvent.ERROR,errorInsertDayData);
}
private function errorInsertDayData(e:SQLErrorEvent):void {
    sql.removeEventListener(SQLEvent.RESULT, insertedDayData);
    sql.removeEventListener(SQLErrorEvent.ERROR,errorInsertDayData);
}

なんかSQLiteには型というのが存在しないらしいです。
「CREATE TABLE」の時に指定してても意味ないっぽい。
知らずにDate型を指定してたらSELECTでうまく取れなくてしばらくハマってしまった。。
結局は上記のようにミリ秒に直してTEXTとして入れました。

それにしても、なかなかAIR広まらないなあ。。

| | コメント (0) | トラックバック (0)