android学习十四(android的接收短信)
来源:互联网 发布:linux机器上重启 编辑:程序博客网 时间:2024/06/11 03:31
收发短信是每个手机基本的操作,android手机当然也可以接收短信了。android系统提供了一系列的API,使得我们可以在自己的应用程序里接收和发送短信。
其实接收短信主要是利用我们前面学过的广播机制。当手机接收到一条短信的时候,系统会发出一条值为andorid.provider.Telephony.SMS_RECEIVED的广播,这条广播里携带着与短信相关的所有数据。每个应用程序都可以在广播接收器里对它进行监听,收到广播时在从中解析出短信的内容即可。
下面我们来个具体的例子实践下吧,新建一个SMSTest项目,首先修改activity_main.xml中的代码,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:layout_gravity="center_vertical" android:text="From:" /> <TextView android:id="@+id/sender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:layout_gravity="center_vertical" android:text="Content:" /> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> </LinearLayout>
修改MainActivity中的代码,如下:
package com.jack.smstest;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.telephony.SmsMessage;import android.view.Menu;import android.widget.TextView;public class MainActivity extends Activity {private TextView sender;private TextView content;private IntentFilter receiverFilter;//过滤器private MessageReceiver messageReceiver;//广播接收器@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sender=(TextView) findViewById(R.id.sender);content=(TextView) findViewById(R.id.content);receiverFilter=new IntentFilter();receiverFilter.addAction("android.provider.Telephony.SMS_RECEIVED");messageReceiver=new MessageReceiver();registerReceiver(messageReceiver,receiverFilter);//注册广播}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();unregisterReceiver(messageReceiver);//解绑广播} class MessageReceiver extends BroadcastReceiver{ //定义广播接收器@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stub/* * 首先从Intent参数中取出一个Bundle对象,然后使用pdu密钥来提取一个SMS pdus数组,其中 * 每一个pdu都表示一条短信消息。接着使用SmsMessage的createFromPdu()方法将每一个 * pdu字节数组转换为SmsMessage对象,调用这个对象的getOriginatingAddress()方法 * 就可以获取到发送短信的发送方号码,调用getMessageBody()方法就可以获取到短信的内容,然后 * 将获取到的发送方号码和短信内容显示在TextView上。 * */Bundle bundle=intent.getExtras();Object[] pdus=(Object[]) bundle.get("pdus");//提取短信消息SmsMessage[] messages=new SmsMessage[pdus.length];for(int i=0;i<messages.length;i++){messages[i]=SmsMessage.createFromPdu((byte[]) pdus[i]);}String address=messages[0].getOriginatingAddress();//获取发送号码String fullMessage="";for(SmsMessage message: messages){fullMessage+=message.getMessageBody();//获取短信内容}sender.setText(address);content.setText(fullMessage);}}}
上面的广播接收器使用的动态注册技术,有不懂的可以看下前面关于广播的文章。程序接短信需要一定的权限,修改AndroidManifest.xml中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jack.smstest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="13" 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.jack.smstest.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> </application></manifest>
运行程序,显示如下:
当有短信到来的时候,短信的发送方和内容就会显示在界面上。这里我们使用DDMS进行模拟短信发送,切换到DDMS视图下,然后点击Emulator Control切换卡,在这里就可以向模拟器发送短信了。如下所示:
填写了指定发送的号码为5556,并填写好一段短信,点击发送send,这样短信就发送成功了,接着我们立马查看下SMSTest这个程序,结果如下所示:
可以看到短信发送方号码和短信内容都显示到了界面,说明短信接收的功能实现了。
拦截短信
仔细观察上面的一幅图,你会发现在系统状态栏出现了一个通知图标,这个通知图标是有android自带的短信程序产生的。也就是说当短信到来的时候,不仅我们的程序会接收到这条短信,系统的程序同样会收到。同样一条短信被重复接收两遍会降低用户体验。那么怎么屏幕系统短信的接收功能了?在前面学习广播接收器的时候,学过有序广播的传递是可以截断的,而系统发出的短信广播正是一条有序广播,因此我们可以截断。修改MainActivity中的代码,如下:
package com.jack.smstest;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.telephony.SmsMessage;import android.view.Menu;import android.widget.TextView;public class MainActivity extends Activity {private TextView sender;private TextView content;private IntentFilter receiverFilter;//过滤器private MessageReceiver messageReceiver;//广播接收器@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sender=(TextView) findViewById(R.id.sender);content=(TextView) findViewById(R.id.content);receiverFilter=new IntentFilter();receiverFilter.addAction("android.provider.Telephony.SMS_RECEIVED");receiverFilter.setPriority(100);//设计优先级messageReceiver=new MessageReceiver();registerReceiver(messageReceiver,receiverFilter);//注册广播}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();unregisterReceiver(messageReceiver);//解绑广播} class MessageReceiver extends BroadcastReceiver{ //定义广播接收器@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stub/* * 首先从Intent参数中取出一个Bundle对象,然后使用pdu密钥来提取一个SMS pdus数组,其中 * 每一个pdu都表示一条短信消息。接着使用SmsMessage的createFromPdu()方法将每一个 * pdu字节数组转换为SmsMessage对象,调用这个对象的getOriginatingAddress()方法 * 就可以获取到发送短信的发送方号码,调用getMessageBody()方法就可以获取到短信的内容,然后 * 将获取到的发送方号码和短信内容显示在TextView上。 * */Bundle bundle=intent.getExtras();Object[] pdus=(Object[]) bundle.get("pdus");//提取短信消息SmsMessage[] messages=new SmsMessage[pdus.length];for(int i=0;i<messages.length;i++){messages[i]=SmsMessage.createFromPdu((byte[]) pdus[i]);}String address=messages[0].getOriginatingAddress();//获取发送号码String fullMessage="";for(SmsMessage message: messages){fullMessage+=message.getMessageBody();//获取短信内容}sender.setText(address);content.setText(fullMessage);abortBroadcast();//截断广播}}}
注意看修改的代码,关键性的步骤只有两步。一是提高MessageReceiver的优先级,让它能够优先系统短信程序接收到短信广播。二是在onReceive()方法中调用abortBroadcast()方法,中止掉广播的继续传递。
现在重新运行程序,再向模拟器发送一条短信,这时只有我们自己的程序才能收到这条短信了,按下Back键将程序关闭后,系统的短信程序又会重新拥有接收短信的功能。
注意这个功能一定要谨慎使用,随意拦截短信有可能会造成重要数据的丢失,所以在拦截之前一定要想清楚这中功能是不是你想要的。
发送短信
下面继续对SMSTest项目进行扩展,給它加上发送短信的功能。那么还是先来编写布局文件吧,修改activity_main.xml中的代码,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:layout_gravity="center_vertical" android:text="From:" /> <TextView android:id="@+id/sender" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="10dp" android:layout_gravity="center_vertical" android:text="Content:" /> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="10dp" android:text="To:" /> <EditText android:id="@+id/to" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" > <EditText android:id="@+id/msg_input" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" /> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="send" /> </LinearLayout> </LinearLayout>
修改MainActivity中的代码,在里面加入发送短信的处理逻辑,代码如下:
package com.jack.smstest;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.telephony.SmsManager;import android.telephony.SmsMessage;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class MainActivity extends Activity {private TextView sender;private TextView content;private IntentFilter receiverFilter;//过滤器private MessageReceiver messageReceiver;//广播接收器private EditText to;//接收人号码private EditText msgInput;//短信内容private Button send;//发送按钮@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sender=(TextView) findViewById(R.id.sender);content=(TextView) findViewById(R.id.content);receiverFilter=new IntentFilter();receiverFilter.addAction("android.provider.Telephony.SMS_RECEIVED");receiverFilter.setPriority(100);//设计优先级messageReceiver=new MessageReceiver();registerReceiver(messageReceiver,receiverFilter);//注册广播to=(EditText) findViewById(R.id.to);msgInput=(EditText) findViewById(R.id.msg_input);send=(Button) findViewById(R.id.send);send.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stub/* * 当send按钮被点击时,会先调用SmsManager的getDefault()方法 * 获取到SmsManager的实例,然后再调用它的sendTextMessage()方法就可以 * 去发送短信了。sendTextMessage()方法接收5个参数,其中第一个参数用于指定 * 接收人的手机号码,第三个参数用于指定短信的内容,其他的几个参数我们暂时用不到, * 直接传入null就可以了。 * */SmsManager smsManager=SmsManager.getDefault();smsManager.sendTextMessage(to.getText().toString(),null, msgInput.getText().toString(), null, null);}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();unregisterReceiver(messageReceiver);//解绑广播} class MessageReceiver extends BroadcastReceiver{ //定义广播接收器@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stub/* * 首先从Intent参数中取出一个Bundle对象,然后使用pdu密钥来提取一个SMS pdus数组,其中 * 每一个pdu都表示一条短信消息。接着使用SmsMessage的createFromPdu()方法将每一个 * pdu字节数组转换为SmsMessage对象,调用这个对象的getOriginatingAddress()方法 * 就可以获取到发送短信的发送方号码,调用getMessageBody()方法就可以获取到短信的内容,然后 * 将获取到的发送方号码和短信内容显示在TextView上。 * */Bundle bundle=intent.getExtras();Object[] pdus=(Object[]) bundle.get("pdus");//提取短信消息SmsMessage[] messages=new SmsMessage[pdus.length];for(int i=0;i<messages.length;i++){messages[i]=SmsMessage.createFromPdu((byte[]) pdus[i]);}String address=messages[0].getOriginatingAddress();//获取发送号码String fullMessage="";for(SmsMessage message: messages){fullMessage+=message.getMessageBody();//获取短信内容}sender.setText(address);content.setText(fullMessage);abortBroadcast();//截断广播}}}
发送短信需要权限,因此修改AndroidManifest.xml中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jack.smstest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="13" android:targetSdkVersion="17" /> <!--增加接收短信权限 --><uses-permission android:name="android.permission.RECEIVE_SMS"/> <!--增加发送短信权限 --> <uses-permission android:name="android.permission.SEND_SMS"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.jack.smstest.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> </application></manifest>
现在重写运行程序之后,SMSTest就拥有了发送短信的能力。不过点击send按钮虽然将短信发送出去了,但是我们并不知道到底发送成功了没有,这个时候就可以利用sendTextMessage()方法的第四个参数来对短信的发送状态进行监控了。修改MainActivity中的代码,如下所示:
package com.jack.smstest;import android.os.Bundle;import android.app.Activity;import android.app.PendingIntent;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.telephony.SmsManager;import android.telephony.SmsMessage;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {private TextView sender;private TextView content;private IntentFilter receiverFilter;//过滤器private MessageReceiver messageReceiver;//广播接收器private EditText to;//接收人号码private EditText msgInput;//短信内容private Button send;//发送按钮private IntentFilter sendFilter;//发送短信过滤器private SendStatusReceiver sendStatusReceiver;//发送短信广播接收器@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sender=(TextView) findViewById(R.id.sender);content=(TextView) findViewById(R.id.content);receiverFilter=new IntentFilter();receiverFilter.addAction("android.provider.Telephony.SMS_RECEIVED");receiverFilter.setPriority(100);//设计优先级messageReceiver=new MessageReceiver();registerReceiver(messageReceiver,receiverFilter);//注册广播to=(EditText) findViewById(R.id.to);msgInput=(EditText) findViewById(R.id.msg_input);send=(Button) findViewById(R.id.send);sendFilter=new IntentFilter();sendFilter.addAction("SENT_SMS_ACTION");sendStatusReceiver=new SendStatusReceiver();registerReceiver(sendStatusReceiver,sendFilter);send.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stub/* * 当send按钮被点击时,会先调用SmsManager的getDefault()方法 * 获取到SmsManager的实例,然后再调用它的sendTextMessage()方法就可以 * 去发送短信了。sendTextMessage()方法接收5个参数,其中第一个参数用于指定 * 接收人的手机号码,第三个参数用于指定短信的内容,其他的几个参数我们暂时用不到, * 直接传入null就可以了。 * */SmsManager smsManager=SmsManager.getDefault();Intent sendIntent=new Intent("SENT_SMS_ACTION");PendingIntent pi=PendingIntent.getBroadcast(MainActivity.this,0, sendIntent, 0);smsManager.sendTextMessage(to.getText().toString(),null, msgInput.getText().toString(), pi, null);/* * 在send按钮的点击事件里面我们调用了PendingIntent.getBroadcast()方法 * 获取到一个PendingIntent对象,并将它作为第四个参数传递到sendTextMessage() * 方法中。然后又注册一个新的广播接收器SendStatusReceiver,这个广播接收器就是专门 * 用于监听短信发送状态的,当getResultCode()==RESULT_OK就会提示发送成功,否则 * 提示发送失败。 * */}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();unregisterReceiver(messageReceiver);//解绑广播unregisterReceiver(sendStatusReceiver);//解绑广播} class MessageReceiver extends BroadcastReceiver{ //定义广播接收器@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stub/* * 首先从Intent参数中取出一个Bundle对象,然后使用pdu密钥来提取一个SMS pdus数组,其中 * 每一个pdu都表示一条短信消息。接着使用SmsMessage的createFromPdu()方法将每一个 * pdu字节数组转换为SmsMessage对象,调用这个对象的getOriginatingAddress()方法 * 就可以获取到发送短信的发送方号码,调用getMessageBody()方法就可以获取到短信的内容,然后 * 将获取到的发送方号码和短信内容显示在TextView上。 * */Bundle bundle=intent.getExtras();Object[] pdus=(Object[]) bundle.get("pdus");//提取短信消息SmsMessage[] messages=new SmsMessage[pdus.length];for(int i=0;i<messages.length;i++){messages[i]=SmsMessage.createFromPdu((byte[]) pdus[i]);}String address=messages[0].getOriginatingAddress();//获取发送号码String fullMessage="";for(SmsMessage message: messages){fullMessage+=message.getMessageBody();//获取短信内容}sender.setText(address);content.setText(fullMessage);abortBroadcast();//截断广播}}class SendStatusReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubif(getResultCode()==RESULT_OK){//短信发送成功Toast.makeText(context, "send succeed", Toast.LENGTH_LONG).show();;}else{//短信发送失败Toast.makeText(context, "send failed",Toast.LENGTH_LONG).show();;}}}}
运行程序,在文本框中输入接收方的手机号码已经短信内容,然后点击send按钮,结果如下所示:
注意:这里虽然提示发送成功了,但实际上使用模拟器来发送短信对方是不可能接收到的,只有把项目运行到手机上,才能真正实现发送短信的功能。
另外,根据国际标准,每条短信的长度不得超过160个字符,如果想要发送超过这个长度的短信,则需要将这条短信分割成多条短信来发送,使用SmsManager的sendMultipartTextMessage()方法就可以实现上述功能。该方法的使用和sendTextMessage()方法也基本类似。
短信的基本操作就总结到到这了。
转载请注明来至:http://blog.csdn.net/j903829182/article/details/41218591
- android学习十四(android的接收短信)
- android 短信的接收!
- Android的短信接收类
- 短信接收--Android彩信的接收流程(应用层)
- android broadcast学习之监控他人手机接收的短信
- Android学习(1)——接收和发送短信
- Android拦截短信,接收短信
- android接收短信功能
- android 短信接收
- Android-拦截接收短信
- android 接收短信流程
- Android接收端口短信
- android短信接收过程
- Android 短信接收监听
- android短信接收流程
- Android-拦截接收短信
- 短信接收 Android
- android短信接收/发送
- ini_set ini_get ini_get_all ini_restore 的理解分析
- Unity3d学习之路:开始篇章
- 新手学,java使用分水岭算法进行图像分割(一)
- AOP 示意图解释
- 计算机基础知识——ASCII码
- android学习十四(android的接收短信)
- 大数据分析及处理
- shiro安全框架扩展教程--如何防止可执行文件的入侵攻击
- JSON相关的学习笔记,json的表示方法,eval(),parse(),stringify()方法的使用
- MFC框架
- 主题模型-LDA浅析
- 主场景当中添加层,然后有一个get方法,方便使用
- Qt连接数据库之sqlite
- Java Serialization机制和transient