概述
Android四大核心组件指的是Activity,Service,ContentProvider, BroadCast Receiver,核心组件都是由Android系统进行管理和维护的,都要在清单文件中进行注册,广播接收者比较特殊,既可以在清单文件中注册,也可以直接使用代码注册,有的广播接收者,必须代码注册,如电量的改变或者屏幕的锁屏,下面是学习安桌四大组件的一个总结。
一. Activity
二. Service
BroadCast Receiver
1. 定义
广播是一种广泛运用的在应用程序之间传输信息的机制,主要用来监听系统或者应用发出的广播信息,然后根据广播信息作为相应的逻辑处理,也可以用来传输少量、频率低的数据。在实现开机启动服务和网络状态改变、电量变化、短信和来电时,通过接收系统的广播,让应用程序作出相应的操作。BroadcastReceiver 自身并不实现图形用户界面,但是当它收到某个通知后, BroadcastReceiver 可以通过启动 Service 、启动 Activity 或是 NotificationMananger 提醒用户。
2. BroadcastReceiver的注册
BroadcastReceiver的注册方式有且只有两种,一种是静态注册(推荐使用),另外一种是动态注册,广播接收者在注册后就开始监听系统或者应用之间发送的广播消息。
a.接收短信广播示例
定义自己的BroadcastReceiver 类:
public class MyBroadcastReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
//区分接收到的是哪种广播
String action = intent.getAction();
//获取广播中包含的应用包名
Uri uri = intent.getData();
if(action.equals("android.intent.action.PACKAGE_ADDED")){
System.out.println(uri + "被安装了");
}
else if(action.equals("android.intent.action.PACKAGE_REPLACED")){
System.out.println(uri + "被更新了");
}
else if(action.equals("android.intent.action.PACKAGE_REMOVED")){
System.out.println(uri + "被卸载了");
}
}
}
b. 静态方式
在AndroidManifest.xml的application里面定义receiver并设置要接收的action。
< receiver android:name = ".MyBroadcastReceiver" >
< intent-filter android:priority = "1000" >
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</ intent-filter >
</ receiver >
这里的priority取值是 -1000到1000,值越大优先级越高,同时注意加上系统接收短信的限权。
静态注册的广播接收者是一个常驻在系统中的全局监听器,当你在应用中配置了一个静态的BroadcastReceiver,安装了应用后而无论应用是否处于运行状态,广播接收者都是已经常驻在系统中了。同时应用里的所有receiver都在清单文件里面,方便查看。要销毁掉静态注册的广播接收者,可以通过调用PackageManager将Receiver禁用。
C. 动态方式
在Activity中声明BroadcastReceiver的扩展对象,在onResume中注册,onPause中卸载
public class MainActivity extends Activity {
MyBroadcastReceiver receiver;
@Override
protected void onResume() {
// 动态注册广播 (代码执行到这才会开始监听广播消息,并对广播消息作为相应的处理)
receiver = new MyBroadCastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.PACKAGE_ADDED" );
filter.addAction("android.intent.action.PACKAGE_REPLACED" );
filter.addAction("android.intent.action.PACKAGE_REMOVED" );
registerReceiver( receiver , filter);
super.onResume();
}
@Override
protected void onPause() {
// 撤销注册 (撤销注册后广播接收者将不会再监听系统的广播消息)
unregisterReceiver(receiver);
super.onPause();
}
}
3. 广播的两种类型
无序广播:所有跟广播的intent匹配的广播接收者都可以收到该广播,
并且是没有先后顺序(同时收到)
有序广播:所有跟广播的intent匹配的广播接收者都可以收到该广播,
但是会按照广播接收者的优先级来决定接收的先后顺序
优先级的定义:-1000~1000
最终接收者:所有广播接收者都接收到广播之后,它才接收,并且一定会接收
abortBroadCast:阻止其他接收者接收这条广播,类似拦截,只有有序广播可以被拦截
4. IP拨号器
原理:接收拨打电话的广播,修改广播内携带的电话号码
定义广播接收者接收打电话广播
public class CallReceiver extends BroadcastReceiver {
//当广播接收者接收到广播时,此方法会调用
@Override
public void onReceive(Context context, Intent intent) {
//拿到用户拨打的号码
String number = getResultData();
//修改广播内的号码
setResultData("17951" + number);
}
}
在清单文件中定义该广播接收者接收的广播类型
<receiver android:name="com.itheima.ipdialer.CallReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
接收打电话广播需要权限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
即使广播接收者的进程没有启动,当系统发送的广播可以被该接收者接收时,系统会自动启动该接收者所在的进
5.在代码中注册广播接收者
IntentFilter mfilter = new IntentFilter( );
mfilter.addAction("com.android.open.audio");
mfilter.addAction("com.android.close.audio");
mContext.registerReceiver( mReceiver, mfilter );
BroadcastReceiver mReceiver = new BroadcastReceiver( ) {
@Override
public void onReceive( Context context, Intent intent ) {
String action = intent.getAction( );
Log.e(TAG, "action ======= " + action);
if(action.equals("com.android.open.audio"))
{
//操作A
}else if(action.equals("com.android.close.audio"))
{
//操作B
}
}
};
6. 广播拦截
在广播接收者中,使用abortBroadcast()方法,可以终止有序广播向后继续传递,即后续的接收者们将无法接收到该广播。
注意:该方法只能在接收有序广播时调用!
7. adb命令发送广播
com.android.mybroadcast为要发送的广播
am broadcast -a com.android.mybroadcast
8. 代码发送广播
Intent intent = new Intent();
intent.setAction("com.android.mybroadcast");
//发送的额外数据
intent.putExtra("key1","value1");
intent.putExtra("key2","value2");
mContext.sendBroadcast(intent);