Android--广播的使用实例(监听网络连接)

Android四大组件,除了activity外,用的最多的估计就是BroadcaseReceiver.
广播分为两种广播类型:

  • 标准广播(无序)
  • 有序广播
    无序广播就是指所有的广播接收者都可以接收到所需要的信息,有序广播则不然,有序广播可根据优先级进行接收,中间可能会被拦截。
    大家都知道,广播为Android四大组件之一,想要使用他必须要注册。
    广播注册形式分为两种:
  • 静态注册(清单文件中注册)
  • 动态注册(代码中注册)
    下面就通过一个实例在展示每种广播形式。
    监听手机网络变化
/**
*动态注册广播监听网络变化
*1.注册广播
*2.创建netWorkChangeReceiver类继承BroadCastReceiver,实现onReceiver()方法
*
*/
public class MainActivity extends Activity {
    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetworkChangeReceiver();
        //动态注册
        registerReceiver(networkChangeReceiver, intentFilter);
}
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解除广播
        unregisterReceiver(networkChangeReceiver);
    }

class NetworkChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "network changes",
        Toast.LENGTH_SHORT).show();
        //得到网络连接管理器
        ConnectivityManager connectionManager = (ConnectivityManager)
        getSystemService(Context.CONNECTIVITY_SERVICE);
        //通过管理器得到网络实例
        NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();
        //判断是否连接
        if (networkInfo != null && networkInfo.isAvailable()) {
            Toast.makeText(context, "network is available",
            Toast.LENGTH_SHORT).show();
        } else {
                Toast.makeText(context, "network is unavailable",
                Toast.LENGTH_SHORT).show();
        }
    }
}
}

代码中注释比较清楚了。就不进行说明了。
记得别忘记了添加权限

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

有的人可能会说了,如果这个类不存在了,就接收不到广播了,如果需要打开应用就接收到广播的话,就需要静态注册了。
实现开机启动功能

<receiver android:name=".BootCompleteReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

在清单文件的Application标签下进行注册。action是必不可少的。
创建BootCompleteReceiver类

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

需要注意的是,不要在onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收
器中是不允许开启线程的,当onReceive()方法运行了较长时间而没有结束时,程序就会报错。
刚才一直说的接收广播,下面来看看发送自定义广播:
在发送广播之前,我们还是需要先定义一个广播接收器来准备接收此广播才行,不然发
出去也是白发。因此新建一个MyBroadcastReceiver 继承自BroadcastReceiver,代码如下所示:

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

在清单文件中注册

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

接下来就是发送广播了:

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //action和清单文件中的action对应
        Intent intent = new Intent("com.example.broadcasttest.
        MY_BROADCAST");
        //发送广播
        sendBroadcast(intent);
}
}

发送本地广播:
为了能够简单地解决广播的安全性问题,Android 引入了一套本地广播机制,使用这个
机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用
程序发出的广播,这样所有的安全性问题就都不存在了。
本地广播的用法并不复杂,主要就是使用了一个LocalBroadcastManager 来对广播进行
管理,并提供了发送广播和注册广播接收器的方法。下面我们就通过具体的实例来尝试一下
它的用法,修改MainActivity 中的代码,如下所示:

public class MainActivity extends Activity {
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        // 获取实例
        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.broadcasttest.
                LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent); // 发送本地广播
            }
        });
    intentFilter = new IntentFilter();
    intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
    localReceiver = new LocalReceiver();
    localBroadcastManager.registerReceiver(localReceiver, intentFilter);
    // 注册本地广播监听器
    }
    @Override
    protected void onDestroy() {
    super.onDestroy();
    localBroadcastManager.unregisterReceiver(localReceiver);
    }
    class LocalReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received local broadcast",
        Toast.LENGTH_SHORT).show();
    }
    }
}

最后我们再来盘点一下使用本地广播的几点优势吧。
1. 可以明确地知道正在发送的广播不会离开我们的程序,因此不需要担心机密数据泄
漏的问题。
2. 其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐
患。
3. 发送本地广播比起发送系统全局广播将会更加高效。
强制下线功能
强制下线功能需要先关闭掉所有的活动,然后回到登录界面。先创建一个ActivityCollector 类用于管理所有的活动,代码如下所示:

/**
*记录所有的activity
*/
public class ActivityCollector {
    //创建一个集合记录打开的activity
    public static List<Activity> activities = new ArrayList<Activity>();
    //每次调用这个方法添加activity
    public static void addActivity(Activity activity) {
        activities.add(activity);
    }
    //关闭指定activity
    public static void removeActivity(Activity activity) {
        activities.remove(activity);
    }
    //关闭所有activity
    public static void finishAll() {
        for (Activity activity : activities) {
            if (!activity.isFinishing()) {
                activity.finish();
            }
        }
    }
}

然后创建BaseActivity 类作为所有活动的父类,代码如下所示:

/**
*创建activity的基类
*/
public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //每次调用这个方法添加activity
        ActivityCollector.addActivity(this);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }
}

登录界面我就不列出来了。主要是看广播。创建LoginActivity类继承BaseActivity类
强制下线广播代码

//发送强制下线广播,场景自己订
Intent intent = new Intent("com.example.broadcastbestpractice.
FORCE_OFFLINE ");
sendBroadcast(intent);

,接下来我们就需要创建一个广播接收器了,新建ForceOfflineReceiver
继承自BroadcastReceiver,代码如下所示:

/**
*自定义广播类
*/
public class ForceOfflineReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) {
        //接收到广播后创建dialog
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
        dialogBuilder.setTitle("Warning");
        dialogBuilder.setMessage("You are forced to be offline. Please try
        to login again.");
        //不能手动取消dialog
        dialogBuilder.setCancelable(false);
        dialogBuilder.setPositiveButton("OK",
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ActivityCollector.finishAll(); // 销毁所有活动
                Intent intent = new Intent(context,
                LoginActivity.class);
                //在非activity中使用intent,需要开辟新任务桟
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent); // 重新启动LoginActivity
            }
        });
        AlertDialog alertDialog = dialogBuilder.create();
        // 需要设置AlertDialog的类型,保证在广播接收器中可以正常弹出
        alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTE
        M_ALERT);
        alertDialog.show();
    }
}

在清单文件中:

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

<receiver android:name=".ForceOfflineReceiver" >
<intent-filter>
<action android:name="com.example.broadcastbestpractice.
FORCE_OFFLINE" />
</intent-filter>
</receiver>

这里有几点内容需要注意,首先由于我们在ForceOfflineReceiver 里弹出了一个系统级别
的对话框,因此必须要声明android.permission.SYSTEM_ALERT_WINDOW 权限。然后对
LoginActivity 进行注册,并把它设置为主活动,因为肯定不能让用户启动程序就直接进入
MainActivity 吧。最后再对ForceOfflineReceiver 进行注册,并指定它接收com.example.
broadcastbestpractice.FORCE_OFFLINE 这条广播。

基本上就是这样。
申明:本文中代码采用郭神的第一行代码中内容。便于自己理解。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值