Android -- (14) , SMS相关。

2013/2/11


一,发送SMS

--介绍如何在应用里面发送信息。

1.1发送信息

首先要在AndroidManifest中添加一个许可:
<uses-permissionandroid:name=”android.permission.SEND_SMS”/>

这样当应用被安装的时候,就会提示此应用可能会发送SMS信息。

在应用中发送信息,可以用SmsManager类:                                                                                                     
private voidsendSMS(String phoneNumber, String message)
{
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, null, null);
}
这里首先用SmsManager的getDefault()方法来获得一个SmsManager对象,之后就可以用其sendTextMessage方法来发送信息了。
这个方法有五个参数:
➤ destinationAddress— Phone number of the recipient
➤ scAddress— Service center address; use nullfor default SMSC
➤ text— Content of the SMS message
➤ sentIntent— Pending intent to invoke when the message is sent (discussed in more detail in the 
next section)
➤ deliveryIntent— Pending intent to invoke when the message has been delivered (discussed in 
more detail in the next section)

1.2 发送信息后获得回应

--发送信息后,可能会马上成功,可能会要延迟,这里示范发送信息后返回结果。

首先,用PendingIntent对象来代表延迟和发送成功:

sentPI= PendingIntent.getBroadcast(this, 0,
newIntent(SENT), 0);
deliveredPI= PendingIntent.getBroadcast(this, 0,
newIntent(DELIVERED), 0);

这里第一个表示已发送,第二个表示发送成功。然后向活动注册两个监听器,用于监听上面两个事件(sent和delivered)的发生:
 
registerReceiver(smsDeliveredReceiver, new IntentFilter(DELIVERED)); 
registerReceiver(smsSentReceiver, new IntentFilter(SENT));                                                                                          
里面的smsDeliveredReceiver和smsSentReceiver是用于响应对应的事件(一个是DElivered事件,另一个是sent事件)的监听器。具体实现可由实际情况而定。
最后将两个PendingIntent作为最后两个参数传入sendTextMessage:
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
这样,无论信息发送成功与否,都会通过PendingIntent通知用户。

1.3用intent来发送信息

除了可以用SmsManager来发送信息外,还可以用内置的发送信息方法来发送信息:
Intent i = new
Intent(android.content.Intent.ACTION_VIEW);
i.putExtra(“address”, “5556; 5558; 5560”);
i.putExtra(“sms_body”, “Hello my friends!”);
i.setType(“vnd.android-dir/mms-sms”);
startActivity(i);
用一个intent对象 加上设置类型为
vnd.android-dir/mms-sms
设置好address和sms_body,就可以调用内置的发送信息功能。


二,接受信息


--可以在应用中用BroadcastReceiver对象来接收SMS,这样可以让你的应用在接受到特定信息的时候触发特定的功能。

2.1接收信息,用broadcastreceiver。

首先要在AndroidManifest中添加许可:

<uses-permissionandroid:name=”android.permission.RECEIVE_SMS”/>
和指定broadcastreceiver的名字:
<receiver android:name=”.SMSReceiver”>
<intent-filter>
<actionandroid:name=
“android.provider.Telephony.SMS_RECEIVED” />
</intent-filter>
</receiver>

为了监听是否有短信收到,可以用 BroadcastReceiver类,这个类可以接受被的应用以sentBoardcast方法发送的intent对象。也就是说,当别的应用以调用sentBoardcast发送intent的时候,这个类就可以接受到。当接受到某个intent对象的时候,这个类的onReceive方法就会被调用。于是你可以重写这个方法来实现你需要的功能:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{                                         Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = “SMS from “;
if(bundle != null)
SMS Messaging
{     Object[] pdus = (Object[]) bundle.get(“pdus”);
msgs = new SmsMessage[pdus.length];
for(inti=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
if(i==0) {                                                                                                                                          str += msgs[i].getOriginatingAddress();
str += “: “;
} 
                                                                                                                                                    str += msgs[i].getMessageBody().toString(); 
}

Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
Log.d(“SMSReceiver”, str);
}
}
}
这个类继承了BoardcastReceiver类。当sms到来的时候,里面的onReceive方法就会被调用,而且信息的相关内容包含在接受到的intent对象里面。Intent里面包含一个bundle对象,这个就是信息的实体了。
每一个信息对象都是存储在一个PDU 格式的object数组里面,当信息大于160个字符的时候,信息就会被存储在数组里面的多个对象中。用SmsManager类的静态方法
createFromPdu,传入从bundle中获取的object数组(object [])就可以获得包含信息内容的一个SmsManager对象(大于160个字的话多余一个,于是这里用了SmsManager数组)。
用getOriginatingAddress方法可以获得发送人的地址。而用getMessageBody方法则可以获得信息的内容。

这个时候,当一条信息发送过来,系统内置的信息工具和你定义的应用都会对信息进行响应。你也可以阻止系统内置的信息工具接受信息。只需要在内置的信息管理工具接受之前把这个信息的intent接受并处理掉即可:
<receiverandroid:name=”.SMSReceiver”>
<intent-filter android:priority=”100”>
<actionandroid:name=
“android.provider.Telephony.SMS_RECEIVED” />
</intent-filter>
</receiver>

这里添加了一个priority属性:属性值越高,就越先处理到信息。然后当你的应用处理完这个信息之后,添加一句this.abortBroadcast(); 就可以防止这个信息继续被其他程序接受。

2.2用BoardcastReceiver来更新活动

--上面中我们把接收到的信息用toast类来显示出来,你可能需要将信息内容显示在一个控件(如:Textview)里面。以下例子展示了怎么做。
我们把SMSreceiver如下设置:
package net.learn2develop.SMS;


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


public class SMSReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        //---get the SMS message passed in---
        Bundle bundle = intent.getExtras();
        SmsMessage[] msgs = null;
        String str = "SMS from ";
        if (bundle != null)
        {
            //---retrieve the SMS message received---
            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]);
                if (i==0) {
                //---get the sender address/phone number---
                str += msgs[i].getOriginatingAddress();
                str += ": ";
                } 
                //---get the message body---
                str += msgs[i].getMessageBody().toString();                
            }
            
            //---display the new SMS message---
            Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
            Log.d("SMSReceiver", str);
            
            //---stop the SMS message from being broadcasted---
            this.abortBroadcast();
            
            //---launch the SMSActivity---




            
            //---send a broadcast intent to update the SMS received in the activity---
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("SMS_RECEIVED_ACTION");
            broadcastIntent.putExtra("sms", str);
            context.sendBroadcast(broadcastIntent);
        }
    }
}
注意,上面提到,当接受到短信之后,继承了BoardcastReceiver的SMSreceiver的onReceive方法就会被调用。当处理了短信信息之后,onReceive会另外send出另外一个broadcastintent:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(“SMS_RECEIVED_ACTION”);
broadcastIntent.putExtra(“sms”, str);
context.sendBroadcast(broadcastIntent);
这里设置了setAction和加入了一个额外内容(putExtra方法)。这就让设置了接受这个intent的其他应用可以接受到(这里是同一个应用)。
然后我们设置一个broadcastReceiver来接受这个intent信号:
privateBroadcastReceiver intentReceiver= new BroadcastReceiver() {
@Override
public voidonReceive(Context context, Intent intent) {
//---display the SMS received in the TextView---												    TextView SMSes = (TextView) findViewById(R.id.textView1);
SMSes.setText(intent.getExtras().getString(“sms”));
}
};
这个broadcastreceiver接受了我们在第一步中发出的intent(里面有信息的内容),然后将内容设置到Textview上面去。
为了让这个broadcastreceiver不至于接受所有的intent(上面提到,当一个信息接受到的时候,broadcastreceiver也会接受到一个带有信息内容的intent,而现在的这个intent是我们另外发出的)。所有要设置一个intentfilter,从而是这个broadcastreceiver监听特定的Intent:
intentFilter= new IntentFilter();
intentFilter.addAction(“SMS_RECEIVED_ACTION”);
最后,我们将这一对的broadcastreceiver和intentfilter都注册到主活动中:
registerReceiver(intentReceiver, intentFilter);
这样当一个信息被接受的时候,我们的活动就会broadcast出另外一个intent,让它自己接收到。最后设置到Textview中。


2.3接受信息的同时将活动带到前台。

--只需要在SMSreceiver(继承于broadcastreceiver)的onReceive中,发送另外一个Intent之前加上:
Intent mainActivityIntent = new Intent(context, SMSActivity.class);
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainActivityIntent);
这段代码就会在接收到信息之后,将活动(原来在后台)从新带到前台。注意在活动之外调用活动,你需要setFlags为Intent.FLAG_ACTIVITY_NEW_TASK.
然后再在AndroidManifest中设置:
<activity
android:label=”@string/app_name”
android:name=”.SMSActivity”
android:launchMode=”singleTask” >
如果不设置launchMode为singleTask,那么接受到多个信息的时候就会打开多次活动。

三,发送邮件

当然也可以在应用中编程式的发送邮件:

启动邮件的Activity,也是用intent对象,只需要设置好各种信息即可:

Intent emailIntent = newIntent(Intent.ACTION_SEND);
emailIntent.setData(Uri.parse(“mailto:”));
String [] to = emailAddresses;
String [] cc = carbonCopies;
emailIntent.putExtra(Intent.EXTRA_EMAIL, to);
emailIntent.putExtra(Intent.EXTRA_CC, cc);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, message);
emailIntent.setType(“message/rfc822”);
startActivity(Intent.createChooser(emailIntent, “Email”));





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值