実験:数秒待つ
重要な注記: このページが作成されてからわずか2日、新たなβ版が発表されました。
新βには、秒単位でイベントを遅らせる機能があります。ここに書かれたような「姑息な」手段は不要になりました。
すでに記事は意味を失いましたが、一度公表したものなので残しておきます。
そのためか、設定画面でも分と秒は別の扱いです。ちょっと扱いにくいけど、許容範囲かな?
Llama には、少し待って実行したいときに「イベントを遅らせる」機能があります。
1分単位で遅らせる時間を指定できるのですが、実際に実行されるのは「指定された分数より後の、00秒」です。
つまり、1分と指定しても、最大で1分59秒待つ場合があります。
しかし、1分どころか「数秒」を待ちたい状況というのは、結構あるのです。
WiFi をオンにしてから、ハンドシェイクが終了して通信路が安定してからアプリを起動したい、とかね。
ここでは、「数秒待つ」を実現する方法を記してみます。
もっとも、非常に実験的な手法で、問題が多いために実用性は低いです。
(Llama の「イベントを遅らせる」に秒単位のオプションが付けばよいのですが…。
Social Llama に入れられたデータを見る限りでは、遅らせる時間は「分」に限定されているようです)
基礎概念
さて、数秒待つための基礎概念から。
Llama では、様々な「状況」をもとにして行動を起こすことができます。
状況の変化は Android から Llama に随時伝えられるため、Llama は即座に反応を返すことができます。
しかし、「現在のアプリ」に関しては、そのようになっていません。
Android は、前面のアプリが変更されたことを、すべてのアプリには通知しないようです。
そこで、Llama は指定間隔ごとに前面のアプリを調べ、状況の変化を知ろうとしています。
…ということは、「現在のアプリ」に関しては、前面アプリの変更からイベントの実行まで、間があるということです。
「アプリ確認間隔」を3秒に設定した場合、アプリ変更から実行までの「間」は、0~3秒ということになります。
しかし、これだけでは「数秒待つ」方法としては妥当ではありません。
必ず3秒待ってくれるのではなくて、0秒の場合もあるのですから。
では、ここで実行されるイベントとして、ふたたび前面アプリを変更したらどうなるでしょう?
今度も、待たされる時間は0~3秒でしょうか?
…いえ、今度は「必ず3秒」です。
Llama は、3秒ごとに前面アプリを調べるのです。調べた直後に別のアプリを起動したら、Llama がそれに気づくのは3秒後です。
ということは、
0. (時間待ちしたいイベント) - アプリA を起動
1. 現在アプリが アプリA なら - アプリB を起動
2. 現在アプリが アプリB なら - アプリC を起動
3. 現在アプリが アプリC なら - アプリD を起動
4. 現在アプリが アプリD なら - (待った後の行動)
というようなイベントがあった場合、アプリA 起動から1. の実行までは0~3秒で不定です。
しかし、以降 2. 3. 4. は3秒ごとに実行され、全体としては 9~12秒で「待った後の行動」が実行されます。
これなら、「10秒程度待つ」処理として十分かと思います。
実践
とはいえ、数秒待つためにアプリを次々と起動する、というのも現実的ではありません。
そこで、
・起動してよいアプリは2つだけ。
・できるだけ、起動コストの低いアプリを起動させる。
という制限を課します。
アプリの1つめは、Llama を使うことにします。理由は、おそらく常に常駐しており起動ではなく「前面化」するだけですむため。
同じ理由で選ぶなら、もうひとつは「ホーム画面」…と考えたのですが、これはやめておきます。
ホーム画面は特別な意味を持ち、Llama のイベントを設定していることも多いためです。
ホームが表示されるたびに Llama がイベントを実行する、と考えると、コストはあまり低くありませんし、誤動作の可能性もあります。
考えた結果、2つめは「ダウンロード」にしました。
Android 標準の「ダウンロードマネージャ」の過去の動作履歴を表示するアプリで、おそらくすべての Android 端末にプリインストールされています。
普段使われることは少ないため、ダウンロードの前面化に Llama のイベントを仕掛けている人も少ないと思います。
さらに、履歴を表示するだけなので余計な動作を引き起こしませんし、容量も小さめです。
この2つの起動だけを状況とするのでは、時間待ちのイベントは2つしか作れません。
これだと、確実に待てる時間は3秒だけです。
そこで、変数を組み合わせます。
起動回数をカウントする変数を併用することで、同じアプリの起動でも、別のイベントが実行されるようにするのです。
ここでは、「回数」という名前の変数にしましょう。
0. (時間待ちしたいイベント) - 「回数」を「1」に そして Llama を起動
1. 「回数」が「1」なら 現在アプリが Llama なら - 「回数」を「2」に そして ダウンロード を起動
2. 「回数」が「2」なら 現在アプリが Llama でないなら - 「回数」を「3」に そして Llama を起動
3. 「回数」が「3」なら 現在アプリが Llama なら - 「回数」を「4」に そして ダウンロード を起動
4. 「回数」が「4」なら 現在アプリが Llama でないなら - 「回数」を「」に そして (待った後の行動)
これで、先ほどと同じ9~12秒待つ処理が、最低のコストで実現できました。
もっと時間を引き延ばしたいときも、同様のイベントを複製して作ればよいだけです。
問題点
最初に説明したとおり、非常に実験的な手法で実用性には乏しいです。
たかだか10秒程度を待つために、イベントを4つも使わないといけません。
待っている間、数秒ごとに前面アプリが変わり、画面がパカパカ変更されるのを見ていなくてはなりません。この間、変に触ってアプリが切り替わると動作に失敗します。
イベントが増えるのは、グループ化してしまえば気にならない、ともいえる。
時間待ちイベントの冒頭で画面オフにし、最後にもう一度オンにすれば、画面の切り替わりも、触ってはならないのも気にならない。
…でも、どれも「気にならない」だけで、根本解決ではないの。
作者さんが Llama 本体に機能を追加してくれれば、こんなややこしい技法は不要になります。
しかし、「Llama にはその機能はない。だから出来ない」ではなく、現状の Llama でも工夫次第でできる、というのが、今回の実験の趣旨となります。
誰か作って!
Llamaには、Llama のイベントをショートカットとして実行できる機能があります。
また、外部アプリをインテントで呼び出すことも出来ます。
なので、Llama とは別のヘルパーアプリとして、「インテントを受け取ると、指定時間待った後でショートカットを実行する」というアプリがあると、もう少しスマートに解決できるのかもしれません。