[AIR] 常駐アプリ作成したけど、OSのスリープができなくなったら確認すること

2010/04/7

こんにちは。きんくまです。
AIRアプリで常駐型のもの(例えばガジェット、ウィジェット、RSSリーダーとか)を作成したときのこと。
作ったアプリを起動していると、うまくOSのスリープモードに入らないことが判明しました。
スリープに入らないと嫌われちゃって、あまり使われなくなる可能性があるので、これは
何とかしないといけません。

それで、手探りで原因を探していくと次の2点があるとダメなことがわかりました。

1)外部へのネットワークを使っている
2)FLVを再生している

この他にもあるかもしれないのですが、とりあえず自分でわかったのはこれだけ。

もう少し詳しく説明すると、
1)外部へのネットワークを使っている
これは、例えばサーバーに何がしかのデータを読みにいったり、Webページを定期的に表示しようとしたり、アップデート機能を使って頻繁にサーバーによみにいくとかいうことです。

ローカル上のswfを定期的に読み込んだりするのは実験したところOKっぽいです。

2)FLVを再生している
FLVを再生する際にローカルファイルでも、NetConnectionとかNetStreamとか使うのでこれが原因なんじゃないかな?と勝手に予想。
ちなみに、swf内にFLV埋め込み型でもダメです。内部で上のクラスを自動で動作させていると思われます。

FLVじゃなくて、通常のムービークリップをまわし続けてた場合はOKでした。

対策→NativeApplicationのEvent.USER_IDLEとEvent.USER_PRESENTを使う

NativeApplicationのEvent.USER_IDLEとEvent.USER_PRESENTを使うを使うことによって、OSレベルでユーザーがマウスやキーボードの操作を停止・再開したことがイベントとしてとることができます。

例えばモニタークラスなんかをつくって、必要なときはそれを見に行くことでいろいろとできると思います。

package
{
	import flash.desktop.NativeApplication;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	/**
	 * ユーザーの入力がOSレベルでおこなわれなくなるのを監視します
	 * @author KinkumaDesign
	 */
	public class NativeAppUserIdleMonitor extends EventDispatcher
	{
		private static var _instance:NativeAppUserIdleMonitor;
		private var _isIdle:Boolean;
		
		public function NativeAppUserIdleMonitor() 
		{
			if (_instance != null) {
				throw new Error('singleton');
			}else {
				init();
			}
		}
		
		public static function get instance():NativeAppUserIdleMonitor
		{
			if (_instance == null) {
				_instance = new NativeAppUserIdleMonitor();
			}
			return _instance;
		}
		
		private function init():void
		{
			_isIdle = false;
			NativeApplication.nativeApplication.idleThreshold = 60; //操作をやめてから60秒後にイベント発行
			NativeApplication.nativeApplication.addEventListener(Event.USER_IDLE, nativeAppUserIdleHD);
			NativeApplication.nativeApplication.addEventListener(Event.USER_PRESENT, nativeAppUserPresentHD);
		}
		
		private function nativeAppUserPresentHD(e:Event):void 
		{
			_isIdle = false;
			dispatchEvent(new Event(Event.USER_PRESENT));
		}
		
		private function nativeAppUserIdleHD(e:Event):void 
		{
			_isIdle = true;
			dispatchEvent(new Event(Event.USER_IDLE));
		}
		
		public function get isIdle():Boolean
		{
			return _isIdle;
		}
	}

}

使い方例。
ここでは使うときにだけ、isIdeleプロパティを見てるけど、
モニタークラスからイベントが発行されるからそのイベントを監視しててもいいかも。

var monitor:NativeAppUserIdleMonitor = NativeAppUserIdleMonitor.instance;
if(monitor.isIdle){
	//ユーザーが操作してない!なんかするとかしないとかの処理
}else{
	//ユーザーが操作してる!なんかするとかしないとかの処理
}
LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る