android学习十四(android的接收短信)

           收发短信是每一个手机主要的操作,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;//广播接收器
	@Override
	protected 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);//注冊广播
	}

	@Override
	public 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;
	}
	
	
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unregisterReceiver(messageReceiver);//解绑广播
	}


     
	class MessageReceiver extends BroadcastReceiver{
     //定义广播接收器
	
		@Override
		public 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;//广播接收器
	@Override
	protected 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);//注冊广播
	}

	@Override
	public 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;
	}
	
	
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unregisterReceiver(messageReceiver);//解绑广播
	}


     
	class MessageReceiver extends BroadcastReceiver{
     //定义广播接收器
	
		@Override
		public 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;//发送button
	@Override
	protected 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(){

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				/*
				 * 当sendbutton被点击时,会先调用SmsManager的getDefault()方法
				 * 获取到SmsManager的实例,然后再调用它的sendTextMessage()方法就能够
				 * 去发送短信了。sendTextMessage()方法接收5个參数,当中第一个參数用于指定
				 * 接收人的手机号码,第三个參数用于指定短信的内容。其它的几个參数我们临时用不到,
				 * 直接传入null就能够了。
				 * */
				SmsManager smsManager=SmsManager.getDefault();
				smsManager.sendTextMessage(to.getText().toString(),
						null, msgInput.getText().toString(), 
						null, null);
			}
			
		});
		
	}

	@Override
	public 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;
	}
	
	
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		unregisterReceiver(messageReceiver);//解绑广播
	}


     
	class MessageReceiver extends BroadcastReceiver{
     //定义广播接收器
	
		@Override
		public 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就拥有了发送短信的能力。只是点击sendbutton尽管将短信发送出去了。可是我们并不知道究竟发送成功了没有,这个时候就能够利用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;//发送button
	
	private IntentFilter sendFilter;//发送短信过滤器
	private SendStatusReceiver sendStatusReceiver;//发送短信广播接收器
	@Override
	protected 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(){

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				/*
				 * 当sendbutton被点击时。会先调用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); /* * 在sendbutton的点击事件里面我们调用了PendingIntent.getBroadcast()方法 * 获取到一个PendingIntent对象,并将它作为第四个參数传递到sendTextMessage() * 方法中。

然后又注冊一个新的广播接收器SendStatusReceiver。这个广播接收器就是专门 * 用于监听短信发送状态的,当getResultCode()==RESULT_OK就会提示发送成功,否则 * 提示发送失败。

* */ } }); } @Override public 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; } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); unregisterReceiver(messageReceiver);//解绑广播 unregisterReceiver(sendStatusReceiver);//解绑广播 } class MessageReceiver extends BroadcastReceiver{ //定义广播接收器 @Override public 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{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if(getResultCode()==RESULT_OK){ //短信发送成功 Toast.makeText(context, "send succeed", Toast.LENGTH_LONG).show();; }else{ //短信发送失败 Toast.makeText(context, "send failed", Toast.LENGTH_LONG).show();; } } } }



执行程序。在文本框中输入接收方的手机号码已经短信内容,然后点击sendbutton,结果例如以下所看到的:



注意:这里尽管提示发送成功了,但实际上使用模拟器来发送短信对方是不可能接收到的,仅仅有把项目执行到手机上,才干真正实现发送短信的功能。

另外。依据国际标准。每条短信的长度不得超过160个字符,假设想要发送超过这个长度的短信,则须要将这条短信切割成多条短信来发送。使用SmsManager的sendMultipartTextMessage()方法就能够实现上述功能。该方法的使用和sendTextMessage()方法也基本类似。

   短信的基本操作就总结到到这了。


转载请注明来至:http://blog.csdn.net/j903829182/article/details/41218591

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值