SIN@SAPPOROWORKSの覚書

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

Xamarin.Android SMS(Cメール)送信

【 Xamarin 記事一覧 】

1 SmsManagerによる送信

SMSメッセージをアプリの中から操作する場合は、SmsManagerを使用します。
SmsManager.DefaultでSmsManagerクラスのインスタンスを作成しSendTextMessage()で送信します。
なお、SMSメッセーシ送信は、SEND_SMSパーミッションの設定が必要です。

var destinationAddress = "090xxxxxxxx";//受信者の電話番号
var scAddress = (string)null;//サービスセンターアドレス nullを指定するとシステムのデフォルト値が使用されます
var text = "本日は晴天なり\r\n今日も元気に頑張りましょう";//メッセージ
var sentIntent = (PendingIntent)null; //送信の成否をインテントに送る場合に指定する
var deliveryIntent = (PendingIntent)null; // 受信者に届いた時にBroadcastを受け取る場合に指定する
  
SmsManager.Default.SendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);

エミュレータでは、何番に送れば自分宛になるのか、ちょっと分からなかったので実機で動作確認しました。
ちなみに、自端末への送信といってもキャリア経由なので、それなりに少し時間はかかる・・・


2 インテント経由の呼び出し

インテント経由でもSMSメッセージを送信することができますが、この場合、パーミッションは必要ありません。
アクションにACTION_SENDTO、URIで電話番号をセットして暗黙的インテントを呼び出すだけです。
こちらの方法は、送信するSMSの編集画面が開きます。

var smsUri = Android.Net.Uri.Parse("smsto:00000000000");
var smsIntent = new Intent(Intent.ActionSendto, smsUri);
smsIntent.PutExtra("sms_body", "本日は晴天なり\r\n今日も元気に頑張りましょう");
StartActivity(smsIntent);

バックグラウンドで送信する必要がなければ、こちらの方がセキュリティ上お勧めなのかも知れません。


3 SMS送信時の完了確認

SmsManagerのSendTextMessageを使用した場合、送信完了と受信完了(受信者がメールを開いた時)のイベントを処理できす。
SendTextMessageの第4パラメータ(sentIntent)及び、第5パラメータ(deliveryIntent)にブロードキャストするインテントをセットします。

var destinationAddress = "090xxxxxxxx";
var scAddress = (string)null;
var text = "メッセージ";
//送信完了時のインテント
var sentIntent = PendingIntent.GetBroadcast(this, 0, new Intent("SMS_SENT"), 0);
//受信完了時のインテント
var deliveryIntent = PendingIntent.GetBroadcast(this, 0, new Intent("SMS_DELIVERED"), 0);
  
SmsManager.Default.SendTextMessage(destinationAddress, scAddress, text, sentIntent, deliveryIntent);

ブロードキャストを受け取る側のコードは次のようになる

//送信完了のブロードキャストを受け取るレシーバ
[BroadcastReceiver]
[IntentFilter(new[] { "SMS_SENT" })]
public class SMSSentReceiver : BroadcastReceiver {
   public override void OnReceive(Context context, Intent intent) {
       Toast.MakeText(context,"SEND "+ResultCode.ToString(),ToastLength.Short).Show();

// 受け取る戻り値は以下の種類があります
//	Result.Ok:"SMS has been sent"
//      SmsResultError.GenericFailure: "Generic Failure"
//	SmsResultError.NoService:"No Service"
//      SmsResultError.NullPdu:"Null PDU"
//      SmsResultError.RadioOff:"Radio Off"

   }
}

//受信完了のブロードキャストを受け取るレシーバ
[BroadcastReceiver]
[IntentFilter(new[] { "SMS_DELIVERED" })]
public class SMSDeliverdReceiver  : BroadcastReceiver {
    public override void OnReceive(Context context, Intent intent){
        Toast.MakeText(context, "DELIVERED "+ResultCode.ToString(), ToastLength.Short).Show();

// 受け取る戻り値は以下の種類があります
//      Result.Ok:"SMS Delivered"
//      Result.Canceled:"SMS not delivered"

    }
}


4 OnResumeとOnPause

OnResume及びOnPauseで、ブロードキャストレシーバの有効無効を設定する必要がある場合は、下記のようになります。

private BroadcastReceiver _smsSentBroadcastReceiver, _smsDeliveredBroadcastReceiver;

protected override void OnResume(){
    base.OnResume();
    //ブロードキャストレシーバーのインスタンスを生成する
    _smsSentBroadcastReceiver = new SMSSentReceiver();
    _smsDeliveredBroadcastReceiver = new SMSDeliveredReceiver();
    //インテントフィルタと紐づける
    RegisterReceiver(_smsSentBroadcastReceiver, new IntentFilter("SMS_SENT"));
    RegisterReceiver(_smsDeliveredBroadcastReceiver, new IntentFilter("SMS_DELIVERED"));
}

protected override void OnPause(){
    base.OnPause();
    //紐づけを解除する
    UnregisterReceiver(_smsSentBroadcastReceiver);
    UnregisterReceiver(_smsDeliveredBroadcastReceiver);
}

【 Xamarin 記事一覧 】