SMS によるテキストメッセージの受信

ここでは SMS のテキストメッセージをプログラムで受信する方法を説明します。

受信といっても、プログラムで通信に関わる箇所をわざわざプログラムするのではありません。

もともとスマートフォンをプラットフォームとしてアプリケーションだけに、 SMS の通信に関わる箇所はスマートフォンが自動的に実行します。

ポイントは、プログラムから受信したメッセージをどのように読み取るか・使うかという点です。

SMS によるテキストメッセージの受信

ここで作るプログラムは次のようなプログラムです。

SMS テキストメッセージを受信したときに、そのメッセージをプログラム上に表示します。

SMS によるテキストメッセージの受信

そして、 Android にインストールされているテキストメッセージングアプリの方にもちゃんとメッセージが届き・・・

SMS によるテキストメッセージの受信

その中身が読めます。

SMS によるテキストメッセージの受信

このように、他のプログラムに影響しない形でメッセージを読み取る方法をしめします。

SMS 受信時のブロードキャスト

SMS 受信時には Android が SMS_RECEIVED (android.provider.Telephony.SMS_RECEIVED)、すなわち SMS を受信しましたというブロードキャストを送信します。

アプリケーションでそのレシーバを実装し、登録していれば、SMS が受信されたタイミングでブロードキャストを受け取ることができる、というわけです。

そのときのインテントから PDU データが取れますので、ここからメッセージを読み取ります。

レシーバーのコードは次の通りです。ここでは Android からの SMS_RECEIVED ブロードキャストを受け取り内容を読み取り、 このアプリケーション内で再度ブロードキャストを送ります。それをメインアクティビティで受け取り、TextView に内容をセットします。

package com.example.sms3;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;

public class SMSReceiveBroadcastReceiver 
  extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
  
  Bundle bundle = intent.getExtras();
  SmsMessage[] msgs = null;
  
  if(bundle == null){
    return;
  }

  StringBuilder sb = new StringBuilder();
  Object[] pdus = (Object[]) bundle.get("pdus");
  msgs = new SmsMessage[pdus.length];
  for(int i=0; i<msgs.length; i++){
    msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
    
    sb.append("--------" + i + "--------\n");
    String s = msgs[i].getOriginatingAddress();
    sb.append("OriginatingAddress: " + 
    msgs[i].getOriginatingAddress() + "\n");
    sb.append("MessageBody: " + 
    msgs[i].getMessageBody() + "\n");
  }
  
  // Send Broadcast
  Intent broadcastIntent = new Intent();
  broadcastIntent.putExtra("txt", sb.toString());
  broadcastIntent.setAction(MainActivity.ACTION_RECEIVED);
  context.sendBroadcast(broadcastIntent);  
  }

}

アクティビティ側は次の通り。

package com.example.sms3;

import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {

  public static final String ACTION_RECEIVED 
  = "com.example.sms3.ACTION_RECEIVED";
  
  TextView logTextView;
  ReceivedBroadcastReceiver receiver = null;
  IntentFilter intentFilter;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  logTextView = (TextView) findViewById(R.id.logTextView);
  }

  @Override
  protected void onPause() {
  super.onPause();
  unregisterReceiver(receiver);
  }

  @Override
  protected void onResume() {
  super.onResume();
  receiver = new ReceivedBroadcastReceiver();
  intentFilter = new IntentFilter();
  intentFilter.addAction(ACTION_RECEIVED);
  registerReceiver(receiver, intentFilter);
  }

  class ReceivedBroadcastReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    String s = intent.getStringExtra("txt");
    logTextView.setText(s);
  }    
  }
}

やっていることはきわめて単純です。ブロードキャストを受け取って、それを TextView にセットしているだけです。

AndroidManifest.xml は次の通り。SMS_RECEIVED のパーミッションと、レシーバーの登録がポイントです。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sms3"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
  android:minSdkVersion="8"
  android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

<application
  android:allowBackup="true"
  android:icon="@drawable/ic_launcher"
  android:label="@string/app_name"
  android:theme="@style/AppTheme" >
  <activity
    android:name="com.example.sms3.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>
  <receiver android:name=".SMSReceiveBroadcastReceiver">
    <intent-filter>
      <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
  </receiver>
</application>
</manifest>

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Android 開発入門