Android全局监听系统广播

从事安卓有两年多了,对广播的认识却非常少,平时用到广播最多的莫过于监听系统的网络变化,我在本文中主要是讲解自己对于广播应用的一种思想,如果对于广播还不是很熟悉的童鞋们可以参考以下这个链http://www.cnblogs.com/trinea/archive/2012/11/09/2763182.html
下面就以网络监听为例子进行讲解。

1、自定义广播

这里在onReceive里面进行回调处理,通过NetworkCallback回调给注册监听的页面。
ANDROID_NET_CHANGE_ACTION:广播IntentFilter的action
ObjectsHolder:内部用ArrayList实现的多对象持有管理类(详情见下)

public class NetworkReceiver extends BroadcastReceiver
{

    private final static String ANDROID_NET_CHANGE_ACTION = "com.king.CONNECTIVITY_CHANGE";
    private static BroadcastReceiver sReceiver;
    private static IObjectsHolder<NetworkCallback> sObjectsHolder = new ObjectsHolder<>();

    @Override
    public void onReceive(Context context, Intent intent)
    {
        sReceiver = this;
        String action = intent.getAction();
        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action) || ANDROID_NET_CHANGE_ACTION.equals(action))
        {
            final NetworkType type = getNetworkType(context);

            sObjectsHolder.foreach(new IterateCallback<NetworkCallback>()
            {
                @Override
                public boolean next(int i, NetworkCallback item, Iterator<NetworkCallback> it)
                {
                    item.onNetworkChanged(type);
                    return false;
                }
            });

        }

    }


    public static BroadcastReceiver getReceiver()
    {
        if (sReceiver == null)
        {
            sReceiver = new NetworkReceiver();
        }
        return sReceiver;
    }


    /**
     * 发送网络检测广播
     *
     * @param context
     */
    public static void sendBroadcast(Context context)
    {
        Intent intent = new Intent();
        intent.setAction(ANDROID_NET_CHANGE_ACTION);
        context.sendBroadcast(intent);
    }

    /**
     * 注册广播
     *
     * @param context
     */
    public static void registerReceiver(Context context)
    {
        IntentFilter filter = new IntentFilter();
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(ANDROID_NET_CHANGE_ACTION);
        context.getApplicationContext().registerReceiver(getReceiver(), filter);
    }


    /**
     * 取消注册广播
     *
     * @param context
     */
    public static void unregisterReceiver(Context context)
    {
        if (sReceiver != null)
        {
            try
            {
                context.getApplicationContext().unregisterReceiver(sReceiver);
            } catch (Exception e)
            {
            }
        }
    }


    /**
     * 添加回调
     *
     * @param callback
     */
    public static void addCallback(NetworkCallback callback)
    {
        sObjectsHolder.add(callback);
    }

    /**
     * 移除回调
     *
     * @param callback
     */
    public static void removeCallback(NetworkCallback callback)
    {
        sObjectsHolder.remove(callback);
    }

    /**
     * 获得ConnectivityManager对象
     *
     * @param context
     * @return
     */
    public static ConnectivityManager getConnectivityManager(Context context)
    {
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return manager;
    }

    /**
     * 网络是否可用
     *
     * @param context
     * @return
     */
    public static boolean isNetworkConnected(Context context)
    {
        ConnectivityManager manager = getConnectivityManager(context);
        NetworkInfo info = manager.getActiveNetworkInfo();
        if (info != null)
        {
            return info.isConnected();
        } else
        {
            return false;
        }
    }

    /**
     * wifi是否可用
     *
     * @param context
     * @return
     */
    public static boolean isWifiConnected(Context context)
    {
        ConnectivityManager manager = getConnectivityManager(context);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        if (networkInfo == null)
        {
            return false;
        } else
        {
            return ConnectivityManager.TYPE_WIFI == networkInfo.getType();
        }
    }


    /**
     * 获得网络类型
     *
     * @param context
     * @return
     */
    public static NetworkType getNetworkType(Context context)
    {
        ConnectivityManager manager = getConnectivityManager(context);
        NetworkInfo networkInfo = manager.getActiveNetworkInfo();
        if (networkInfo == null)
        {
            return NetworkType.None;
        } else
        {
            int type = networkInfo.getType();
            if (type == ConnectivityManager.TYPE_MOBILE)
            {
                return NetworkType.Mobile;
            } else if (type == ConnectivityManager.TYPE_WIFI)
            {
                return NetworkType.Wifi;
            } else
            {
                return NetworkType.None;
            }
        }
    }


    public enum NetworkType
    {
        /**
         * wifi网络
         */
        Wifi,
        /**
         * 移动数据网络
         */
        Mobile,
        /**
         * 无网络
         */
        None
    }

    public interface NetworkCallback
    {
        /**
         * 网络变化监听
         *
         * @param type
         */
        void onNetworkChanged(NetworkType type);
    }

}
2、创建接口和ObjectsHolder类

一个内部用ArrayList实现的多对象持有管理类

public interface IObjectsHolder<T>
{

    /**
     * @Description 添加对象
     * @param object
     */
    void add(T object);

    /**
     * @Description 移除对象
     * @param object
     */
    boolean remove(T object);

    /**
     *
     * @Description 是否已经包含了该对象
     * @param object
     */
    boolean contains(T object);

    /**
     * @Description 对象个数
     */
    int size();

    /**
     * @Description 清空对象
     */
    void clear();

    /**
     * @Description 遍历对象
     */

    boolean foreach(IterateCallback<T> callback);


    /**
     * @Description 倒序遍历对象
     */
    boolean foreachReverse(IterateCallback<T> callback);

}
public class ObjectsHolder<T> implements IObjectsHolder<T>
{
    private List<T> mListObject = new ArrayList<>();

    @Override
    public void add(T object)
    {
        if (object == null)
        {
            return;
        }
        if (!mListObject.contains(object))
        {
            mListObject.add(object);
        }
    }

    @Override
    public boolean remove(T object)
    {
        if (object == null)
        {
            return false;
        }
        return mListObject.remove(object);
    }

    @Override
    public boolean contains(T object)
    {
        if (object == null)
        {
            return false;
        }
        return mListObject.contains(object);
    }

    @Override
    public int size()
    {
        return mListObject.size();
    }

    @Override
    public void clear()
    {
        mListObject.clear();
    }

    @Override
    public boolean foreach(IterateCallback<T> callback)
    {
        return CollectionUtil.foreach(mListObject,callback);
    }

    @Override
    public boolean foreachReverse(IterateCallback<T> callback)
    {
        return CollectionUtil.foreachReverse(mListObject,callback);
    }
}
3、在程序入口处进行注册
public class App extends Application
{
    private static App sInstance;

    public static App getApplication()
    {
        return sInstance;
    }

    @Override
    public void onCreate()
    {
        super.onCreate();
        sInstance = this;
        init();
    }

    private void init()
    {
        NetworkReceiver.registerReceiver(this);
    }


    @Override
    public void onTerminate()
    {
        NetworkReceiver.unregisterReceiver(this);
        super.onTerminate();
    }
}
4、在BaseActivity实现接口并提供方法给子类调用
public class BaseActivity extends AppCompatActivity implements NetworkReceiver.NetworkCallback
{

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        init();
    }

    private void init()
    {
        NetworkReceiver.addCallback(this);
    }

    @Override
    protected void onDestroy()
    {
        NetworkReceiver.removeCallback(this);
        super.onDestroy();
    }

    @Override
    public void onNetworkChanged(NetworkReceiver.NetworkType type)
    {

    }

public class MainActivity extends BaseActivity
{

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

    @Override
    public void onNetworkChanged(NetworkReceiver.NetworkType type)
    {
        //此处因为为测试机没有SIM卡,如在开发中可以改成mobil
        if (type == NetworkReceiver.NetworkType.Wifi)
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("当前处于数据网络下,会耗费较多流量,是否继续?");
            builder.setCancelable(false);
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {

                }
            });
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {

                }
            });
            builder.show();
        }
        super.onNetworkChanged(type);
    }
}

具体的demo请查看https://github.com/BingoKingCoding/NetworkMonitor
谢谢支持。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,428评论 25 707
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,066评论 0 62
  • 第一章:使命感和价值观 一个公司确立的使命感和价值观不应当是放之四海而皆准的说辞,而用当时公司根据自身独特的实际情...
    刘敦敦阅读 144评论 0 0
  • ​撰稿 & 采访 | Natalie AI前线出品| ID:ai-front 编者按: 如今人工智能已经成为普罗大...
    AI前线阅读 531评论 0 2
  • 爸,快看,你儿子来了。一进病房,姐劈头就这么一句。 映入我眼帘的是一身病号服、头上绑了纱布、一只胳膊吊着、一条腿包...
    王二福阅读 237评论 0 1