着信イベントを拾ってごにょごにょするアプリを作ることになったのですが、作ってる最中に不要になりました。
せっかくなので調べたことは書き残しておくことに。
#0.概要
やりたかったことは着信したら相手に紐づいた通話メモを残す、です。
通話が終了したタイミングで登録画面を表示して会話内容を入力して登録ボタンを押したら別のアプリのAPIに投げて登録してもらう、といった感じですね。
そう、その「別のアプリ」に既にその機能があることが分かったので不要になったのですが。開発元の営業に聞いても無いって言われたからから作ってって言われたんですけども!
ま、それはさておき。
ちなみに、着信履歴から共有ボタンでインテント飛ばしてもらってそこから登録、も考えたのですが、着信履歴には共有ボタンって無いんですね。履歴から電話帳登録ができるので共有ボタンあるものだと思ってたのですが。
どうやら着信履歴は権限さえあればContentProvider
でアクセスできる共有情報として扱うみたいです。
でもわざわざ別アプリで着信履歴見るのもなあ・・・ってことで今回は不採用。
ユーザーからすると普通の着信履歴使えよ!って思いますよね。使えないんですけども。
#1.着信の拾い方
Androidは着信するとインテントを投げてくれるみたいです。暗黙的インテント(Explicit Intent)というやつですね。これは特定のアプリに対して投げられるのではなく、該当のインテントフィルターを持つアプリ全てが対象になります。
「狼が来たぞー!」と叫べば羊と村人がそれぞれ別の動きをしてくれる感じですね。(羊は叫んでもわからないだろとか無しで)
ですのでAndroid Manifestにandroid.intent.action.PHONE_STATE
のインテントフィルターをつけてあげればOKです。
あと電話ステータスの読み取り権限が必要なのでandroid.permission.READ_PHONE_STATE
を足しておきましょう。
さて、となるとインテントが投げられるまでじっと待機してなきゃいけないからServiceにしないとだめか?と思いきや、BroadcastReceiver
にすればOKです。
BroadcastReceiverは起動していなくてもインテントに反応して動いてくれます。
というわけでマニフェストはこんな感じ。
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
~中略~ >
<receiver android:name=".PhoneCallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
PhoneCallReceiver
がBroadcastReceiverを継承して作ったクラスになります。
着信の処理の仕方についてはこちらを参考にさせて頂きました。
http://techbooster.org/android/application/1853/
#2.BroadcastReceiver
繰り返しになりますがPhoneCallReceiverはBroadcastReceiverを継承して作ります。インテントを受信するとonReceiveメソッドが走るのでそこをOverrideして作り込みます。
そこでintent.getExtras
で情報を取り出してもいいのですが、MyPhoneStateListener
を使うと美しいようです。
BroadcastReceiverを使うのはこちらを参考にさせて頂きました。
http://storyboard.jp/blog/android_telmanager/
#3.intentの中身は?
さて、ここまでで着信の処理の仕方は終わりなのですが、intentの中身を調べてみました。
なんでこんなことやるかっていうと、まず第1に、どんなときにどんな情報が取れるのか詳しく見たかったので(そのままだ)、第2に通話時間を計る場合にどうしたらいいか見たかったので。
使ったのはAQUOS PHONE ZETA - SH01F (Android 4.4.2)です。
BroadcastReceiverでPreferenceに書き込んでそれを表示するActivityを付け足しました。
###1.着信して拒否した(自分が切った)
着信 - incoming_nmber=xxx,state=RINGING
終了 - incoming_nmber=xxx,state=IDLE
###2.着信して取る前に切れた(不在着信)
着信 - incoming_nmber=xxx,state=RINGING
終了 - incoming_nmber=xxx,state=IDLE
###3.着信して通話して相手が切った
着信 - incoming_nmber=xxx,state=RINGING
応答 - state=OFFHOOK
終了 - state=IDLE
通話すると応答、終了時に番号が取れなくなりますね。
###4.着信して通話して自分が切った
着信 - incoming_nmber=xxx,state=RINGING
応答 - state=OFFHOOK
終了 - state=IDLE
自分が切っても相手が切っても同じ
###5.着信して留守電になって相手が切った
着信 - incoming_nmber=xxx,state=RINGING
応答 - state=OFFHOOK
終了 - state=IDLE
留守電は通話と同じですね。
###6.着信中にさらに着信(話し中)
19:09:41.036
着信 - incoming_nmber=xxx,state=RINGING
話し中の分は全く反応なし。当然といえば当然ですね。
が、終了が取れてないだと・・・?
話し中特有の現象なのか、通常でも起こりうるのか・・・。
もう一回。
19:30:10.593
着信 - incoming_nmber=xxx,state=RINGING
終了 - incoming_nmber=xxx,state=IDLE
IDLE取れた上に番号も取れた???
なんか気分次第のような・・・
###7.着信して通話中にさらに着信(キャッチホン)それを拒否
着信 - incoming_nmber=xxx,state=RINGING
応答 - state=OFFHOOK
着信 - incoming_nmber=yyy,state=RINGING
拒否 - incoming_nmber=yyy,state=OFFHOOK
終了 - state=IDLE
拒否した時点のものもOFFHOOKになってますね。
2回目の着信と拒否したときの番号は後からかかってきた番号になっています。
###8.着信して通話中にさらに着信(キャッチホン)それに「保留して応答」
19:15:42.551
着信 - incoming_nmber=xxx,state=RINGING
応答 - state=OFFHOOK
着信 - incoming_nmber=yyy,state=RINGING
応答 - incoming_nmber=yyy,state=OFFHOOK
終了 - state=IDLE
拒否の場合と同じ。
###9.着信して通話中にさらに着信(キャッチホン)それに「終了して応答」
19:17:07.244
着信 - incoming_nmber=xxx,state=RINGING
応答 - state=OFFHOOK
着信 - incoming_nmber=yyy,state=RINGING
応答 - state=OFFHOOK
終了 - state=IDLE
保留の場合とおなz・・・2回目の応答の電話番号が無くなりましたね。はてさて。
###10.発信して通話
19:21:21
発信 - state=OFFHOOK
終了 - state=IDLE
番号わかりません。
###11.発信して切った
19:20:23.117
発信 - state=OFFHOOK
終了 - state=IDLE
同じく番号わかりません。
通話時間を取るのは茨の道の予感ですね。