2015-5-1
android 广播机制
5.1简介
分为标准广播(Normal broadcasts)(无先后顺序,几乎同时接收,不可截断)和有序广播(Ordered broadcasts)(有先后顺序,可以截断)两种。
5.2接收系统广播
广播接收器对感兴趣的广播进行注册,这样就能监听到对应的广播,并在内部处理相应的逻辑。
注册广播的方式有两种,分别为在代码中注册(动态注册)(缺点:必须在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreat()方法中的)和在AndroidManifest.xml(静态注册)中注册。
创建广播接收器的方法为:新建一个继承自BroadcastReceiver的类,并重写父类的onReceive()方法就行了,监听到广播时对应的处理逻辑就在onReceive()方法中。
5.2.1通过动态注册的方法实现监听网络变化
IntentFilter:组件告诉Android系统自己乐意接收哪些隐式intent(显式的Intent会直接传送到目标组件)
http://blog.csdn.net/today520/article/details/7000048
1 package com.example.broadcasttest; 2 3 import android.app.Activity; 4 import android.content.BroadcastReceiver; 5 import android.content.Context; 6 import android.content.Intent; 7 import android.content.IntentFilter; 8 import android.net.ConnectivityManager; 9 import android.net.NetworkInfo; 10 import android.os.Bundle; 11 import android.view.Menu; 12 import android.view.MenuItem; 13 import android.widget.Toast; 14 15 public class MainActivity extends Activity { 16 private IntentFilter intentFilter; 17 private NetworkChangeReceiver networkChangeReceiver; 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 intentFilter = new IntentFilter(); 23 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); 24 networkChangeReceiver = new NetworkChangeReceiver(); 25 registerReceiver(networkChangeReceiver,intentFilter); 26 } 27 28 @Override 29 protected void onDestroy() { 30 // TODO Auto-generated method stub 31 super.onDestroy(); 32 unregisterReceiver(networkChangeReceiver); 33 } 34 35 class NetworkChangeReceiver extends BroadcastReceiver{//非静态内部类 36 37 @Override 38 public void onReceive(Context arg0, Intent arg1) { 39 // TODO Auto-generated method stub 40 ConnectivityManager connectivityManager = (ConnectivityManager) 41 getSystemService(Context.CONNECTIVITY_SERVICE); 42 NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 43 if( networkInfo != null && networkInfo.isAvailable() ){ 44 Toast.makeText(arg0, "network is availbale", Toast.LENGTH_SHORT).show(); 45 }else{ 46 Toast.makeText(arg0, "network is unavailbale", Toast.LENGTH_SHORT).show(); 47 } 48 } 49 50 } 51 }
MainActivity.class
需在在AndroidManifest.xml中声明
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
5.2.2通过静态注册监听开机启动广播
//开机启动广播只能用静态注册来监听(?)
1 package com.example.broadtest2; 2 3 import android.content.BroadcastReceiver; 4 import android.content.Context; 5 import android.content.Intent; 6 import android.widget.Toast; 7 8 public class BootCompleted extends BroadcastReceiver{ 9 10 @Override 11 public void onReceive(Context arg0, Intent arg1) { 12 // TODO Auto-generated method stub 13 Toast.makeText(arg0, "开机啦",Toast.LENGTH_SHORT).show(); 14 } 15 }
BootCompleted.class 广播接收器
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.broadtest2" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="8" 9 android:targetSdkVersion="20" /> 10 11 <application 12 android:allowBackup="true" 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" 15 android:theme="@style/AppTheme" > 16 <activity 17 android:name=".MainActivity" 18 android:label="@string/app_name" > 19 <intent-filter> 20 <action android:name="android.intent.action.MAIN" /> 21 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 </activity> 25 <receiver 26 android:name=".BootCompleted" > 27 <intent-filter> 28 <action android:name="android.intent.action.BOOT_COMPLETED" /> 29 </intent-filter> 30 </receiver> 31 </application> 32 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 33 </manifest>
AndroidManifest.xml 这里需对开机启动做权限声明&静态注册广播
这里MainActivity.class中不用写跟广播有关系的内容。
5.3发送自定义广播
5.3.1发送标准广播
1 Intent intent = new Intent("lalala");//自定义的广播名 2 intent.putExtra("key", "get lalala BroadCast~");//可以附带些数据 3 sendBroadcast(intent);
例子:采用静态注册的方法,点击按钮发送一个自定义的广播,MainActivity中就是发送了下广播,没有直接涉及到diy_broadcastReceiver.class。
1 package com.example.broadcasttest; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.Menu; 7 import android.view.MenuItem; 8 import android.view.View; 9 import android.view.View.OnClickListener; 10 import android.widget.Button; 11 12 public class MainActivity extends Activity { 13 14 Button bt; 15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_main); 19 bt = (Button) findViewById(R.id.button1); 20 bt.setOnClickListener(new OnClickListener() { 21 22 @Override 23 public void onClick(View arg0) { 24 // TODO Auto-generated method stub 25 Intent intent = new Intent("lalala"); 26 intent.putExtra("key", "get lalala BroadCast~"); 27 sendBroadcast(intent); 28 } 29 }); 30 } 31 }
MainActivity.class
1 package com.example.broadcasttest; 2 3 import android.content.BroadcastReceiver; 4 import android.content.Context; 5 import android.content.Intent; 6 import android.widget.Toast; 7 8 public class diy_broadcastReceiver extends BroadcastReceiver{ 9 10 @Override 11 public void onReceive(Context arg0, Intent arg1) { 12 // TODO Auto-generated method stub 13 String s = arg1.getExtras().getString("key");//或者arg1.getStringExtra("key"); 14 Toast.makeText(arg0, s, Toast.LENGTH_SHORT).show(); 15 } 16 17 }
diy_broadcastReceiver.class
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context="${relativePackage}.${activityClass}" > 6 7 <TextView 8 android:id="@+id/textView1" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:text="@string/hello_world" /> 12 13 <Button 14 android:id="@+id/button1" 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:layout_alignParentLeft="true" 18 android:layout_below="@+id/textView1" 19 android:layout_marginTop="19dp" 20 android:text="Send BroadCast" /> 21 22 </RelativeLayout>
activity_main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.broadcasttest" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="8" 9 android:targetSdkVersion="20" /> 10 11 <application 12 android:allowBackup="true" 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" 15 android:theme="@style/AppTheme" > 16 <activity 17 android:name=".MainActivity" 18 android:label="@string/app_name" > 19 <intent-filter> 20 <action android:name="android.intent.action.MAIN" /> 21 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 </activity> 25 <receiver 26 android:name=".diy_broadcastReceiver" > 27 <intent-filter> 28 <action android:name="lalala" /> 29 </intent-filter> 30 </receiver> 31 </application> 32 33 </manifest>
AndroidManifest.xml
别的应用,如果静态注册了同样的广播,也会进行相应的操作。
问题:
一个广播接收器注册了多个广播,怎样根据广播来源的不同,进行不同的操作?
5.3.2发送有序广播
//..........