SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.Android 電話の発信及び状態のモニタ

【 Xamarin 記事一覧 】

1 電話の発信

(1) ACTION_DIAL


インテント経由で電話をかける場合は、アクションにACTION_DIAL、URLでtel:を指定します。
指定した電話番号がセットされた状態で電話アプリが起動し、後はコール開始のボタンを押すだけとなります。

var url = Android.Net.Uri.Parse("tel:09068739557");
var intent = new Intent(Intent.ActionDial, url);
StartActivity(intent); 

(2) CALL_PHONE


パーミッション CALL_PHONE をセットすると、アクションACTION_CALLで、いきなりのコール開始が可能です。

var uri = Android.Net.Uri.Parse("tel:0901112222");
var intent = new Intent(Intent.ActionCall, uri);
StartActivity(intent); 

2 電話状態のモニタ

相手からかかってきた電話に対する自分の対応をモニタすることができます。

電話の状態は、次のうちのどれかになります。
・アイドル状態(Idle) 未使用
・受信状態(Ringing) 呼出中
・受話状態(Off hook) 通話中

なお、ここでの状態は、自電話の状態であり、「相手が受話器を上げた」というようなイベントは取得できません。(通話中に相手が電話を切った場合は、状態が通話中(Off hook)から未使用(Idle)になるので、これを検知することは可能です)

なお、このモニタのためには、パーミッションREAD_PHONE_STATEが必要です。



(1) PhoneStateListener

最初に、リスナー用クラスを作成する方法です。
リスナー用クラスは、PhoneStateListenerクラスを継承して作成します。

internal class MyPhoneStateListener : PhoneStateListener{
    
    private readonly Context _context;
    
    public MyPhoneStateListener(Context context){
        _context = context;
    }

    public override void OnCallStateChanged(CallState state, string incomingNumber){
        base.OnCallStateChanged(state, incomingNumber);

        switch (state){
            case CallState.Idle: //アイドル状態(通話中の電話を切った場合も、このイベントが発生する)
                Toast.MakeText(_context, "idle", ToastLength.Short).Show();
                break;
            case CallState.Ringing: //相手から電話がかかってきた(発信元番号はincomingNumber)
                Toast.MakeText(_context, "Ringing : " + incomingNumber, ToastLength.Short).Show();
                break;
            case CallState.Offhook: //電話に出た
                Toast.MakeText(_context, "offhook", ToastLength.Short).Show();
                break;
        }
    }
}

作成したリスナー用クラスは、TelephonyManagerで設定及び解除します。

var listener = new MyPhoneStateListener(this);
var manager = (TelephonyManager)GetSystemService(TelephonyService);

//設定
manager.Listen(listener, PhoneStateListenerFlags.CallState);

//解除
//manager.Listen(listener, PhoneStateListenerFlags.None);

アプリが起動している間だけイベントを処理したいのであれば、上記の「設定」及び「解除」を OnResume() 及び OnPause() で処理すればいいと思います。

(2) BoardcastReceiver


次にブロードキャストレシーバで状態変化を受ける例です。常時イベントを処理したい場合は、こちらになるでしょう。

[BroadcastReceiver]
[IntentFilter(new[] { "android.intent.action.PHONE_STATE"})]
public class PhoneStateReceiver : BroadcastReceiver {
    public override void OnReceive(Context context, Intent intent){
        var state = intent.GetStringExtra(TelephonyManager.ExtraState);
        var number = intent.GetStringExtra(TelephonyManager.ExtraIncomingNumber);
        Toast.MakeText(context, state + " " + number, ToastLength.Short).Show();
    }
}


IntentからGetStringExtra()でいくつかの情報が取得可能です。






3 エミュレータへの発信


DDMの「Emulator Control」でエミュレータに対して発信が可能です。今回のデバッグはこちらで行いました。

【 Xamarin 記事一覧 】