android学习笔记之Intent与BroadcastReceiver(二)

本文深入解析了Android系统中BroadcastIntents的工作原理及应用,包括自定义action的使用、广播接受者的注册方式、有序广播与Sticky广播的概念与实现,以及如何利用BroadcastReceiver进行数据处理。
摘要由CSDN通过智能技术生成

安卓系统大量的使用了Broadcast Intents去广播系统的事件,比如网络连接、底座模式的状态、电话接听状态等。

当然也可以自定义的去广播。 

当你广播消息的时候,Intent指定action,data,和category,这样准确去确定由哪个广播接受者去接受广播。

对于自定义action,为了避免重名,通常是以包名为开头,如:
public static final String NEW_LIFEFORM_DETECTED =“com.paad.action.NEW_LIFEFORM”;

我们知道intent是可以指定uri标识数据(setData),或者添加额外的基础类型数据:

例子: 

Intent intent = new Intent(LifeformDetectedReceiver.NEW_LIFEFORM); 
intent.putExtra(LifeformDetectedReceiver.EXTRA_LIFEFORM_NAME, 
                    detectedLifeform); 
intent.putExtra(LifeformDetectedReceiver.EXTRA_LONGITUDE, 
                    currentLongitude); 
intent.putExtra(LifeformDetectedReceiver.EXTRA_LATITUDE, 
                    currentLatitude);
sendBroadcast(intent);
 

那么由谁来接受广播?

那就是大名鼎鼎的BroadcastReceiver(广播接受者)来接收Broadcast Intents。

作为组件之一,像activity一样,也可以为其定义intent-filter这里先不讨论。

当然需要为其注册,像activity一样,对于广播接受者,注册方式分为2种:第一种在代码中动态注册,第二种就像activity一样在mainfest中直接注册声明。

在mainfest中的接受者,不需要自个人所在的app跑起来,当有合适的Intent发来的时候,它会自动启动。

BroadcastReceiver 框架代码:

public class MyBroadcastReceiver extends BroadcastReceiver { 
   @Override 
   public void onReceive(Context context, Intent intent) { 
     //TODO: React to the Intent received. 
   } 
}

 

这个Reiceiver的onReceive方法默认在主线程中执行,所以避免ANR,不要做耗时的操作。

 

略微完整的DEMO:
public class LifeformDetectedReceiver 
   extends BroadcastReceiver { 
   public final static String EXTRA_LIFEFORM_NAME 
     = “EXTRA_LIFEFORM_NAME”; 
   public final static String EXTRA_LATITUDE = “EXTRA_LATITUDE”; 
   public final static String EXTRA_LONGITUDE = “EXTRA_LONGITUDE”;

   public static final String 
     ACTION_BURN = “com.paad.alien.action.BURN_IT_WITH_FIRE”;

  public static final String 
     NEW_LIFEFORM = “com.paad.alien.action.NEW_LIFEFORM”;

  @Override 
  public void onReceive(Context context, Intent intent) { 
     // Get the lifeform details from the intent. 
     Uri data = intent.getData(); 
     String type = intent.getStringExtra(EXTRA_LIFEFORM_NAME); 
     double lat = intent.getDoubleExtra(EXTRA_LATITUDE, 0); 
     double lng = intent.getDoubleExtra(EXTRA_LONGITUDE, 0); 
     Location loc = new Location(“gps”); 
     loc.setLatitude(lat); 
     loc.setLongitude(lng); 
     if (type.equals(“facehugger”)) { 
       Intent startIntent = new Intent(ACTION_BURN, data); 
       startIntent.putExtra(EXTRA_LATITUDE, lat); 
       startIntent.putExtra(EXTRA_LONGITUDE, lng);

       context.startService(startIntent); 
     } 
  } 
}

在代码中动态注册:
private IntentFilter filter = 
  new IntentFilter(LifeformDetectedReceiver.NEW_LIFEFORM);

private LifeformDetectedReceiver receiver = 
  new LifeformDetectedReceiver();

@Override 
public void onResume() { 
   super.onResume();

   // 在运行时注册。

   registerReceiver(receiver, filter); 
}

@Override 
public void onPause() { 
     // 在暂停状态注销。 
   unregisterReceiver(receiver);

   super.onPause(); 
}

 

在Mainfest中注册:
<receiver android:name=”.LifeformDetectedReceiver”> 
  <intent-filter> 
     <action android:name=”com.paad.alien.action.NEW_LIFEFORM”/> 
  </intent-filter> 
</receiver>

 

广播有序的Intents

就是发送有序的广播,根据广播接受者的优先级不同,优先级高的接收者可以优先接受到发来的有序广播,除非你中途中止了广播(abortBroadcast),不然会继续往下传播。

那么如何广播有序的Intents?

String requiredPermission = “com.paad.MY_BROADCAST_PERMISSION”;
sendOrderedBroadcast(intent, requiredPermission);

哪里指定优先级?
<receiver 
  android:name=”.MyOrderedReceiver” 
  android:permission=”com.paad.MY_BROADCAST_PERMISSION”> 
  <intent-filter 
     android:priority=”100”> 
     <action android:name=”com.paad.action.ORDERED_BROADCAST” /> 
  </intent-filter> 
</receiver>

 

代码中的话:

IntentFilter 对象的setPriority即可。

一个常见的例子来接收有序广播:目标是接收一个处理过的结果集。首先把最终接收到结果的接受者优先级设低点,然后比它高的接受者优先处理了这些数据,层层处理,最后的接受者接收到的会是最终的结果。

//在未被最后个接受者接收时,所初始化的值。

int initialResult = Activity.RESULT_OK; 
String initialData = null; 
String initialExtras = null;

// A special Handler instance on which to receive the final result. 
// Specify null to use the Context on which the Intent was broadcast. 
Handler scheduler = null;

sendOrderedBroadcast(intent, requiredPermission, finalResultReceiver,
                            scheduler, initialResult, initialData, initialExtras);  

怎么获得最终的值?

在接受者的onReceive里,可以get到这些值。

广播Sticky Intents

英文意思解释起来貌似是粘性的Intent(意图),那么什么是粘性的呢?与其它的intent有什么不同?
答:这种intent会保存与最后一个广播相关的值,也就是说下一个接收到的也是最近的值。

IntentFilter battery = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent currentBatteryCharge = registerReceiver(null, battery);

上述代码,你会发现注册的接收者居然是为null,首先这里是为了接收到当前系统电池状态的广播intent---系统设备状态广播(比如电池、还有底座状态等),它们广播的是Sticky Intents,所以你经常不需要去弄个接收者去接收这些intents. 只要像上面代码那样registerReceiver它会返回最新的intent。

 

那么我如何去广播我自己的Sticky intents?

答:首先,你的App的mainfest必须包含BROADCAST_STICKY权限。然后在程序中,你就可以使用sendStickyBroadcast(intent)去发送这样的广播。

既然你说这种Intent会保留下值来,那么我不想要了,如何移除它呢?

答:removeStickyBroadcast(intent).

转载于:https://my.oschina.net/wangjunhe/blog/100133

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值