Android系统中关于短信(SMS)的操作

忙着游戏的开发,很长一段时间没来更新了。最近的一片都是去年更新的了。感叹时间过得真快啊。今天记录下Android手机上的短信操作,Android上的短信操作主要有这么三种:
1、发送短信
2、收短信
3、查看短信
下面逐个介绍;首先看下发送短信的demo

输入手机号码、短信内容;点击发送按钮便发送短信到指定号码的手机上了。当然这里只是个很简单demo了,如果做个良好用户体验的应用那还有很多内容需要判断的:1、手机号码的合法性2、短信内容是否过长(超过140个字)3、短信发送状态的跟踪,并提示用户关于这些操作的api,后面会陆续介绍。先看下这个简单demo:发送短信操作涉及到用户的个人信息和手机资费,所以必须获得用户的授权。在Androidmenifest.xml文件中添加相应的权限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sendsms"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.SEND_SMS" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity 的代码:
public class MainActivity extends Activity {
	private static final String TAG = "MainActivity";

	EditText phoneNumberTxt;
	EditText msgTxt;
	Button sendBtn;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		phoneNumberTxt = (EditText) findViewById(R.id.phone_number_txt);
		msgTxt = (EditText) findViewById(R.id.msg_txt);
		sendBtn = (Button) findViewById(R.id.send_btn);

		sendBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				String phoneNumber = phoneNumberTxt.getText().toString();
				String msg = msgTxt.getText().toString();

				if (phoneNumber.length() > 0 && msg.length() > 0) {
					sendSMS(phoneNumber, msg);				
				} else {
					Toast.makeText(MainActivity.this, "请输入手机号和短信内容", Toast.LENGTH_SHORT).show();
				}
			}
		});
	}

	private void sendSMS(String number, String message) {
		SmsManager smsManager = SmsManager.getDefault();
		smsManager.sendTextMessage(number, null, message, null, null);
	}
}

发送短信的操作在sendSMS方法中,需要注意的是Android framework中有两个SmsManager。
android.telephony.gsm.SmsManager和android.telephony.SmsManager;从Api level 4开始前者就被后者代替了。因为后者同时支持GSM和CDMA。
上面发送短信的操作非常简单,但是发送短信的整个过程用户体验很差,短信是否发送出去?对方是否已经接收到了?这些都未提示。要做到更好的用户
体验就需要仔细阅读下sendTextMessage这个API了。


destinationAddress the address to send the message to

scAddress is the service center address or null to use the current default SMSC 

text                 the body of the message to send

sentIntent if not NULL this PendingIntent is broadcast when the message is successfully sent, or failed. The result code will be Activity.RESULT_OK for success, or one of these errors:
RESULT_ERROR_GENERIC_FAILURE
RESULT_ERROR_RADIO_OFF
RESULT_ERROR_NULL_PDU
For RESULT_ERROR_GENERIC_FAILURE the sentIntent may include the extra "errorCode" containing a radio technology specific value, generally only useful for troubleshooting.The per-application based SMS control checks sentIntent. If sentIntent is NULL the caller will be checked against all unknown applications, which cause smaller number of SMS to be sent in checking period.
deliveryIntent if not NULL this PendingIntent is broadcast when the message is delivered to the recipient. The raw pdu of the status report is in the extended data ("pdu").

这里简单描述下五个参数
destinationAddress  短信的目标地址,也就是短信要发送到的手机号码
scAddress  关于这个地址可以查看 wiki文档 http://en.wikipedia.org/wiki/Short_message_service_center,没有特别指定就设置为null
text 这个为短信的内容
sentIntent  一个PendingIntent,在短信发送成功后发送的广播。(关于PendingIntent这里暂时不表,后面会写文章介绍。这里只需要知道可以通过它在短信发送成功后调用提示用户发送成功的代码)
deliveryIntent 同样是PendingIntent,是在对方接收到短信后发送的广播。
这里需要明白的是:短信发送并不是点对点(P2P),A发送短信给B,并不是直接就发送到B上,中间是要经过运营商的。所以会分两步,第一步是短信成功发送到运营商,第二步是运营商成功发送到目标用户。
所以这里会出现sentIntent,deliveryIntent两个PendingIntent。找到这两个入口点后,就可以添加一些代码来完成良好的用户体验了。

public class MainActivity extends Activity {

	private static final String TAG = "MainActivity";
	private static final String SENT = "SENT_SMS";
	private static final String DELIVERED = "DELIVERED_SMS";

	EditText phoneNumberTxt;
	EditText msgTxt;
	Button sendBtn;

	BroadcastReceiver sentReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			Log.e(TAG, "sent receiver onReceive");
			switch (getResultCode()) {
			case SmsManager.RESULT_ERROR_NO_SERVICE:
				showToast("短信服务不可用");
				break;
			case SmsManager.RESULT_ERROR_NULL_PDU:
				showToast("没有短信格式描述单元");
				break;
			case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
				showToast("短信未发送成功");
				break;
			case SmsManager.RESULT_ERROR_RADIO_OFF:
				showToast("没有信号");
				break;
			case Activity.RESULT_OK:
				showToast("短信已发送");
				break;
			default:
				break;
			}
		}
	};

	BroadcastReceiver deliveredReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			showToast("对方已经接收到短信");
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		phoneNumberTxt = (EditText) findViewById(R.id.phone_number_txt);
		msgTxt = (EditText) findViewById(R.id.msg_txt);
		sendBtn = (Button) findViewById(R.id.send_btn);

		sendBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				String phoneNumber = phoneNumberTxt.getText().toString();
				String msg = msgTxt.getText().toString();

				if (phoneNumber.length() > 0 && msg.length() > 0) {
					sendSMSWithMonitor(phoneNumber, msg);
				} else {
					Toast.makeText(MainActivity.this, "请输入手机号和短信内容", Toast.LENGTH_SHORT).show();
				}
			}
		});
	}

	@Override
	protected void onResume() {
		super.onResume();
		registerReceiver(sentReceiver, new IntentFilter(SENT));
		registerReceiver(deliveredReceiver, new IntentFilter(DELIVERED));
	}

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

	private void sendSMSWithMonitor(String number, String message) {
		PendingIntent sendPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
		PendingIntent deliveredPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);

		SmsManager smsManager = SmsManager.getDefault();
		smsManager.sendTextMessage(number, null, message, sendPendingIntent, deliveredPendingIntent);
	}

	private void showToast(String text) {
		Toast.makeText(this, text, Toast.LENGTH_LONG).show();
	}
}

相对之前的代码主要添加了两个BraodcastReceiver,接收短信发送成功和对方接收到的广播。这里使用的是两个隐式Intent来广播。关于显示Intent和隐式Intent会在后面的文章中说明。上面代码发送的短信是在系统的短信库里无法查到的,因为并未写入到系统的短信库中。如何写入到系统的短信库,后面的短信内容操作会详细介绍。

介绍完发送短信后,接着介绍下接收短信。接收短信相对发送短信来得简单得多。Android系统在接收到短信后会广播一个android.provider.Telephony.SMS_RECEIVED消息,接收短信只需接收这个消息,显示短信的内容即可。
public class SMSReceiver extends BroadcastReceiver {


	@Override
	public void onReceive(Context context, Intent intent) {
		Bundle bundle = intent.getExtras();
		SmsMessage[] msgs = null;
		StringBuilder sb = new StringBuilder();
		if (bundle != null) {
			Object[] pdus = (Object[]) bundle.get("pdus");
			msgs = new SmsMessage[pdus.length];
			for (int i = 0; i < pdus.length; i++) {
				msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
				sb.append(buildContentFromSmsMessage(msgs[i])).append("\n");
			}
			Toast.makeText(context, sb.toString(), Toast.LENGTH_SHORT).show();
		}


	}


	private String buildContentFromSmsMessage(SmsMessage smsMsg) {
		return smsMsg.getOriginatingAddress() + " : " + smsMsg.getMessageBody().toString();
	}
}
代码中出现的pdus表示的多个PDU,PDU是短信的数据格式(内部包含指令和数据),具体查看wiki文档http://en.wikipedia.org/wiki/Protocol_data_unit

同时在Androidmenifest.xml文件中注册:
<receiver android:name=".SMSReceiver" >
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

先写到这,后面会尽快更新短信的操作。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值