[Android] Bluetoothが勝手にOFFになって困ってる人用のアプリ

私の使っている Androidスマホが、Bluetooth が 勝手に OFF になっていることがある。

車に乗り込んだときなど、車の(カーナビの)ハンズフリーに自動的に接続していてほしいので、Bluetoothは常にONにしておきたい。

それで私は常にBluetoothはON状態にしてるんだけど、でも、私の使ってる端末がへんなのか、なぜか、勝手に Bluetooth が OFF になっていることが、よく、あるのです。
(BluetoothをONにしてあるのに) 端末の電源を再投入したときなど、高確率で、OFF になってしまう。
映画見る時などは電源を切るので、帰りに電源を入れて車に乗って…しばらくしてからハンズフリーにつながってないのに気づいたりする。

なんで勝手にOFFになるのか…原因を調べるのもめんどくさいので、
「定期的にBluetoothがOFFになってないか調べて、OFFになっていたら、ONにする」アプリを作りました。

bton (ビートン)

…私以外に使う人いるだろうか?

セイコーエプソンのRTCをAndroidで使う場合

EPSONのRTCで、Linuxカーネルソースツリーにドライバが入っていないチップでも
セイコーエプソン製リアルタイムクロックモジュール用Linux Driverダウンロードページ
があったので、Androidでも簡単に使えるかと思ったら、甘かった。

セイコーエプソン提供のドライバで一応RTCとして動作はするのだが、Androidでは “wake up capable” でないと使えない。セイコーエプソン提供のドライバはそうなっていない。(linux-3.10.101 を見たが、ソースツリーに入っているEPSON RTCのドライバもそうなっていない)

(”wake up capable” でないRTCは、alarmtimer でRTCとして登録されない。
kernel/time/alarmtimer.c : alarmtimer_rtc_add_device() で device_may_wakeup() かどうかチェックしている)

この結果、「起動時にはRTCから読み出した時刻がシステム時計に反映される(ここまではLinuxカーネルがやってる仕事なので)が、Android上で(android.os.SystemClock.setCurrentTimeMillis()を使用して)(※このメソッドは特権が必要なので通常のAndroidシステムでは一般のアプリからは使えない)時計をセットしてもそれがRTCに書き込まれない」という事象が起きる。

RTCドライバをいじって、といっても1行追加しただけだが、 probe() の際に

device_init_wakeup(&client->dev, 1);
(※I2C RTCの場合)

をしてやるとalarmtimerがRTCとして登録してくれるので、AndroidからもRTCに書き込めるようになり、一応この問題は無くなる。
でもよく調べてないのでこれだけで大丈夫かわからない。ちゃんと修正しないといけないだろうけど・・・。

なお、こういうドライバは他にも kernel/driver/rtc 内にいくつもあるので注意が必要。
rtc-ds1307.c (DS1307, DS3231 等のドライバ) など(rtc-ds1307.c は、割り込みピンを使う場合は、大丈夫なのかもしれない?)

Androidアプリ「GPS定期測位」を作ってみた

→ Galaxy SII/Android/Google Latitudeの不満点

といった不満があったので、Androidアプリ作成の練習も兼ねて「一定時間おきにGPS測位するだけ」のAndroidアプリを作ってみた。

無料なので、もし同様の不満を感じているかたがいらしたらどうぞ。
個人的にはけっこう満足。
Google Latitudeで、そんなにバッテリも使わず、1時間に1回程度は、むちゃくちゃな誤差もなく、位置履歴が採れるようになったので。

GPS定期測位(Android Market)

アプリのアイコン、GPS衛星のつもりなんだけど・・・そう見えなかったらゴメンナサイ。

GPSでの測位を一定時間おきに行う、ただそれだけのアプリです。

このアプリそのものは、測位結果を記録することを目的としていません。

このアプリがGPSで測位したタイミングで、Google Latitudeが位置情報履歴を残してくれることを期待しています。

■製作意図

Androidの「無線とネットワーク」での位置情報取得を有効にしていると、時として非常に精度が悪い位置情報が取得されることがあります。

しかし、それを嫌って「無線とネットワーク」での位置情報取得を無効にし、「GPS機能を使用」だけを有効にしていると、Google Latitudeは自分でGPSを起動して位置情報を取りに行こうとはしないようで、Googleマップやその他のアプリがGPSを使った時、ついでに位置情報履歴を記録するだけのようです。逆に言うとGPSを使わないでいると、いつまでたっても履歴が残りません。

ならば、定期的にGPSで測位してやるアプリを動かしておけば、Google Latitudeも定期的に履歴を残してくれるのではないか?というのが本アプリの製作意図です。

実際、本アプリを15分おきの設定で動作させておけば、1時間に1~2回程度は、Google Latitudeで履歴が残るようになりました。

■設定・動作について

GPS測位間隔は、15分・30分・1時間・2時間 から選択できます。
(注:間隔は目安であり、正確ではありません)

GPSを起動して一定時間内に測位できなければその回の測位はあきらめますが、
そのタイムリミットは 30秒・1分・2分 から選択できます。

有効に設定すると、Androidを再起動しても、起動時から定期測位動作は有効になります。

アプリの画面には、直近10回までの測位動作結果を表示します。
動作時刻 OK 測位成功 測位までにかかった秒数と、大まかな座標を表示
動作時刻 NG 測位失敗 失敗判定までの秒数

本アプリの測位機能は常時バックグラウンドで動作しているわけではなく、必要時のみ起動しますので、バッテリ使用は最小限だと思います。
(技術的に言うと、ServiceをAlarmManagerによって起動しています)

動作確認は GALAXY SII(Docomo SC-02C) Android 2.3.5 で行っています。

2011/11/25 Ver 1.0 初版

AndroidのAlarmManagerで設定したAlarmが消えてしまうことがあった

(後記。TIME_SET等ではAlarmが消えることはありませんでした。コメント参照してください)

Androidのアプリを作っていた。
AlarmManagerでServiceを定期的に起動するようにしたが、気がついたら、Serviceが動かなくなっている。
なぜ? とググっていたら・・・

rokuta96のAndroidアプリ開発 アラーム3

システム時間変更イベントで、アラームがクリアされてしまうとのこと。

えーそんなのアリかよ・・・でもまあそういうイベント時にクリアしたくなるOSの気持ちもわかるな・・・
え、でもおれ今回のアプリを実験開始してから時刻設定とかタイムゾーン変更とかしたことないし、おかしくね?・・・・・・・・・あっ!

日付と時刻…ネットワーク自動設定!これかあ!

さっそくBroadcastReceiverを付けて確認してみたら、たしかに、ときどき、TIMEZONE_CHANGED や TIME_SET が発生していた。
これ気をつけないといけないのね。

2017/10 追記。
久しぶりに AlarmManagerを使ってみたら、setInexactRepeating() で、ぜんぜん、指定したインターバルで呼ばれない。

ドキュメントを見る…

intervalMillis
interval in milliseconds between subsequent repeats of the alarm. Prior to API 19, if this is one of INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY then the alarm will be phase-aligned with other alarms to reduce the number of wakeups. Otherwise, the alarm will be set as though the application had called setRepeating(int, long, long, PendingIntent).
As of API 19, all repeating alarms will be inexact and subject to batching with other alarms regardless of their stated repeat interval.

API 19(Android 4.4 kitkat)以前は、INTERVAL_FIFTEEN_MINUTES、INTERVAL_HALF_HOUR、INTERVAL_HOUR、INTERVAL_HALF_DAY、またはINTERVAL_DAYのいずれかである場合、アラームは他のアラームと位相調整されてウェイクアップの回数を減らします。 それ以外の場合は、アプリケーションがsetRepeating(int、long、long、PendingIntent)を呼び出したかのようにアラームが設定されます。
API 19では、繰り返されるすべてのアラームは、指定された繰り返し間隔に関係なく、不正確で、他のアラームとのバッチ処理が行われます。

まじかよ…ひでえな。

GALAXY SII(Docomo SC-02C)の「位置情報履歴」がヘン

GALAXY SII(Docomo SC-02C)の、「位置情報とセキュリティ」設定画面には、「位置情報履歴」というのがあって、「最新の位置情報を100件まで保存」と書いてあるのだが…

そう言われたら、当然、FIFO・リングバッファ式に位置情報履歴が保存されてるんだろうなあ、と思うじゃないですか。見てみると、

最新のが1件と、あとは妙に古い日の位置情報がこんなふうに同時刻で多数残っている。
昨日やおととい(11/20, 11/19)もGPSは使ったのに、スルーされてる。
いつ見てもこんな感じ。なにこれ…(‘A`)どういうロジックでこうなってるのか全然わからないよ。