Android学习笔记-广播机制BoradcastReceiver
2016-05-08 13:24
351 查看
广播分为有序广播和标准广播,
分为动态注册和静态注册
下面是一个动态注册监听网络变化的例子
静态注册实现开机自启:
我们在action里面指定系统广播,添加开机启动还需要如下权限:
以上广播都是调用的系统广播:
现在我们来自定义广播:
标准广播:
点击按钮发送一条广播所有指定这条广播的接收器都可以接收到这条广播
接收器
我们在权限文件中指定这个接收器接收广播:
有序广播:
有序广播就改一行代码即可sendOrderedBroadcast();
第一个参数是是需要传入的intent广播 第二个参数是权限一般为null
下面用两个接收器来接收这条有序广播
android:priority 这个是设置这有序广播的优先级 这里我们设置到com.example.android_study.CustomTestBroadOrder这个接收器当中。广播会先发送给这个接收器
abortBroadcast()这个方法是截断这个有序广播 ,有序广播发送到这里就不会在发送了.
本地广播:
本地广播简单指只能在应用程序内访问该广播。之前我们发送的标准广播有序广播,外部应用也可以访问的到。为了一个安全性,我们可以使用本地广播。
本地广播其实就是调用了一个LocalBroadcastManager类,用这个类来开启本地广播,需要注意的是发送本地广播是不能够静态注册的。
本地广播有几点优势:
1.可以明确知道发送的广播不会离开我们的程序,所以不用担心数据泄漏的问题。
2.其他程序也不可能把广播发送到我们内部,所以也不必担心安全隐患。
3.发送本地广播,比发送系统全局广播更加高效。
简单例子:发送广播实现强制下线功能:
首先我们先新建一个登录activity:
布局:
登录activity代码:
逻辑很简单,用户名admin 密码123456 就登录成功 否则失败
接下来我们新建一个Activity管理类,因为在实际应用中首先并不清楚是在哪个activity弹出来的强制下线,我们在做强制下线之前就必须要清除所有activity。在跳转到登录页.
下面我们在进行编写一个Baseactivity来控制activity下面的activity都继承该类:
接下来写主activity:
代码很简单,布局在这里就不贴了。就以上所学的点击按钮发送一个标准广播。
接下来我们指定一个广播接收器来接收这个广播,在到这个广播接收器的onReceive方法当中处理逻辑
完成之后我们需要在权限文件当中进行相关配置:
下面我们跑一下程序:
分为动态注册和静态注册
下面是一个动态注册监听网络变化的例子
/** * 广播的使用 */ public class BrodcastReceiverActivity extends Activity { private IntentFilter filter; private NetWrokReceiver networkreceiver; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_brodcastreceiver); // 动态注册广播 filter = new IntentFilter(); filter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkreceiver = new NetWrokReceiver(); registerReceiver(networkreceiver, filter); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); unregisterReceiver(networkreceiver);//动态注册一定要取消注册 } class NetWrokReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //获取系统网络状态判断是否有没有网络 //这是一个系统服务类专门用来管理网络连接的 ConnectivityManager manager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info=manager.getActiveNetworkInfo(); if(info!=null&&info.isAvailable()){ Toast.makeText(context, "当前有网络", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context, "当前没有网络", Toast.LENGTH_SHORT).show(); } } } }
静态注册实现开机自启:
public class TestBroadCast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "开机自启实现成功", Toast.LENGTH_SHORT).show(); } }
<receiver android:name="com.example.android_study.TestBroadCast" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
我们在action里面指定系统广播,添加开机启动还需要如下权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
以上广播都是调用的系统广播:
现在我们来自定义广播:
标准广播:
点击按钮发送一条广播所有指定这条广播的接收器都可以接收到这条广播
package com.example.android_study; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.TextView; public class MainActivity extends Activity { private TextView sendout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initview(); } private void initview() { sendout=(TextView) findViewById(R.id.sendout); sendout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent("com.example.android_study.TESTBROD"); intent.putExtra("name","test"); sendBroadcast(intent);//发送标准广播 } }); } }
接收器
public class CustomTestBroadCast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String name=intent.getStringExtra("name"); Toast.makeText(context, "接收到了这条广播"+"名字是"+name, Toast.LENGTH_SHORT).show(); } }
我们在权限文件中指定这个接收器接收广播:
<receiver android:name="com.example.android_study.CustomTestBroadCast"> <intent-filter > <action android:name="com.example.android_study.TESTBROD"/> </intent-filter> </receiver>
有序广播:
有序广播就改一行代码即可sendOrderedBroadcast();
第一个参数是是需要传入的intent广播 第二个参数是权限一般为null
public class MainActivity extends Activity { private TextView sendout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initview(); } private void initview() { sendout=(TextView) findViewById(R.id.sendout); sendout.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent("com.example.android_study.TESTBROD"); intent.putExtra("name","test"); sendOrderedBroadcast(intent,null);//发送有序广播 } }); } }
下面用两个接收器来接收这条有序广播
<receiver android:name="com.example.android_study.CustomTestBroadCast"> <intent-filter > <action android:name="com.example.android_study.TESTBROD"/> </intent-filter> </receiver>
<receiver android:name="com.example.android_study.CustomTestBroadOrder"
>
<intent-filter android:priority="100">
<action android:name="com.example.android_study.TESTBROD"/>
</intent-filter>
</receiver>
android:priority 这个是设置这有序广播的优先级 这里我们设置到com.example.android_study.CustomTestBroadOrder这个接收器当中。广播会先发送给这个接收器
public class CustomTestBroadCast extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { String name=intent.getStringExtra("name"); Toast.makeText(context, "接收到了这条广播"+"名字是"+name, Toast.LENGTH_SHORT).show(); } }
public class CustomTestBroadOrder extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "这是有序广播接收的", Toast.LENGTH_SHORT).show(); abortBroadcast();//截断这个有序广播 } }
abortBroadcast()这个方法是截断这个有序广播 ,有序广播发送到这里就不会在发送了.
本地广播:
本地广播简单指只能在应用程序内访问该广播。之前我们发送的标准广播有序广播,外部应用也可以访问的到。为了一个安全性,我们可以使用本地广播。
public class LocathostBroad extends Activity { IntentFilter filer; locatBroad locat; LocalBroadcastManager manager; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView sendoutlocat=(TextView) findViewById(R.id.locat); manager=LocalBroadcastManager.getInstance(LocathostBroad.this); sendoutlocat.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent("com.example.android_study.LOCATBROD"); manager.sendBroadcast(intent);//发送本地广播 } }); filer=new IntentFilter(); filer.addAction("com.example.android_study.LOCATBROD"); locat=new locatBroad(); manager.registerReceiver(locat, filer); } @Override protected void onDestroy() { super.onDestroy(); manager.unregisterReceiver(locat); } class locatBroad extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(LocathostBroad.this, "发送了本地广播", Toast.LENGTH_SHORT).show(); } } }
本地广播其实就是调用了一个LocalBroadcastManager类,用这个类来开启本地广播,需要注意的是发送本地广播是不能够静态注册的。
本地广播有几点优势:
1.可以明确知道发送的广播不会离开我们的程序,所以不用担心数据泄漏的问题。
2.其他程序也不可能把广播发送到我们内部,所以也不必担心安全隐患。
3.发送本地广播,比发送系统全局广播更加高效。
简单例子:发送广播实现强制下线功能:
首先我们先新建一个登录activity:
布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="用户名" /> <EditText android:id="@+id/pass" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="密码" android:password="true" /> <Button android:id="@+id/login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="登录" android:textColor="#000" android:textSize="18sp" /> </LinearLayout>
登录activity代码:
public class login_activity extends BaseActivity{ private EditText name; private EditText pass; private Button login; String names; String passw; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.login_activity); name=(EditText) findViewById(R.id.name); pass=(EditText) findViewById(R.id.pass); login=(Button) findViewById(R.id.login); login.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { names=name.getText().toString(); passw=pass.getText().toString(); if(names.equals("admin") && passw.equals("123456")){ Toast.makeText(login_activity.this, "登陆成功", Toast.LENGTH_SHORT).show(); startActivity(new Intent(login_activity.this,TestForcedActivity.class)); login_activity.this.finish(); }else{ Toast.makeText(login_activity.this, "登录失败", Toast.LENGTH_SHORT).show(); } } }); } }
逻辑很简单,用户名admin 密码123456 就登录成功 否则失败
接下来我们新建一个Activity管理类,因为在实际应用中首先并不清楚是在哪个activity弹出来的强制下线,我们在做强制下线之前就必须要清除所有activity。在跳转到登录页.
public class ActivityContorl { private static ActivityContorl contorl; public static ActivityContorl getInstance(Context context) { if (contorl == null) { contorl = new ActivityContorl(context); } return contorl; } public ActivityContorl(Context context) { } public static List<Activity> list = new ArrayList<Activity>(); public static void addActivity(Activity activity) { list.add(activity); } public static void removeActivity(Activity activity) { list.remove(activity); } public static void finshall() { for (Activity activity : list) {// 遍历 if (!activity.isFinishing()) { activity.finish(); } } } }
下面我们在进行编写一个Baseactivity来控制activity下面的activity都继承该类:
public class BaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); ActivityContorl.getInstance(this).addActivity(this); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); ActivityContorl.getInstance(this).removeActivity(this); } }
接下来写主activity:
public class TestForcedActivity extends BaseActivity { private Button qiangzhi; @SuppressWarnings("static-access") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.testfor_activity); qiangzhi=(Button) findViewById(R.id.qiangzhi); ActivityContorl.getInstance(TestForcedActivity.this).addActivity(TestForcedActivity.this); qiangzhi.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent("com.example.android_study.Forcedoffline"); sendBroadcast(intent);//发送标准广播 } }); } }
代码很简单,布局在这里就不贴了。就以上所学的点击按钮发送一个标准广播。
接下来我们指定一个广播接收器来接收这个广播,在到这个广播接收器的onReceive方法当中处理逻辑
public class TestForctedBroad extends BroadcastReceiver{ @Override public void onReceive(final Context context, Intent intent) { AlertDialog.Builder alertDialog=new AlertDialog.Builder(context); alertDialog.setTitle("您的帐号在其他地方登录"); alertDialog.setMessage("请您重新登录"); alertDialog.setCancelable(false);//不可取消 alertDialog.setPositiveButton("确定", new OnClickListener() { @SuppressWarnings("static-access") @Override public void onClick(DialogInterface dialog, int which) { ActivityContorl.getInstance(context).finshall();//销毁所有活动 Intent intent=new Intent(context,login_activity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //活动是在广播里面运行的要加上这个 context.startActivity(intent); } }); AlertDialog alertDialogs=alertDialog.create();//设置dialog的类型 alertDialogs.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); //不设置这个它将在广播接收器里面无法弹出 alertDialogs.show(); }
完成之后我们需要在权限文件当中进行相关配置:
<activity android:name="com.example.android_study.login_activity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.android_study.TestForcedActivity" > </activity> <receiver android:name="com.example.android_study.TestForctedBroad" > <intent-filter> <action android:name="com.example.android_study.Forcedoffline" /> </intent-filter> </receiver>
下面我们跑一下程序:
相关文章推荐
- Android SDK Android NDK Android Studio 官方下载地址
- Android实现ViewPager+Fragment
- android 音乐播放器关于歌词的处理
- Android 监听ScrollView滑动距离简单处理
- Android studio 错误提示,英文转中文
- android Gradle 教程
- Android Scroller分析
- 解决Gradle DSL method not found: ‘android()’
- Lucene highlighter高亮显示
- android studio 学习笔记之 生成签名APK
- android contentprovider
- Android开发艺术探索首观
- Android Studio导入ZXING
- Android ViewPager之实现轮播广告效果
- android packagemanager
- android 系统给应用的jar
- Android工作总结
- android studio 学习笔记之 注释规范化
- Android利用Fragment实现新闻客户端界面切换(addBackStack,popBackStack)
- Android Studio解决导入开源项目出现的相关问题