Intent广播事件

    作为一种系统级消息传递的机制,Intent有能力穿越进程边界传递结构化消息。

 

    到目前为止,你已经了解了使用Intent来启动一个新的应用程序组件,但是,它们还可以通过sendBroadcast方法在组件间广播匿名消息。你可以在你的应用程序中实现Broadcast Receiver来监听和响应这些广播的Intent。广播Intent用于通知系统的监听者或应用程序事件,从而扩展了应用程序间的事件驱动编程模型。



1、广播事件

    

    广播Intent让你的程序更加开放;通过使用Intent来广播事件,你让你和第三方开发者响应事件而不需要修改你的原始程序。在你的应用程序里,你可以监听广播的Intent来替换或增强本地的(或第三方的)应用程序,或者对系统变化和应用程序事件作出响应。举个例子,通过监听外来的呼叫广播,你可以改变呼叫者的铃声或音量。

       Android广泛地使用广播Intent来广播系统事件,如电池充电变化,网络连接和来电。

广播Intent是相当地简单。在你的程序组件里,构建你要广播的Intent,使用sendBroadcast方法发送出去。设定Intent的动作、数据和种类来使Broadcast Receiver精确地决定它们的兴趣。在这里,Intent动作字符串用来标识要广播的事件,因此,它必须是独一无二的标识事件的字符串。习惯的,动作字符串使用Java包的样子来定义,如下面的片段所示:

public static final String NEW_LIFEFORM_DETECTED =

“com.paad.action.NEW_LIFEFORM”;

如果你想在Intent中包含数据,你可以使用Intentdata属性来指定一个URI。你还可以包含extras来增加额外的本地类型值。考虑就事件驱动模型而言,这些extras包等价于事件处理函数的可选参数。

 

下面的框架代码给出了一个广播的Intent的基本创建,使用之前定义的动作和一些以extras方法储存的额外的事件信息。

Intent intent = new Intent(NEW_LIFEFORM_DETECTED);

intent.putExtra(“lifeformName”, lifeformType);

intent.putExtra(“longitude”, currentLongitude);

intent.putExtra(“latitude”, currentLatitude);

sendBroadcast(intent);

2、使用Broadcast Receiver监听广播

 

         Broadcast Receiver用于监听广播Intent。为了激活一个Broadcast Receiver,需要在代码或在程序manifest中注册。当注册一个Broadcast Receiver时,你必须使用Intent Filter来指定要监听哪个Intent

 

    为了创建一个新的Broadcast Receiver,需要扩展BroadcastReceiver类,并重写onReceive事件处理函数,如下面的框架代码所示:

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

public class MyBroadcastReceiver extends BroadcastReceiver {

	@Override

	public void onReceive(Context context, Intent intent) {

	//TODO: React to the Intent received.

	}
}

    当广播的Intent与注册的接收器的Intent Filter匹配时,onReceive方法会执行。onReceive处理函数必须在5秒内完成,否则应用程序无响应的对话框会显示。

 Intent广播的时候,注册有Broadcast Receiver的应用程序不需要正在运行。它们在有匹配的广播Intent时自动启动。这对于资源管理来说,是极好的,因为它允许你创建可以被关闭或杀死的事件驱动应用程序,而此刻又以安全的方式对广播事件做出响应。

 

    典型的,Broadcast Receiver会更新内容、启动服务、更新ActivityUI或使用通知管理器来通知用户。5秒的执行限制确保了主进程不能,或者说不应该在Broadcast Receiver中直接结束。

   下面的例子显示了如何实现一个Broadcast Receiver

public class LifeformDetectedBroadcastReceiver extends BroadcastReceiver {

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

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

在程序的manifest中注册

 

    为了在程序的manifest中包含一个Broadcast Receiver,通过在application节点增加一个receiver标签,并指定要注册的Broadcast Receiver的类名。receiver节点需要包含一个intent-filter标签来指定要监听的动作字符串,如下面的XML片段所示:

<receiver android:name=”.LifeformDetectedBroadcastReceiver”>
	<intent-filter>

		<action android:name=”com.paad.action.NEW_LIFEFORM”/>

	</intent-filter>
</receiver>

Broadcast Receiver以这种方注册将总是处于活跃状态。

 

在代码中注册

 

你可以在代码中控制Broadcast Receiver的注册。这种做法的典型例子就是receiver用来在Activity中更新UI元素。一个好的习惯是当Activity不可见(或不活跃)时,反注册Broadcast Receiver

 

下面的代码片段显示了如何使用一个Intent Filter注册Broadcast Receiver

// Create and register the broadcast receiver.

IntentFilter filter = new IntentFilter(NEW_LIFEFORM_DETECTED);

LifeformDetectedBroadcastReceiver r = new LifeformDetectedBroadcastReceiver();

registerReceiver(r, filter);

为了反注册一个 Broadcast Receiver ,在程序上下文中使用unregisterReceiver方法,传入一个 Broadcast Receiver 实例,如下所示:


unregisterReceiver(r);


3、Android本地广播


         Android给许多系统服务广播Intent。你可以使用这些基于系统事件的消息来给自己的工程增添一些功能,这些事件如时区变更、数据连接状态、SMS消息或电话呼叫。

 

下面的列表介绍了一些Intent类中的本地动作常量;这些动作基本上用于设备状态改变的跟踪:

 

 ACTION_BOOT_COMPLETED

一旦设备完成启动时触发。需要RECEIVE_BOOT_COMPLETED权限。

 

 ACTION_CAMERA_BUTTON

摄像头按被按下时触发。

 

 ACTION_DATE_CHANGEDACTION_TIME_CHANGED

当手动修改日期或时间时广播这两个动作。

 

 ACTION_GTALK_SERVICE_CONNECTEDACTION_GTALK_SERVICE_DISCONNECTED

GTalk连接或丢失连接时广播这两个动作。更多GTalk消息将在第9章详细讨论。

 

 ACTION_MEDIA_BUTTON

媒体按钮按下时触发。

 

 ACTION_MEDIA_EJECT

当用户选择弹出外部的储存媒体,会首先触发这个。如果你的程序读写到外部媒体存储器,你应该监听这个事件来保存和关闭任何打开的文件句柄。

 

 ACTION_MEDIA_MOUNTEDACTION_MEDIA_UNMOUNTED

当新的外部存储媒体成功地添加到设备或从设备移除时触发。

 

 ACTION_SCREEN_OFFACTION_SCREEN_ON

当屏幕打开或关闭时广播。

 

 ACTION_TIMEZONE_CHANGED

当电话的当前时区变更时会广播这个动作。Intent中包含一个ID为java.util.TimeZone的时区extras

 

Android用来通知应用程序状态变更的动作的列表可参考:

 

http://code.google.com/android/reference/android/content/Intent.html.

 

Android还使用Broadcast Receiver来监听特定的事件如SMS消息接收。动作和与这些事件关联的Intent将在后面的章节详细讨论,等你了解了更多关于关联服务之后。



你可能感兴趣的:(android,intent,Broadcast,BroadcReceive)