安卓中 广播 服务 及其简单应用范围的一些总结

1.广播与广播接收者

1.API

静态注册广播接收者
清单文件中配置:
<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 intent = new Intent();
        intent.putExtra("键", 要携带到接收者的信息);
        intent.setAction("自定义广播");            //设置广播监听的动作
        sendBroadcast(intent);
两种广播的区别
静态注册广播接收者在程序的整个运行期间都会监听。

动态注册的广播接收者可以控制在需要的时候开启监听,不需要的时候关闭监听。通常可以将动态注册广播接收者放到一个服务中,服务开启时注册广播,服务关闭时取消注册。

2.例子

常见系统广播
    //监听系统启动广播
    <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>
动态注册广播接收者(一般在服务中动态注册 重要)
适用情况: 广播接收者监听事件变化,有变化后就返回给服务,服务通过返回Bind或者写SharePrecefence等方法传出数据。
具体运用举例:
1.开启电话监听,监听来电去电 ,例如 黑名单,归属地查询等
2.程序加锁 ,监听当前栈顶程序是否被加锁
3.实时定位 ,不断读取当前定位信息
4.锁屏事件 ,监听到锁屏后可以做一些清理工作
5.和桌面上的Widget通信
两种注册类型的区别:
静态注册是当程序关闭后,如果有广播发过来,还能启动程序
动态注册的生命周期跟程序的生命周期是一样的,程序关闭后动态注册的广播是不能在接收到广播的


动态注册的优点:在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);

2.服务

2.1 API

注册一个服务
清单文件
    <service android:name=".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) {
        }
aidl 获取其他进程服务的信息

3.内容提供者

3.1API

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);

3.2应用场合举例

1.查询联系人数据库
2.查询短信数据库
3.音乐文件
自定义的数据库我们直接使用SQLiteOpenHelper进行查询

4.意图 的一些应用场合和分类

隐式意图
开启其他应用
    安装程序
                /**
                 * 使用隐式题图安装指定路径下的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);
显式意图
...
发送广播
    例子见第一章
开启服务
    例子见第二章
带返回值的开启新的Activity
1.A页面跳转到B:
Intent intent = new Intent(AActivity.this, BActivity.class);   

    //  如果需要返回数据,用此方法发送intent    第二个参数为发送码
    startActivityForResult(intent, 2);
2.B页面发送数据给A,B页面关闭:
Intent intent = new Intent();
    intent.putExtra("...", ...);    
    setResult(2, intent);

    finish();
3.A页面接收B传来的数据:

在A页面的类中复写以下方法,通过发送码或者返回码判断接收到数据的流向

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if(resultCode == 1)
        {
            ... 
        }else if(resultCode == 2){
            ...
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

这里写代码片

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值