关闭

broadcast receiver广播接收器

266人阅读 评论(0) 收藏 举报
分类:

注册广播有2种方式
1.代码注册(动态注册)
2.在AndroidManifest.xml注册(静态注册)

动态注册

MainActivity.java

public class MainActivity extends Activity {
 NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        IntentFilter intentFilter =new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//网络状态发生变化的广播
        networkChangeReceiver = new NetworkChangeReceiver(); 
        registerReceiver(networkChangeReceiver, intentFilter);//注册
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);//解除注册
    }
    public class NetworkChangeReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent arg1) {
            ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo =connectivityManager.getActiveNetworkInfo();
            if(networkInfo!=null&&networkInfo.isAvailable()){
                Toast.makeText(context, "network is available", Toast.LENGTH_LONG).show();
            }
            else{
                Toast.makeText(context, "network is unavailable", Toast.LENGTH_LONG).show();
            }
        }
}

查询网络连接的状态必须要在AndroidManifest.xml中注册

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

当网络连接状态发生改变的时候
这里写图片描述
这里写图片描述

静态注册
新建一个BootCompleteReceiver.java

package com.example.broadcastReceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class BootCompleteReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent arg1) {
        Toast.makeText(context,"BootComplete", Toast.LENGTH_LONG).show();
    }

}

AndroidManifest.xml

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED">
<!--接收开机启动广播的权限-->
</uses-permission>
 <application>
   <receiver         android:name="com.example.broadcastReceiver.BootCompleteReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <!--开机启动的广播-->
            </intent-filter>
        </receiver>
 </application>

效果:

‘’

自定义发送广播

使用静态的方式先注册广播

<receiver 
            android:name="com.example.broadcastReceiver.MyBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.MyBroadcastReceiver"/>
            </intent-filter>
        </receiver>

MyBroadcastReceiver.java(广播接收器类)

package com.example.broadcastReceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyBroadcastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent arg1) {
        Toast.makeText(context,"mybroadcastReceiver", Toast.LENGTH_SHORT).show();
    }

}

在MainActivity发送广播

Button btn_sent =(Button) this.findViewById(R.id.sendBroadcast);
        btn_sent.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent  = new Intent("android.intent.action.MyBroadcastReceiver");
                sendBroadcast(intent);
            }
        });

效果

这里写图片描述

广播可以用于应用程序之间的通信。
在另一个app内也静态的注册一个广播接收器,接收的广播为第一个app发送的广播。

有序广播
在原来

Intent intent  = new Intent("android.intent.action.MyBroadcastReceiver");
sendBroadcast(intent);

改为

sendOrderedBroadcast(intent, null);

当广播为有序广播时,要为广播接收器设定优先级
android:priority=”100”

 <receiver 
            android:name="com.example.broadcastReceiver.MyBroadcastReceiver">
            <intent-filter android:priority="100">
                <action android:name="android.intent.action.MyBroadcastReceiver"/>
            </intent-filter>
        </receiver>

有序广播可以被切断
当广播被此广播接收器接收后,广播被切断

public class MyBroadcastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent arg1) {
        Toast.makeText(context,"mybroadcastReceiver", Toast.LENGTH_SHORT).show();
        abortBroadcast();//切断广播
    }

}

上方的广播属于全局广播,存在安全性问题,广播有可能被别的程序截获,别的程序也可以不断的向我们的程序发送垃圾广播,因此引入本地广播

本地广播

本地广播使用的是动态注册,因为既然是在app内传播,app当然已经启动了,所以不使用静态注册是可以理解的(不能静态注册)

MainActivity.java

 LocalReceiver localReceiver;
 LocalBroadcastManager localBroadcastManager;
{
localBroadcastManager =      LocalBroadcastManager.getInstance(this);//实例一个本地广播管理者 

IntentFilter inteFilter = new IntentFilter();       inteFilter.addAction("android.intent.action.LoaclBroadcast");

localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,inteFilter);//注册本地广播监听器

        Button btn_sent =(Button) this.findViewById(R.id.sendBroadcast);
        btn_sent.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent  = new Intent("android.intent.action.LoaclBroadcast");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
}

@Override
    protected void onDestroy() {
        super.onDestroy();
    localBroadcastManager.unregisterReceiver(localReceiver);//解除注册
    }

public class LocalReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent arg1) {
            Toast.makeText(context, "localBroadcast", Toast.LENGTH_SHORT).show();
        }

    }

效果
这里写图片描述

在广播接受器弹出窗口

package com.example.broadcastReceiver;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.view.WindowManager;
import android.widget.Toast;

public class MyBroadcastReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent arg1) {

        AlertDialog.Builder ab =new AlertDialog.Builder(context);
        ab.setTitle("hello world!");
        ab.setCancelable(false);//不可以取消
        ab.setMessage("ni hao!");
        ab.setPositiveButton("ok",null);

        AlertDialog alertDialog = ab.create();
        alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//系统级别的弹出窗口
        //是TYPE_SYSTEM_ALERT而不是TYPE_SYSTEM_DIALOG
        alertDialog.show();
    }
}

声明权限

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

效果
这里写图片描述


2015/12/27 更新

(讨论的是动态注册)
在活动创建的时候注册广播,在活动销毁的时候销毁广播。
即一个活动没有被创建就不会收到广播,之前发的广播不会在活动启动后接收到。
必须在活动存活的时候发送广播,活动才能接收到。

如果有多个活动同时接受一个广播,并且这些活动都是存活的,那么它们都可以接收到广播。接收的顺序按栈向上的顺序,即在底层的活动会先接收到。


项目中的使用广播的格式
定义一个Broadcast类,专门为APP注册和销毁广播

package com.example.broadcast;


import com.example.testbroadcast1227.MyApp;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

public class MyBroadcast {

    public static String BROADCAST = "broadCast";
    public static String BROADCAST2 = "broadCast2";


    /**
     * 注册广播接收者
     */
    public static void registerBroadcastReceiver(String action,BroadcastReceiver receiver) {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(action);
        MyApp.getContext().registerReceiver(receiver, intentFilter);
        //这里的MyApp.getContext()返回的是 继承Application类的context
    }

    public static void registerBroadcastReceiver(String [] actions,BroadcastReceiver receiver) {
        IntentFilter intentFilter = new IntentFilter();
        for (String action : actions) {
            intentFilter.addAction(action);
        }
        MyApp.getContext().registerReceiver(receiver, intentFilter);
    }


    /**
     * 销毁广播接收者
     */
    public static void unregisterBroadcastReceiver(BroadcastReceiver receiver) {
        MyApp.getContext().unregisterReceiver(receiver);
    }




    /**
     * 发广播
     */
    public static void sendBroadcastAction(String action){
        sendBroadcastAction(action, null);
    }

    public static void sendBroadcastAction(String action,Bundle bundle){
        Intent intent = new Intent(action);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        MyApp.getContext().sendBroadcast(intent);
    }

}

在具体的活动中用法:
MainActivity.java

package com.example.testbroadcast1227;

import com.example.broadcast.MyBroadcast;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{

    private BroadcastReceiver receiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        registerBroadcast();

        Button bt = (Button) findViewById(R.id.bt_sendBroadcast);
        bt.setOnClickListener(this);
        Button bt2 = (Button) findViewById(R.id.bt_intoAct2);
        bt2.setOnClickListener(this);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterBroadcast();
    }

    private void registerBroadcast() {
        if (receiver == null) {
            receiver = new BroadcastReceiver(){

                @Override
                public void onReceive(Context context, Intent intent) {
                    if (intent.getAction().equals(MyBroadcast.BROADCAST)) {
                        Log.v("TAG", "1:broadcast");
                    }
                    else if (intent.getAction().equals(MyBroadcast.BROADCAST2)) {
                        Log.v("TAG", "1:broadcast2");
                    }
                }};
        }

        MyBroadcast.registerBroadcastReceiver(new String[] {
                MyBroadcast.BROADCAST,
                MyBroadcast.BROADCAST2 }, receiver);
    }

    private void unregisterBroadcast() {
        MyBroadcast.unregisterBroadcastReceiver(receiver);
    }

    @Override
    public void onClick(View v) {

    switch (v.getId()) {
    case R.id.bt_sendBroadcast:
        MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST);
        break;

    case R.id.bt_intoAct2:
        //跳转
        Act2.show(this);
        break;
    }

    }



}

Act2.java

package com.example.testbroadcast1227;

import com.example.broadcast.MyBroadcast;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Act2 extends Activity implements OnClickListener{

    BroadcastReceiver receiver;

    public static void show(Context context) {
        Intent intent = new Intent(context,Act2.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act2);
        registerBroadcast();
        Button bt2 = (Button) findViewById(R.id.bt_sendBroadcast2);
        bt2.setOnClickListener(this);
        Button bt1 = (Button) findViewById(R.id.bt_sendBroadcast1);
        bt1.setOnClickListener(this);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterBroadcast();
    }


    private void registerBroadcast() {
        if (receiver == null) {
            receiver = new BroadcastReceiver(){

                @Override
                public void onReceive(Context context, Intent intent) {
                    if (intent.getAction().equals(MyBroadcast.BROADCAST)) {
                        Log.v("TAG", "2:broadcast");
                    }
                    else if (intent.getAction().equals(MyBroadcast.BROADCAST2)) {
                        Log.v("TAG", "2:broadcast2");
                    }
                }};
        }

        MyBroadcast.registerBroadcastReceiver(new String[] {
                MyBroadcast.BROADCAST,
                MyBroadcast.BROADCAST2 }, receiver);
        }

    private void unregisterBroadcast() {
        MyBroadcast.unregisterBroadcastReceiver(receiver);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bt_sendBroadcast2:
            MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST2);
            break;

        case R.id.bt_sendBroadcast1:
            MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST);
            break;
        }
    }

}

在MainActvity点击按钮发送广播:
这里写图片描述
只有MainActivity能接到广播

在Act2的2个按钮分别发送广播:
这里写图片描述
可以看到2个活动都收到广播,并且是MainActivity先收到,Act2后收到

2016/01/27更新

1.开机广播

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

在4.42 (T1),4.4.4(小米平板1) 测试均无法接收

2.app如果被杀死(Back键退出不算),将无法接收到广播


2016/3/25 更新

广播接收器注册一共有两种形式 : 静态注册和动态注册.

两者及其接收广播的区别:

1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低>\

2.动态注册广播不是 常驻型广播 ,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。

静态注册是常驻型 ,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

3.在同一个优先级下,谁先启动的快,谁将先接收到广播.

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:33774次
    • 积分:789
    • 等级:
    • 排名:千里之外
    • 原创:26篇
    • 转载:82篇
    • 译文:0篇
    • 评论:0条