关闭

Android__Broadcast

标签: android
112人阅读 评论(0) 收藏 举报
分类:

Broadcast:
广播机制 分两种:

标准广播(Normal broadcasts)
是一种完全异步执行的广播,在广播发出后,所有广播接收器几乎在同一时刻接收到
因此没有先后顺序可言

有序广播(Ordered broadcast)
同步执行的广播,在广播发出后,在同一时刻只有一个广播接收器能收到这条广播
层层传递,也就是层层可以拦截并作其他处理

注册广播:
代码中注册成为动态注册
AndroidManifest.xml下注册成为静态注册

//动态注册:

public class MainActivity extends Activity {

    //广播的动态注册,即代码注册
    private IntentFilter  intentFilter;
    private NetworkChangeReciver networkChangeReciver;


    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        //广播对象
        intentFilter = new IntentFilter();

        //广播监听的对象
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");

        //广播接收
        networkChangeReciver = new NetworkChangeReciver();

        //广播注册
        registerReceiver(networkChangeReciver, intentFilter);


    }
//内部类----广播接收器
    class NetworkChangeReciver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
//          Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();


            //监听网络是否可用
            ConnectivityManager connectivityManager =(ConnectivityManager)
                    getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

            if(networkInfo!=null && networkInfo.isAvailable()){

                Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();

            }else{
                Toast.makeText(context, "network is Inavailable", Toast.LENGTH_SHORT).show();
            }


        }

    }
}
//动态注册的广播在最后一定要unregisterReceiver(networkChangeReciver);
    @Override
    protected void onDestroy(){
            super.onDestroy();
            unregisterReceiver(networkChangeReciver);
        }
//最后别忘记添加相应的权限
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

静态注册(AndroidManifest.xml)

案例:静态注册开机启动
同样,必须新建一个广播接收器的class

public class BootCompleteReciver extends BroadcastReceiver {


    //在AndroidManifest静态注册后,在这里重写onReceive就Ok,实现你的操作
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();

    }

}
//在AndroidManifest.xml文件中:


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <!-- 这里添加了一个接收器,并在接收器加上了一个Action,这里实现的功能就是开机启动 -->
      <receiver 
                android:name=".BootCompleteReciver">
                <intent-filter >
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
            </receiver>
    </application>



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

以上的两种接收器实现了接收系统的广播,广播都是由系统直接发出的。那么如何创建自定义的广播呢

自定义发送广播:

/*发送标准的广播:
    案例:这里我们通过按钮的点击事件来发送一条广播,采用静态注册的方法*/

    //创建一个广播接收器
    public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Toast.makeText(context, "received in MyBroadcastReceiver", 
                Toast.LENGTH_SHORT).show();

        //拦截广播
        //abortBroadcast();

    }

}

//然后在AndroidManifest.xml文件下:
 <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <!-- 表示接收的是一个action为MY_BROADCAST的广播 -->
     <receiver android:name=".MyBroadcastReceiver">
         <!-- 设置为100,确保先接收广播 -->
         <intent-filter android:priority="100">
             <action android:name="com.baozhong.sendbroadcast.MY_BROADCAST"/>
         </intent-filter>
     </receiver>
    </application>
    //只要两个程序所接收的广播是一样的,那么这两个应用程序几乎同时接收到了这个广播,点击其中一个
//会接收到两条信息
public class MainActivity extends Activity {
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main_activtiy);

        //以下为发送广播
        //button为发送点
        //注意Intent传递的内容要和action里面的一致,这样才能成为一个对应得广播


        Button button = (Button)findViewById(R.id.button);

        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent = new Intent("com.baozhong.sendbroadcast.MY_BROADCAST");
                sendBroadcast(intent);
                //sendOrderedBroadcast(intent,null);
            }
        });

    }

}

同:点击发送的com.baozhong.sendbroadcast.MY_BROADCAST和接收器中的
 <action android:name="com.baozhong.sendbroadcast.MY_BROADCAST"/>
 相同,才能接收


 /*再新建一个SendBroadcast2
和原先的一样

在没有拦截的情况下,一条广播可以被两个程序接收,回应两次*/


 //发送有序的广播:

 /*在原先的项目的MainActivity中加入一条语句sendOrderedBroadcast(intent,null);
 ,然后再对应得广播接收器MyBroadcast加入拦截abortBroadcast();

可以查看到其效果
*/
/*以上的广播属于系统的全局广播,即发送的广播可以被其他应用程序接收到

那么就可能会引起安全性的问题,那么如何进一步解决这个问题?

使用本地广播来实现:
本地广播多了一个LocalBroadcastManager 用于获取实例 发送广播 注册接收器的监听的一整套的广播机制,所以比较安全*/

//本地广播无法通过静态来注册,只能通过代码注册

//这个为本地广播
//关键是加了private LocalBroadcastManager localBroadcastManager;
//本地广播用来管理本地注册
/*注意:本地广播无法通过静态注册的方式接收
 * 因为静态注册主要是为了在未启动的情况下也能接收到广播
 * 而发送本地广播时,我们的程序已经启动了
 * 因此不需要静态注册功能
 * 所以本地广播比较安全,之前做的都是全局广播
 * 
 * */
public class MainActivity extends Activity {
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        //获取本地广播管理实例
        localBroadcastManager = LocalBroadcastManager.getInstance(this);


        Button button =(Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent = new Intent("com.baozhong.localbroadcastmanager."
                        + "LOCAL_BROADCAST");
                //发送本地广播
                localBroadcastManager.sendBroadcast(intent);
            }
        });

        intentFilter = new IntentFilter();//获取传送广播对象

        //加载广播
        intentFilter.addAction("com.baozhong.localbroadcastmanager.LOCAL_BROADCAST");

        localReceiver = new LocalReceiver();


        //注册本地广播监听器
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);

    }

    class LocalReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            Toast.makeText(context, "receive in Local broadcast", Toast.LENGTH_SHORT).show();

        }

    }
}

/*广播的最佳实践:OffLine实现强制下线的功能

如何实现强制下线:关闭所有的活动,并回到登录界面

一开始为LoginActivity,如果登录成功,就进入发送点击强制下线的广播的界面MainActivity,点击发送广播之后,
就弹出一个警告的对话框,点击Ok后就回到登陆界面LoginActivity*/

//将LoginActivity作为一开始的启动界面


//警告的对话框接收器:AlertDialog.Builder构建一个对话框

public class ForceOfflineReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, Intent intent) {
        // TODO Auto-generated method stub
        //注意一个final Context context
        //AlertDialog.Builder构建一个对话框
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
        dialogBuilder.setTitle("warning");
        dialogBuilder.setMessage("You are forced to be offline.Please try"
                + " to login again");
        dialogBuilder.setCancelable(false);//设置为不能按返回键取消

        //点击Ok,然后活动重新跳到登录界面
        dialogBuilder.setPositiveButton("OK", new OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                //销毁所有的活动
                ActivityCollector.finishAll();
                Intent intent = new Intent(context,LoginActivity.class);

                //一定要加入这个标志FLAG_ACTIVITY_NEW_TASK
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
            }
        });

        //设置一下AlertDialog的类型,保证在广播接收器中对话框可以正常弹出
        AlertDialog alertDialog = dialogBuilder.create();

        alertDialog.getWindow().
        setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

        alertDialog.show();




    }

}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:17782次
    • 积分:389
    • 等级:
    • 排名:千里之外
    • 原创:27篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    最新评论
  • 图片加载器

    xiaoxxxlong: 能把 demo 地址给出来么 直接跑着测试哇。。最近开发需要处理图片的东东 ,,谢谢楼主