Android四大组件之BroadcastReceiver

来源:互联网 发布:阿里 知乎 编辑:程序博客网 时间:2024/05/29 12:18

1 为什么需要广播接收者(BroadcastReceiver)

【1】有什么样的人员听广播?老人 出租车司机  等等

【2】想听广播必须得有:电台  收音机

【3】Android系统内部已经定义好了电台,已经定义好了一些广播事件,比如:外拨电话、短信到来、SD卡状态、电池电量等等

【4】使用BroadcastReceiver去接收系统已经定义好的这些事件

【5】定义广播接收者的目的是为了方便开发者进行开发

补充:javame(针对移动开发)  javase(java基础) javaee(web开发)

2 案例:IP拨号器(17951)

【1】定义广播接收者继承BroadcastReceiver

public class OutGoingCallReceiver extendsBroadcastReceiver {//☆☆☆☆第一步[1]

         //当进行外拨电话的时候调用

         @Override

         publicvoid onReceive(Context content, Intent intent) {

 

                   //[1]获取当前拨打的电话号码

                   StringcurrentNumber = getResultData();

                   //[2]在当前的号码前面加上17951

                   //[2.1]判断当前拨打的号码是否是长途

                   if(currentNumber.startsWith("0")) {

                            setResultData("17951"+currentNumber);

                   }

         }

}

【2】在清单文件中配置

<receiver  android:name="com.itheima.ipdail.OutGoingCallReceiver">

           <intent-filter >

                <action

                   android:name="android.intent.action.NEW_OUTGOING_CALL"//☆☆☆第三步[3]

                    />

           </intent-filter>

       </receiver>

【3】实现相应的逻辑

 //点击按钮 保存用户输入的ip号码
    public void click(View v){
        //[1]获取用户输入的ip号码
        String ipnumber = et_ipnumber.getText().toString().trim();
        //[2]把当前ipnumber存起来 存到sp中
        SharedPreferences sp = getSharedPreferences("config", 0);
        //[3]获取sp的编辑器
        sp.edit().putString("ipnumber", ipnumber).commit();
        //[4]保存成功
        Toast.makeText(getApplicationContext(), "保存成功", 1).show();
    }

【4】记得加上权限:PROCERSS_OUTGOING_CALLS


3 案例:SD卡状态监听器

         [1]    定义广播接受者并且继承BroadcastReceiver

         publicclass SdcardStateReceiver extends BroadcastReceiver {

 

         //当SD卡状态发生改变的时候执行

         @Override

         publicvoid onReceive(Context context, Intent intent) {

 

                   //[1]获取到当前广播的时间类型

                   Stringaction = intent.getAction();

                  

                   if("android.intent.action.MEDIA_MOUNTED".equals(action)) {

                            System.out.println("说明SD卡挂载上来了...");

                           

                   }elseif ("android.intent.action.MEDIA_UNMOUNTED".equals(action)) {

                            System.out.println("说明SD卡卸载了....");

                   }

                  

         }

 

}

         [2]    在清单文件中配置一下

         <receiver

           android:name="com.itheima.sdcardstate.SdcardStateReceiver"

           >

           <intent-filter >

                <actionandroid:name="android.intent.action.MEDIA_MOUNTED"/>

                  <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>

                  <!-- 小细节这里需要配置一个data 约束类型叫file 因为 sd里面存的数据类型是file文件-->

                  <!-- action里面的事件很多,到底哪些事件要配置data呢,总共只有两个 -->

                  <dataandroid:scheme="file"/>

           </intent-filter>

       </receiver>

4 案例:卸载安装

[1]    定义广播接受者

         publicclass AppStateReceiver extends BroadcastReceiver {

         //当有新的应用被安装  或者有应用被卸载了这个方法调用

         @Override

         publicvoid onReceive(Context context, Intent intent) {

                   //获取当前广播的时间类型

                   Stringaction = intent.getAction();

                   if("android.intent.action.PACKAGE_INSTALL".equals(action)) {

                            System.out.println("应用安装了11111");

                   }elseif ("android.intent.action.PACKAGE_ADDED".equals(action)) {

                            System.out.println("应用安装了22222");

                   }elseif ("android.intent.action.PACKAGE_REMOVED".equals(action)) {

                            System.out.println("应用卸载了!!"+intent.getData());

                   }

         }

}

         [2]    配置清单文件

         <receiver

           android:name="com.itheima.appstate.AppStateReceiver">

           <intent-filter >

                <actionandroid:name="android.intent.action.PACKAGE_INSTALL"/>(一般不用install,用的是add

                <actionandroid:name="android.intent.action.PACKAGE_REMOVED"/>

                <actionandroid:name="android.intent.action.PACKAGE_ADDED"/>

                <!--想让action生效 还需要配置一个data  -->

                <data android:scheme="package"/>

           </intent-filter>

       </receiver>


5 案例:开机启动

09-05 03:08:50.684: E/AndroidRuntime(1735):java.lang.RuntimeException: Unable to start receivercom.itheima.bootreceiver.BootReceiver: android.util.AndroidRuntimeException:Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASKflag. Is this really what you want?

         注意:不能直接在广播接收者中activity

         [1]    定义广播接收者

         publicclass BootReceiver extends BroadcastReceiver {

         //当手机重新启动的时候调用

         //记得加上权限 RECEIVE_BOOT_COMPLETED

         @Override

         publicvoid onReceive(Context context, Intent intent) {

                   //在这个方法中开启activity

                   Intentintent2 = new Intent(context, MainActivity.class);

                   //☆☆☆☆☆注意 不能在广播接收者里面直接开启activity 

                   //需要添加一个标记添加一个任务栈的标记

                   intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                   //开启activity

                   context.startActivity(intent2);

         }

}

         [2]    配置清单文件

         <receiver

           android:name="com.itheima.bootreceiver.BootReceiver">

           <intent-filter >

                <action android:name="android.intent.action.BOOT_COMPLETED"/>

           </intent-filter>

       </receiver>

         [3]    记得加上权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

6 有序广播和无序广播

自定义广播分为:

(1)       有序广播:类似中央发送红头文件  按照优先级进行接收

特点:[1]有序广播可以被终止

             [2]有序广播的数据可以被修改

             [3]sendOrderBroadcast()

(2)       无序广播:比如新闻联播每天晚上7点准时开播

特点:[1]无序广播不可以被终止

          [2]数据不可以被修改

          [3]sendBroadcast(Intent intent);

7 特殊广播接收者

操作特别频繁的广播事件  比如:屏幕的锁屏和解锁  电池电量的变化              这种事件在清单文件中注册(配置)是无效的,必须动态的注册

           protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_main);

       //动态的注册特殊广播接受者

       screenReceiver = new ScreenReceiver();

       /*<receiverandroid:name="com.itheima.screen.ScreenReceiver">

           <intent-filter >

                <actionandroid:name="android.intent.action.SCREEN_ON"/>

                <actionandroid:name="android.intent.action.SCREEN_OFF"/>

           </intent-filter>

       </receiver>*/

       //创建IntentFilter对象

       IntentFilter filter = new IntentFilter();

       //添加要注册的action

       filter.addAction("android.intent.action.SCREEN_ON");

       filter.addAction("android.intent.action.SCREEN_OFF");

       //动态注册广播接受者

       registerReceiver(screenReceiver, filter);

    }

         注册广播接收者的2种方式:

1、  动态注册通过代码方式注册

2、  在清单文件通过receiver tag节点静态发布

 

09-0507:46:08.745: E/ActivityThread(2344): Activity com.itheima.screen.MainActivityhas leaked IntentReceiver com.itheima.screen.ScreenReceiver@b2c14508 that wasoriginally registered here. Are you missing a call tounregisterReceiver()?

protected void onDestroy() {
        //当activity 销毁的时候要取消注册广播接受者
        unregisterReceiver(screenReceiver);
        super.onDestroy();
    }



原创粉丝点击