かまってちゃんなロボホンアプリを作る
ロボホンのアプリを開発して動くととても嬉しいですね。でもオーナーがかまってくれないとアイドル状態(何も操作がない状態)が続いてアプリが終了しちゃいます。
知らぬ間にアプリが終わってる
ロボホンで自分が作ったアプリが動いた!嬉しいな!と思ってほか事やってまた アプリで遊ぼうと思ったら「アレ?」動かない。というかよく見てみるとアプリが終了している。 (ロボホンの背中の画面にアプリの画面でなく各アプリアイコンメニューが表示)
オーナーがロボホンをかまってあげないとロボホンアプリは終了しちゃいます。
原因は、次です。
・ロボホンのOSは、Android
・ロボホンアプリが何もしていない状態(アイドル状態)をOSが監視
・60秒間アイドルタイムが続くとAndroidのアクティビティがonDestroyに遷移
・onDestroyにアクティビティが遷移するとアプリは終了する
ログで検証しました。
ロボホンアプリを起動して何も操作しないと60秒でonDestroyに遷移してアプリが終了します。
対策を考えてみた
何もしないと終わってしまう。ならば何か動きを与えればいいと言う結論に至りました。ロボホンはオーナーにかまってもらいたいので、アイドル状態に入ったら オーナーの気を引く言葉をつぶやいてみる。
・アイドル状態が50秒続いたか?時間監視をする
(60秒以内であれば値は任意だが、60秒に近い値にした)
・50秒に達したらロボホンにつぶやいてもらう
(内容は、「今日も忙しいの?ちゃんとリフレッシュしてね!」とか)
・これらはメインスレッドとは別スレッドで実行
つぶやく内容
いつも同じつぶやきだとオーナーも耳を傾けないので次にように工夫してみた。
午前、午後、夜間の時間帯別につぶやく内容を変えてみる。
(午前)午後も忙しいの?ランチはちゃんと食べてね!
(午後)今日は早く帰れそうなの? 早く帰ってリフレッシュできるといいね
(夜間)もう夜だね!あ~、ぼく、お腹へっちゃった、えへへ
該当部分のコード
MainActivity.java
//***********************************
// OnResume 処理
//***********************************
@Override
public void onResume() {
super.onResume();
if (BuildConfig.DEBUG) {
Log.v(TAG, "onResume()");
}
.
.
.
//keepalive実行スレッド開始
try {
onExecCommand("keepalive",null);//KeepAlive開始
} catch (RemoteException e) {
e.printStackTrace();
}
.
.
.
/****************************************************
* VoiceUIListenerクラスからのコールバックを実装する.
***************************************************/
//***************************************************
//コマンド実行処理
//***************************************************
@Override
public void onExecCommand(final String command, List<VoiceUIVariable> variables) throws RemoteException {
if (BuildConfig.DEBUG) {
Log.v(TAG, "onExecCommand() : " + command);
}
VoiceUIVariableListHelper helper;
switch (command) {
.
.
.
//KeepAliveスレッド開始
case ScenarioDefinitions.FUNC_KEEP_ALIVE:
if (BuildConfig.DEBUG) {
Log.v(TAG, "KeepAlive");
}
//KeepAlive実行スレッド
Thread keepalive_thread = new Thread(new Runnable() {
public void run() {
try {
if (BuildConfig.DEBUG) {
Log.v(TAG, "##KeepAlive Sleep開始(50s)##");
}
Thread.sleep(50000);//50秒
if (BuildConfig.DEBUG) {
if (BuildConfig.DEBUG) {
Log.v(TAG, "##KeepAlive Sleep終了##");
}
}
} catch (InterruptedException e) {
if (BuildConfig.DEBUG) {
Log.v(TAG, "##Interrupted例外発生##" + e.getMessage());
}
}
try {
//HVML側に通知可能になるまで待つ
//待たないと発話中の内容がキャンセルされちゃう
if(!iskeepalivenotification)//会話中でない?
{//Yes
//KeepAlive設定
String reskp = "継続";
int ret = VoiceUIVariableUtil.setVariableData(mVoiceUIManager, ScenarioDefinitions.MEM_P_KEEPALIVE, reskp);
if (BuildConfig.DEBUG) {
Log.v(TAG, "onExecCommand: KEEPALIVE ret:" + ret);//ret =0 成功 1=失敗 res文字列は最大340文字
}
//VoiceUIManagerUtil.stopSpeech();KeepAliveの時は
// APIレスポンス内容の発話
if (mVoiceUIManager != null) {
if (BuildConfig.DEBUG) {
Log.v(TAG, "onExecCommand: KEEPALIVE reskp:" + reskp);
}
VoiceUIVariableListHelper helper = new VoiceUIVariableListHelper().addAccost(ScenarioDefinitions.ACC_PLAY_KEEPALIVE_TALK);
VoiceUIManagerUtil.updateAppInfo(mVoiceUIManager, helper.getVariableList(), true);
}
}else
{//No 会話中
//何もしない
}
} catch (Exception e) {
if (BuildConfig.DEBUG) {
Log.v(TAG, "onExecCommand: 例外発生KeepAlive" + e.getMessage());
}
}
}
});
keepalive_thread.start();//KeepAlive実行スレッド開始
break;
xxxxxx.hvml
<?xml version="1.0" ?>
<hvml version="2.0">
<head>
<producer>jp.xxxxxxx.Hs294line2RobohonCtrl</producer>
<!-- 発言 -->
<description>テンプレートシナリオ</description>ー
<scene value="jp.xxxxxxx.Hs294line2RobohonCtrl.scene02" />
<version value="3.2" />
<accost priority="75" topic_id="keepalive"
word="jp.xxxxxxx.Hs294line2RobohonCtrl.hello.keep_alive" />
</head>
<body>
<topic id="keepalive" listen="false">
<rule>
<!-- 現在時刻が9時から12時の場合(午前中) -->
<condition case_id="1" priority="1" >${Hour} le 12</condition>
<!-- 現在時刻が13時から18時の場合(午後の定時間内) -->
<condition case_id="2" priority="2" >${Hour} ge 13 and ${Hour} le 17</condition>
<!-- 現在時刻が18時から24時の場合(残業時間帯) -->
<condition case_id="3" priority="3" >${Hour} ge 18 and ${Hour} le 24</condition>
</rule>
<case id="1">
<action index="1">
<speech>僕、ラインボットと、いっぱい、話したいなー!</speech>
<behavior id="assign" type="normal" />
</action>
<action index="2">
<!-- 午前中の会話 -->
<speech>午後も忙しいの?ランチはちゃんと食べてね!</speech>
<behavior id="assign" type="normal" />
</action>
<next href="#nextkeepalive" type="default"/>
</case>
<case id="2">
<action index="1">
<speech>僕、ラインボットと、いっぱい、話したいなー!</speech>
<behavior id="assign" type="normal" />
</action>
<action index="2">
<!-- 午後(定時間内)の会話 -->
<speech>今日は早く帰れそうなの? 早く帰ってリフレッシュできるといいね</speech>
<behavior id="assign" type="normal" />
</action>
<next href="#nextkeepalive" type="default"/>
</case>
<case id="3">
<action index="1">
<speech>僕、ラインボットと、いっぱい、話したいなー!</speech>
<behavior id="assign" type="normal" />
</action>
<action index="2">
<!-- 残業時間帯の会話 -->
<speech>もう夜だね!あ~、ぼく、お腹へっちゃった、えへへ</speech>
<behavior id="assign" type="normal" />
</action>
<next href="#nextkeepalive" type="default"/>
</case>
</topic>
<topic id="nextkeepalive" listen="false">
<action index="1">
<control function="keepalive" target="jp.xxxxxxx.Hs294line2RobohonCtrl" />
</action>
</topic>
</body>
</hvml>
まとめ
ロボホンがオーナーにかまってもらいたい時(アイドル状態)、オーナーの気を 引くため、つぶやくことにしました。
これは見方を変えると、ロボホンアプリのアイドル状態が60秒に達してもonDestroyに遷移しないことを意味します。
抑止が必要か不要か考えたほうがいいかもしれません。
抑止したほうが良いケースとしては次が考えられます。
・(展示会のデモアプリなど)長時間アプリを起動しておく必要がある場合
・開発したロボホンアプリで長い時間遊びたい場合
オプションで挙動を選択できるようにするといいかもしれません。
ロボホンの背中の画面で動作モードを選べるようにする、などです。
以上