10.1.1全局事件——广播(BroadcastReceiver)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

10.1.1全局事件——广播(BroadcastReceiver)
广播是Android SDK的4大组件中唯一需要被动接收数据的组件,Activity,ContentProvider,Service 可以主动调用并返回数据,但是负责接受Broadcast的数据的连接器却永远也不知道什么时候可以接收到广播,所以广播可以被称为全局事件,系统事件。

广播机制的图解:
在使用广播时需要在androidmanifest.xml文件中注册,在使用时则根据注册代码中的intent-filter中的anction-name来判断调用哪个广播接收器来处理。

现在我们来看一下怎么发送广播:
发送广播流程:
现在来看具体的业务代码:
在广播类中:
package com.it.junms;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
publicclass SMSBroadcastReceiver extends BroadcastReceiver {
private String tag="SMSBroadcastReceiver";
@Override
publicvoid onReceive(Context context, Intent intent) { // TODO Auto-generated method stub可以通过intent获取到的action判断是否是要接收的广播
Log.d(tag, "广播发送成功");
}
}
在Main类中:
package com.it.junms;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
publicclass JunmsBroadcastActivity extends Activity {
/** Called when the activity is first created. */
private Button btnSendBroadcast=null;
//private SMSBroadcastReceiver smsBroadcastReceiver=null;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yout.main);
btnSendBroadcast=(Button)findViewById(R.id.btnSendBroadcast); btnSendBroadcast.setOnClickListener(new OnClickListener() {
@Override
publicvoid onClick(View v) {
// TODO Auto-generated method stub
//smsBroadcastReceiver = new
SMSBroadcastReceiver();
Intent intent = new
Intent("android.provider.Telephony.SMS_RECEIVED");
//intent.setAction("android.provider.Telephony.SMS_RECEIVED ");
JunmsBroadcastActivity.this.sendBroadcast(intent);
}
});
}
}
在AndroidManifest.xml文件中的注册广播代码:
<receiver android:name="SMSBroadcastReceiver"android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
运行效果图:
准备发送广播
接收器收到后的处理结果:
下面是较为重要的3个例子:
1、短信拦截
package com.it.junms;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.widget.Toast;
publicclass SMSBroadcastReceiver extends BroadcastReceiver {
private String tag="SMSBroadcastReceiver";
@Override
publicvoid onReceive(Context context, Intent intent) { // TODO Auto-generated method stub
Bundle bundle=intent.getExtras();
Object[] data = (Object[])bundle.get("pdus");
SmsMessage[] sms = new SmsMessage[data.length];
/*
*用于回复短信(回复短信功能未经测试)
*SmsManager smsManager =SmsManager.getDefault();
*String content,to;
*/
for (int i = 0; i < sms.length; i++) {
sms[i]=SmsMessage.createFromPdu((byte[])data[i]);
String s="短信号码:
"+sms[i].getDisplayOriginatingAddress()+"\n短信内容:
"+sms[i].getDisplayMessageBody();
/*
* 用于回复短信
*在测试回复短信时,注意添加发送短信权限
* 在此短信内容可以自己确定
*content=sms[i].getDisplayMessageBody();
*to=sms[i].getDisplayOriginatingAddress();
*smsManager.sendTextMessage(null, to, content,
null,null);
*/
Toast.makeText(context, s, Toast.LENGTH_LONG).show();
}
}
}
在AndroidManifest.xml文件中添加权限代码和注册代码:
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <receiverandroid:name="SMSBroadcastReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter>
</receiver>
运行效果图:
使用Emulator Consol控制台发送短信
显示拦截短信(“发送广播……”按钮与此没有任何关系),Toast提示的内容就是拦截的短信内容和短信号码
2、去来电拦截:
去来电的广播动作:
来电:android.intent.action.PHONE_STATE
去电:android.intent.action.NEW_OUTGOING_CALL
在读取(拦截)来电时注意添加权限:
<uses-permission
android:name="android.permission.READ_PHONE_STATE"/>
下面是主要代码:
package com.it.junms;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.widget.Toast;
publicclass CallInBroadcastReceiver extends BroadcastReceiver {
@Override
publicvoid onReceive(Context context, Intent intent) { // TODO Auto-generated method stub
//在此只处理了响铃时状态的操作,如果想处理其他状态下的操作可以继续在case中判断
TelephonyManager telephonyManager =
(TelephonyManager)context.getSystemService(Service.TELEPHONY_S ERVICE);
switch (telephonyManager.getCallState()) {
case TelephonyManager.CALL_STATE_RINGING://响铃
String
incomingTel=intent.getStringExtra("incoming_number");
Toast.makeText(context, "来电号码:"+incomingTel, Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
}
在AndroidManifest.xml文件中添加权限代码和注册代码:
<uses-permission
android:name="android.permission.READ_PHONE_STATE"/>
<receiver android:name="CallInBroadcastReceiver" android:enabled="true">
<intent-filter >
<action
android:name="android.intent.action.PHONE_STATE"></action>
</intent-filter>
</receiver>
运行效果图:
使用Emulator Consol控制台拨号
拦截的来电号码
TelephoneManager的状态值(判断相应的状态做相应的处理)
3、显示当前电量值
在main类中创建一个BroadcastReceiver对象,在onReceive方法中获取当前电量值和当前电量的总刻度表
Level:表示当前电量的值
Scale:表示当前电量的总刻度表
在本例子中采用代码注册Receiver
主要使用Action:ACTION_BATTERY_CHANGED
如果要显示电量其他状态下的情况,可以改变Action
下面是主要代码:
package com.it.junms;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
publicclass JunmsBroadcastActivity extends Activity {
/** Called when the activity is first created. */
private Button btnSendBroadcast=null;
private Button btnShowBatteryChangeValue=null;
//private SMSBroadcastReceiver smsBroadcastReceiver=null;
private BroadcastReceiver batteryChangeReceiver=new BatteryChangedBraodcastReceiver(){
@Override
publicvoid onReceive(Context context, Intent intent) {
if(Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction()) ){
//level表示当前电量的值
int level=intent.getIntExtra("level",0);
//scale表示电量的总刻度
int scale=intent.getIntExtra("scale",100);
int val=level*100/scale;
Toast.makeText(context, "当前电量:"+val+"%", Toast.LENGTH_LONG).show();
}
super.onReceive(context, intent);
}
};
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yout.main);
btnSendBroadcast=(Button)findViewById(R.id.btnSendBroadcast); btnShowBatteryChangeValue=(Button)findViewById(R.id.btnShowBat teryChangeValue);
btnSendBroadcast.setOnClickListener(new OnClickListener() {
@Override
publicvoid onClick(View v) {
//smsBroadcastReceiver = new
SMSBroadcastReceiver();
Intent intent = new
Intent("android.provider.Telephony.SMS_RECEIVED");
//intent.setAction("android.provider.Telephony.SMS_RECEIVED ");
JunmsBroadcastActivity.this.sendBroadcast(intent);
}
});
btnShowBatteryChangeValue.setOnClickListener(new
OnClickListener() {
@Override
publicvoid onClick(View v) {
//相当于在androidmanifest.xml注册文件中的action-name
registerReceiver(batteryChangeReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
});
}
}
运行效果图:(“发送广播”按钮在此没有任何用处)
用代码注册广播
用代码注册广播主要用到2个方法:
registerReceiver(receiver, filter); //注册
unregisterReceiver(receiver); //取消注册
解释:用代码注册广播不是常住型广播,会跟随程序的生命周期存在和销毁;在androidmanifest.xml文件中注册是常住行广播,即使程序关闭后有信息广播来,程序也会被系统调用来自动运行。

验证广播接收器是否注册
package com.it.junms;
import java.util.List;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
publicclass JunmsBroadcastActivity extends Activity {
/** Called when the activity is first created. */
private Button btnSendBroadcast=null;
private Button btnShowBatteryChangeValue=null;
private Button btnShowRegistedBroadcast=null;
//private SMSBroadcastReceiver smsBroadcastReceiver=null;
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yout.main);
btnSendBroadcast=(Button)findViewById(R.id.btnSendBroadcast); btnShowRegistedBroadcast=(Button)findViewById(R.id.btnShowRegi stedBroadcast);
btnShowBatteryChangeValue=(Button)findViewById(R.id.btnShowBat teryChangeValue);
btnShowRegistedBroadcast.setOnClickListener(new
OnClickListener() {
@Override
publicvoid onClick(View v) {
// TODO Auto-generated method stub
PackageManager packageManager=getPackageManager();
//指定要查询的广播动作
Intent intent = new
Intent("android.intent.action.PHONE_STATE");
//返回已查到的广播对象,如果没有查询到,则list集合的数量为0
List<ResolveInfo>resolveInfos=
packageManager.queryBroadcastReceivers(intent,
PackageManager.GET_INTENT_FILTERS);
Toast.makeText(JunmsBroadcastActivity.this, resolveInfos.size()+"", Toast.LENGTH_LONG).show();
for (ResolveInfo resolveInfo : resolveInfos) {
String
str=String.valueOf(resolveInfo.toString());
Toast.makeText(JunmsBroadcastActivity.this, str, Toast.LENGTH_LONG).show();
}
}
});
}
}
运行效果图:
该图是检测了一个广播接收器未注册的效果
该图是检测一个广播接收器已经注册的效果
以上内容是广播机制的简单原理和应用,如有不正确的地方还请各位同仁列举出来,本人加以修改,重在技术学习和交流!。

相关文档
最新文档