广播介绍
广播被分为两种不同的类型,“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。普通广播是完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;然而有序广播是按照接收者声明的优先级别(声明在intent-filter元素的android:priority属性中,数据大优先级别越高,取值范围:-1000到1000也可以调用IntentFilter对象的setPriority()进行设置),被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
Context.sendBroadcast()发送的是普通广播,所有订阅者都有机会获得并进行处理。
Context.sendOrderedBroadcast()发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast() ),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将处理结果存进广播Intent,然后传给下一个接收者。
sendStickyBroadcast() 意思只要是如果发送广播之后才执行registerReceiver(BroadcastReceiver,IntentFilter).这个方法依然可以接受到。换句话说,在ReceiverActivity里是通过代码来注册Recevier而不是在Manifest里面注册的。sendStickyBroadcast发出的最后一个Intent会被保留,当下次Recevier处于活跃的时候,又会接受到它。需要加BROADCAST_STICKY权限,否则会抛SecurityException
安卓手机中的短信适合用广播来监测,需要注册广播。此外还可以用来过滤短信,可根据内容和电话号码来过滤短信
把主要代码传上来存盘,方便以后忘记时上来取
首先:订阅感兴趣的广播 Intent ,订阅方法有两种:
第一种:使用代码进行订阅
Java代码
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerClass receiver = new registerClass();
registerReceiver(receiver, filter);
第二种:在 AndroidManifest.xml 文件中的 <application> 节点里进行订阅 :
Html代码
<receiver android:name=".IncomingSMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
package com.lan.www;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
// 这是那个广播类,需继承系统的
public class SmsReciver extends BroadcastReceiver {
private final String MagicString = "lan";
//onReceive的生命周期为10秒,所以里面的操作不能超过10秒
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if((intent.getAction()!=null)&&(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))) //这个action是系统短信专属
{
StringBuffer sb = new StringBuffer();
Bundle bundle = intent.getExtras(); //如果有短信过来,Android系统其实就是用一个Bundle来存短信的
if(bundle!=null)
{
//短信头是一个pdus
Object[] pdus = (Object[]) bundle.get("pdus"); //一条短信(中文是70个字符左右,英文是140左右,都包括了标点符号),可能不只一条,但每一条都有pdus
SmsMessage[] msgs = new SmsMessage[pdus.length]; //有多少条短信就有多少条短信
for (int i = 0; i < msgs.length; i++) {
//短信内容
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
//得到电话号码,一般取第一条短信的电话号码就可以了,要想严谨就应该每条短信都应该进行取电话号码,因为这时可能其他人也在发短信过来,
String telnumber = msgs[0].getOriginatingAddress();
for (SmsMessage smsMessage : msgs) {
sb.append(smsMessage.getMessageBody());
}
if(smgs.length() >0){
}
Log.i("lan", "SMS telnumber="+telnumber+" info="+sb.toString());
//过滤短信
if(sb.indexOf(MagicString)!=-1)
{
//有过滤的短信内容在里面就清除
sb = null;
//阻止广播播出
this.abortBroadcast();
}
if(sb!=null&&sb.length()!=0)
{
Intent it = new Intent(context, SMS1Activity.class).putExtra("info", sb.toString()).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(it);//我这里传给另一个界面了
}
}
//这个方法有时不好用,不好用就加在这里试试
// this.abortBroadcast();
}
}
}
在AndroidManifest.xml文件中进行配置:
<receiver android:name="SmsReciver">
<intent-filter android:priority="1000"> //权限越高,才能确保执行,目前最高是int 类型,
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_SMS"/><!-- 接收短信权限 -->
<uses-permission android:name="android.permission.SEND_SMS"/><!-- 发送短信权限 -->
另发送短信
SmsManager sms = SmsManager.getDefault(); //得到系统的短信管理器
ArrayList<String> texts = sms.divideMessage(text.toString()); //分成若干条短信
PendingIntent pi = PendingIntent.getBroadcast( //不一定发生时,用此类
SendNotify.this,
0,
new Intent(),
0);
for (String string : texts) {
for (int i = 0; i < phones.length; i++) {
sms.sendTextMessage(phones[i], null, string, pi, null); //发送短信
}
}
下面这段摘自http://www.2cto.com/kf/201206/137542.html
如果想在播出的电话加上特殊提示或者默认加上区号,12593优惠号等,那么就需要监听外拨的电话,并进行处理:
向外拨打电话时系统会发出一个有序广播,虽然该广播最终会被拔号器里的广播接收者所接收并实现电话拔打,但我们可以在广播传递给拔号广播接收者之前先得到该广播,然后清除传递给拔号广播接收者的电话号码,在拔号广播接收者接收到该广播时,由于电话号码为null,因此取消电话拔打。
public class OutgoingCallReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
setResultData(null); //清除电话,广播被传给系统的接收者后,因为电话为null,取消电话拔打
// 同样如果你想修改外拔的电话号码,可以这样做
// String phone = getResultData();//得到外拔电话
// setResultData(“12593”+ phone);//在电话前面加上12593
}
}
接收外拔电话广播Intent,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiver android:name=".OutgoingCallReceiver">
<intent-filter android:priority="1">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
并且要进行权限声明:
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>