清单文件中配置:
<receiver android:name="包名.广播接收者文件" >
<intent-filter android:priority="广播拦截的优先级(最大:2147483647)" >
<action android:name="广播监听的动作 可以是自定义的或者系统广播" />
intent-filter>
receiver>
1.动态创建一个广播接收者
class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//收到广播后
//1.可以触发某些事件
//2.从initen参数中获取广播发送的数据
}
};
2.对广播接收者进行动态注册
Receiver = new MyReceiver();
//设置filter信息
IntentFilter filter = new IntentFilter();
filter.addAction("自定义的或者系统广播"); //设置广播监听的动作
//注册
registerReceiver(Receiver, filter);
3.取消注册
unregisterReceiver(mReceiver);
mReceiver = null;
Intent intent = new Intent();
intent.putExtra("键", 要携带到接收者的信息);
intent.setAction("自定义广播"); //设置广播监听的动作
sendBroadcast(intent);
静态注册广播接收者在程序的整个运行期间都会监听。
动态注册的广播接收者可以控制在需要的时候开启监听,不需要的时候关闭监听。通常可以将动态注册广播接收者放到一个服务中,服务开启时注册广播,服务关闭时取消注册。
//监听系统启动广播
<receiver android:name=".receiver.BootCompleteReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
intent-filter>
receiver>
//监听短信
<receiver android:name=".receiver.SmsReceiver" >
<intent-filter android:priority="2147483647" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
intent-filter>
receiver>
//获取管理员权限 MyAdminReceiver需要实现但是不用写内容
<receiver
android:name=".receiver.MyAdminReceiver"
android:description="@string/sample_device_admin_description"
android:label="@string/sample_device_admin"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin_sample" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
intent-filter>
receiver>
//监听创建快捷方式
<receiver android:name=".receiver.MyWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/process_widget_provider" />
receiver>
//监听杀死所有进程
<receiver android:name=".receiver.KillProcess">
<intent-filter>
<action android:name="com.example.mobilesafe.KILLALLPROCESS" />
intent-filter>
receiver>
两种注册类型的区别:
静态注册是当程序关闭后,如果有广播发过来,还能启动程序
动态注册的生命周期跟程序的生命周期是一样的,程序关闭后动态注册的广播是不能在接收到广播的
动态注册的优点:在Android的广播机制中,动态注册的优先级高于静态注册的优先级,因此在必要情况下,我们需要动态注册广播接收器。
静态注册的有点:动态注册广播接收器还有一个优点就是当用来注册广播的Activity关闭后,广播也就失效了,同时反映了静态注册广播的一个优势,就是无需担心广播接收器是否关闭,只要设备处于开启状态,广播接收器就能接收。
操作频繁的广播事件,如果只是在清单配置文件配置,是不生效的。需要使用代码注册才能生效;
步骤:
例1:// 监听屏幕开关
// 1、得到广播接收者的对象
ScreenBroadCastReceiver screenReceiver = new ScreenBroadCastReceiver();
// 2、创建一个intentFilter对象
IntentFilter filter = new IntentFilter();
// 3、注册接收的事件类型
filter.addAction("android.intent.action.SCREEN_ON");
filter.addAction("android.intent.action.SCREEN_OFF");
// 4、注册广播接收者
this.registerReceiver(screenReceiver, filter);
例2.// 注册监听去电的广播
mReceiver = new OutCallReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
registerReceiver(mReceiver, filter);
以上两例需要我们自己实现广播接收者,下面这个例子中系统为我们实现了回调方法
例3. //来电话
mListener = new MyPhoneStateListener();
mTM.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);// 监听来电状态
class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:// 电话玲响
break;
case TelephonyManager.CALL_STATE_IDLE:// 通话结束
break;
default:
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
例4.//设置快捷方式
Intent intent = new Intent(
"com.android.launcher.action.INSTALL_SHORTCUT");
// 设置快捷方式的图标
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, BitmapFactory
.decodeResource(getResources(), R.drawable.home_tools));
// 设置快捷方式名称
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "黑马小卫士");
//不允许重复
intent.putExtra("duplicate", false);
// 动作,跳转主页面
Intent actionIntent = new Intent();
actionIntent.setClass(this,MainActivity.class);
//actionIntent.setAction("com.example.mobilesafe.MAIN");// 通过action启动主页面,需要在清单文件配置action
//actionIntent.addCategory(Intent.CATEGORY_DEFAULT);// 必须配置categroy
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, actionIntent);
// 发送广播
sendBroadcast(intent);
清单文件
".service.MyService" />
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
//创建服务的时候调用
@Override
public void onCreate() {
System.out.println("*****onCreate******");
super.onCreate();
}
//启动server 每次start都会调用一次
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("*****onStartCommand******");
return super.onStartCommand(intent, flags, startId);
}
//手动停止程序后会终止服务,会调用onDestroy()方法
@Override
public void onDestroy() {
System.out.println("*****onDestroy******");
super.onDestroy();
}
}
1.启动
//使用Intent
Intent intent = new Intent(当前Activity.this, MyService.class);
startService(intent);
stopService(intent);
2.使用bind让其他组件获取服务提供的数据
//使用Intent
Intent intent = new Intent(当前Activity.this, MyService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
unbindService(conn);
bindService绑定服务、unBindService解除绑定的服务;
服务是在被绑定的时候被创建,调用oncreate、onbind方法;
服务只能被绑定一次;
服务只能被解除一次,接触绑定的时候调用onUnbind、onDestrory方法,如果多次解除绑定会抛出异常;
推荐的方式(启用顺序):
1.startService:开启并创建一个服务,服务长期运行在后台;
2.bindService:绑定服务,可以调用服务里面的方法;
3.unBindService:解除服务,停止服务里面的方法;
4.stopService:停止服务,销毁服务对象;
MyService中
//这个函数用于返回数据
public IBinder onBind(Intent intent)
{
return new MyBind(); //返回到前台的对象,包含要执行的service中的方法
}
//继承Binder类,这是因为要返回一个实现IBinder类型接口的
public class MyBind extends Binder
{
public void callPaly() {
paly();
}
}
客户端
//绑定服务
bindService(intent, new MyServiceConnection(), BIND_AUTO_CREATE);
//获取服务返回的数据
class MyServiceConnection implements ServiceConnection
{
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//返回服务中包含要调用方法的类
serverRet = (MyBind) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
1.内容解释者
作用: 用来解析内容观察者提供的数据库信息
ContentResolver contentResolver = getContentResolver();
//getContentResolver();是上下文中携带的方法,用于处理内容提供者提供的访问方式。
寻找哪个内容提供者需要用通过uri,uri路径分文 "主机名"+"具体要操作的数据" 其中"主机名"在提供数据库程序的清单文件中定义,"具体要操作的数据"在这个程序的源码中(一般文件名有provide字样),
我们可以通过查找"UriMatcher"函数搜索相关的信息。
Uri uri = Uri.parse("content://.../"); //指定查询哪个应用下数据库的哪个表
Cursor cursor = contentResolver.query(uri, ... ...);
2.内容观察者
//注册内容观察者
getContentResolver().registerContentObserver(uri, true, new MyObeserver(new Handler()));
//收到通知后回调其中的方法
class MyObeserver extends ContentObserver
{
public MyObeserver(Handler handler) {
super(handler);
}
//发现监视路径下的数据库发生变化就会调用此方法
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
}
}
//在数据库操作中发出信号,通知观察者
// 通知观察者,数据发生变化了
Context.getContentResolver().notifyChange(Uri.parse("content://..."),null);
开启其他应用
安装程序
/**
* 使用隐式题图安装指定路径下的apk
* @param path
*/
private void installApk(String path)
{
File file = new File(path);
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
//startActivity(intent);
startActivityForResult(intent, 0);
}
卸载程序
/**
* 卸载应用
*/
private void uninstall(String packageName) {
// 跳转到卸载页面
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:" + packageName));
startActivityForResult(intent, 0);
}
清理缓存
// 清理单个文件缓存
// 跳转到系统设置页面
Intent intent = new Intent();
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.parse("package:" + info.packageName));
intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
打电话
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setAction(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:"+number));
startActivity(intent);
...
例子见第一章
例子见第二章
Intent intent = new Intent(AActivity.this, BActivity.class);
// 如果需要返回数据,用此方法发送intent 第二个参数为发送码
startActivityForResult(intent, 2);
Intent intent = new Intent();
intent.putExtra("...", ...);
setResult(2, intent);
finish();
在A页面的类中复写以下方法,通过发送码或者返回码判断接收到数据的流向
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == 1)
{
...
}else if(resultCode == 2){
...
}
super.onActivityResult(requestCode, resultCode, data);
}
这里写代码片