Androidで電話の着信をハンドリング

Android端末で電話の着信等のイベントをハンドリング。最初はServiceかと思ったんですが、よーく考えるとBroadcastReceiverでいけました。

BroadcastReceiverを継承したカスタムBroadcastReceiverを作成。着信に関するクラスはTelephonyManagerで管理しているので、そちらにandroid.telephony.PhoneStateListenerを登録する。

PhoneStateListenerでは相手の電話番号の他に「着信」「通話」「終了(待ち受け)」の状態を管理できるのでその時の状況に合わせて処理を行う。

Intetn発行してブラウザやアプリをたちあるなど。比較的簡単だったのでとりあずサンプルを晒す。サンプルでは着信時にToastで状態を表示する。

manifest.xmlはこんな感じ。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.storyboard.testtelmanager" >

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--/////着信などを制御するBroadcastReceiver/////-->
        <receiver android:name=".receiver.IncomingCall">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>

    </application>

</manifest>

BroadcastReceiverを継承したIncomingCall

package jp.storyboard.testtelmanager.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

/**
 * 着信イベントを受け取る
 * Created by uramotomasaki on 15/06/03.
 * Copyright (c) 2015 Storyboard All Right Reserved.
 */
public class IncomingCall extends BroadcastReceiver {

    @SuppressWarnings("unused")
    private final String TAG = getClass().getSimpleName();

    private Context ctx;
    public void onReceive(Context context, Intent intent) {
        ctx = context;
        try {
            //TelephonyManagerの生成
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            //リスナーの登録
            MyPhoneStateListener PhoneListener = new MyPhoneStateListener();
            tm.listen(PhoneListener, PhoneStateListener.LISTEN_CALL_STATE);

        } catch (Exception e) {
            Log.e(TAG, ":" + e);
        }

    }

    /**
     * カスタムリスナーの登録
     * 着信〜終了 CALL_STATE_RINGING > CALL_STATE_OFFHOOK > CALL_STATE_IDLE
     * 不在着信 CALL_STATE_RINGING > CALL_STATE_IDLE
     */
    private class MyPhoneStateListener extends PhoneStateListener {
        @SuppressWarnings("unused")
        private final String TAG = getClass().getSimpleName();
        public void onCallStateChanged(int state, String callNumber) {
            Log.d(TAG, ":" + state+"-PhoneNumber:"+callNumber);
            switch(state){
                case TelephonyManager.CALL_STATE_IDLE:      //待ち受け(終了時)
                    Toast.makeText(ctx, "CALL_STATE_IDLE", Toast.LENGTH_LONG).show();
                    break;
                case TelephonyManager.CALL_STATE_RINGING:   //着信
                    Toast.makeText(ctx, "CALL_STATE_RINGING: " + callNumber, Toast.LENGTH_LONG).show();
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:   //通話
                    Toast.makeText(ctx, "CALL_STATE_OFFHOOK", Toast.LENGTH_LONG).show();
                    break;
            }
        }
    }
}