忙着游戏的开发,很长一段时间没来更新了。最近的一片都是去年更新的了。感叹时间过得真快啊。今天记录下Android手机上的短信操作,Android上的短信操作主要有这么三种:
1、发送短信
2、收短信
3、查看短信
下面逐个介绍;首先看下发送短信的demo
MainActivity 的代码:
发送短信的操作在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
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。找到这两个入口点后,就可以添加一些代码来完成良好的用户体验了。
相对之前的代码主要添加了两个BraodcastReceiver,接收短信发送成功和对方接收到的广播。这里使用的是两个隐式Intent来广播。关于显示Intent和隐式Intent会在后面的文章中说明。上面代码发送的短信是在系统的短信库里无法查到的,因为并未写入到系统的短信库中。如何写入到系统的短信库,后面的短信内容操作会详细介绍。
介绍完发送短信后,接着介绍下接收短信。接收短信相对发送短信来得简单得多。Android系统在接收到短信后会广播一个android.provider.Telephony.SMS_RECEIVED消息,接收短信只需接收这个消息,显示短信的内容即可。
同时在Androidmenifest.xml文件中注册:
先写到这,后面会尽快更新短信的操作。
1、发送短信
2、收短信
3、查看短信
下面逐个介绍;首先看下发送短信的demo
<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>
先写到这,后面会尽快更新短信的操作。