`

Android学习10-----Android组件通信 (7) 广播机制:Broadcast

阅读更多

 

一、 广播:

广播也是一种信息的发送机制,在 Android 手机中存在着各种各样的广播信息,如手机刚启动时的提示信息、电池不足的警报信息和来电信息等,都会通过广播的形式发给用户,而处理的形式由用户自己决定。在 Android 系统中,开发者可以定义自己的广播机制,但是所有的广播组件都是以一个类的形式出现,而且这个类必须继承自 BroadcastReceiver 类,而后还需要想 Android 系统注册。

当用户需要进行广播时,可以通过 Activity 程序中的 sendBroadcast() 方法触发所有的广播组件,而每一个广播组件在进行广播启动之前,也必须判断用户所传递的广播操作是否是指定的 Action 类型,如果是,则进行广播的处理。

Android 系统中,每启动一个广播都需要重新实例化一个新的广播组件对象,并自动调用类中的 onReceive() 方法对广播事件进行处理。

MyBroadcastReceiverUtil.java

package com.iflytek.demo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyBroadcastReceiverUtil extends BroadcastReceiver {
	public MyBroadcastReceiverUtil() { // 构造方法
		System.out.println("** 每次广播都会实例化一个新的广播组件进行操作。");
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		Toast.makeText(context, "广播已经启动", Toast.LENGTH_SHORT).show();
	}

}

Broadcast01Activity.java

package com.iflytek.demo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Broadcast01Activity extends Activity {
	private Button mybut = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main);

		this.mybut = (Button) super.findViewById(R.id.mybut);
		this.mybut.setOnClickListener(new OnClickListenerImpl());
	}

	private class OnClickListenerImpl implements OnClickListener {

		@Override
		public void onClick(View v) {
			Intent it = new Intent(Intent.ACTION_EDIT); // 操作的过滤,启动Action
			Broadcast01Activity.this.sendBroadcast(it);// 进行广播
		}

	}
}

AndroidManifest.xml中的application节点下多一个receiver节点

   <!-- 定义广播处理,android:name指定广播处理类,android:enabled:设置启用广播 -->
        <receiver
            android:enabled="true"
            android:name=".MyBroadcastReceiverUtil" >

            <!-- 匹配Action操作时的广播 -->
            <intent-filter >
                <action android:name="android.intent.action.EDIT" />
            </intent-filter>
        </receiver>

 

上面程序中所使用的 Action 是由系统定义好的,下面我们对上面的程序进行扩展,使用一个自定义的 Action ,并向广播中传送一些数据,而此时程序中注册 intent-filter 时,将直接利用 Activity 类中的两个方法完成手工注册及收工注销,方法如下:

No.

方法

描述

1

Public Intent registerReceiver(BroadcastReceiver receiver,IntentFilter filter)

注册一个 Broadcast 广播,并指定 IntentFilter

2

Public Intent unregisterReceiver(BroadcastReceiver receiver)

注销注定的 Broadcast 广播

注:注册时传的 IntentFilter AndroidManifest.xml intent-filter 节点功能一致, IntentFilter 提供的方法有:

No.

方法

描述

1

Public IntentFilter()

创建一个空的 IntentFilter 对象

2

Public IntentFilter(String action)

创建一个 IntentFilter 对象,并指定 Action

3

Public final void addAction(String action)

增加一个要过滤的 Action

4

Public final void addCategory(String category)

增加一个要过滤的 Category

5

Public final Boolean hasAction(String action)

判断指定的 Action 是否存在

6

Public final Boolean hasCategory(String category)

判断指定的 Category 是否存在

Broadcast02Activity.java

package com.iflytek.demo;

import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Broadcast02Activity extends Activity {
	private Button mybut = null;
	private MyBroadcastReceiverUtil broadUtil = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main);

		this.mybut = (Button) super.findViewById(R.id.mybut);
		this.mybut.setOnClickListener(new OnClickListenerImpl());// 设置监听
	}

	private class OnClickListenerImpl implements OnClickListener {

		@Override
		public void onClick(View v) {
			Intent it = new Intent("com.iflytek.action.XDWANG"); // 操作的过滤
			it.putExtra("msg", "http://xdwangiflytek.iteye.com"); // 附加信息
			IntentFilter filter = new IntentFilter("com.iflytek.action.XDWANG");
			Broadcast02Activity.this.broadUtil = new MyBroadcastReceiverUtil();
			Broadcast02Activity.this.registerReceiver(
					Broadcast02Activity.this.broadUtil, filter);// 注册广播
			Broadcast02Activity.this.sendBroadcast(it);// 进行广播
		}

	}

	@Override
	protected void onStop() {
		super.unregisterReceiver(Broadcast02Activity.this.broadUtil);// 注销广播
		super.onStop();
	}

}

MyBroadcastReceiverUtil.java

package com.iflytek.demo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyBroadcastReceiverUtil extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {// 处理广播事件
		if ("com.iflytek.action.XDWANG".equals(intent.getAction())) { // 判断是指定的Action
			String msg = intent.getStringExtra("msg"); // 取得附加信息
			Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
		}
	}

}

 

一、 通过 Broadcast 启动 Service

在前面我们说了 Activity 程序启动 Service 的操作,那么这里我们再来说一下 Broadcas 启动 Service

MyServiceUtil.java:

package com.iflytek.demo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyServiceUtil extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		System.out.println("*** Service onCreate()");
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		System.out.println("*** Service onDestroy()");
		super.onDestroy();
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("*** Service onStartCommand()");
		return Service.START_CONTINUATION_MASK;
	}

}

 

MyBroadcastReceiverUtil.java

package com.iflytek.demo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class MyBroadcastReceiverUtil extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
		context.startService(new Intent(context, MyServiceUtil.class));
	}

}

Broadcast03Activity.java

package com.iflytek.demo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class Broadcast03Activity extends Activity {

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main);
		Intent it = new Intent("com.iflytek.action.XDWANG"); // 操作的过滤
		Broadcast03Activity.this.sendBroadcast(it);
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

}

广播(BroadcastReceiver)可以像Activity程序那样通过配置运行,是一个可以直接运行的没有界面的Activity程序,一般开发都是通过Activity启动广播(BroadcastReceiver)或者Service,或者是利用广播(BroadcastReceiver)启动Service,所以当需要在后台启动Service,而又不想显示前台界面时,就使用广播(BroadcastReceiver)。

三、闹钟服务
Android系统中为了实现闹钟的功能,专门提供了Context.ALARM_SERVICE闹钟服务,当通过getSystemService()方法取得此服务时,将返回一个android.app.AlarmManager,其提供的常用方法有:

No.

常量及方法

描述

1

Public static final int RTC_WAKEUP

到设置的闹钟时间时,自动唤醒设备

2

Public void cancel(PendingIntent operation)

取消闹钟

3

Public void set(int type,long triggerAtTime,PendingIntent operation)

设置闹钟

4

Public void setRepeation(int type,long triggerAtTime,long interval,PendingIntent operation)

设置闹钟重复响起

5

Public void setTime(long millis)

设置时间

AlarmMessage.java

package com.iflytek.demo;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;

/**
 * 
 * @author xdwang
 * 
 * @create 2012-10-29 下午9:31:39
 * 
 * @email:xdwangiflytek@gmail.com
 * 
 * @description 闹钟提示的Activity程序类
 * 
 */
public class AlarmMessage extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		new AlertDialog.Builder(this)// 建立对话框
				.setIcon(R.drawable.ic_launcher)// 设置图标
				.setTitle("闹钟时间已到!")// 设置对话框标题
				.setMessage(
						"闹钟响起,现在时间:"
								+ new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒")
										.format(new Date()))// 定义显示文字
				.setPositiveButton("关闭", new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						AlarmMessage.this.finish();// 关闭对话框后程序结束
					}
				}).show();// 显示对话框
	}

}

MyAlarmReceiver.java

package com.iflytek.demo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * 
 * @author xdwang
 * 
 * @create 2012-10-29 下午9:52:12
 * 
 * @email:xdwangiflytek@gmail.com
 * 
 * @description 定义广播接受类
 * 
 */
public class MyAlarmReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		Intent it = new Intent(context, AlarmMessage.class);// 定义要操作的Intent
		it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 传递一个新的任务标记
		context.startActivity(it);// 启动Intent
	}

}

Broadcast04Activity.java

package com.iflytek.demo;

import java.util.Calendar;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.TimePicker.OnTimeChangedListener;
import android.widget.Toast;

public class Broadcast04Activity extends Activity {

	private AlarmManager alarm = null; // 闹钟服务管理
	private Button set = null;
	private Button delete = null;
	private TextView msg = null;
	private TimePicker time = null;
	private int hourOfDay = 0;// 保存设置的时
	private int minute = 0;// 保存设置的分
	private Calendar calendar = Calendar.getInstance();

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.main);
		this.set = (Button) super.findViewById(R.id.set);
		this.delete = (Button) super.findViewById(R.id.delete);
		this.msg = (TextView) super.findViewById(R.id.msg);
		this.time = (TimePicker) super.findViewById(R.id.time);

		this.alarm = (AlarmManager) super
				.getSystemService(Context.ALARM_SERVICE);// 取得闹钟服务
		this.set.setOnClickListener(new SetOnClickListener());
		this.delete.setOnClickListener(new DeleteOnClickListener());
		this.time.setIs24HourView(true);// 24小时制
		this.time.setOnTimeChangedListener(new OnTimeChangedListenerImpl());// 设置时间改变监听

	}

	/**
	 * 
	 * @author xdwang
	 * 
	 * @create 2012-10-29 下午9:59:51
	 * 
	 * @email:xdwangiflytek@gmail.com
	 * 
	 * @description 
	 *              时间操作的监听,当时间改变后可以及时的将所设置的时间设置到Calendar对象中,然后通过Calendar对象来设置闹钟的响起时间
	 * 
	 */
	private class OnTimeChangedListenerImpl implements OnTimeChangedListener {

		@Override
		public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
			Broadcast04Activity.this.calendar.setTimeInMillis(System
					.currentTimeMillis());// 设置当前时间
			Broadcast04Activity.this.calendar.set(Calendar.HOUR_OF_DAY,
					hourOfDay);// 设置小时
			Broadcast04Activity.this.calendar.set(Calendar.MINUTE, minute);// 设置分钟
			Broadcast04Activity.this.calendar.set(Calendar.SECOND, 0);// 设置秒
			Broadcast04Activity.this.calendar.set(Calendar.MILLISECOND, 0);// 设置毫秒
			Broadcast04Activity.this.hourOfDay = hourOfDay;// 保存设置的小时
			Broadcast04Activity.this.minute = minute;// 保存设置的分钟
		}

	}

	/**
	 * 
	 * @author xdwang
	 * 
	 * @create 2012-10-29下午10:10:08
	 * 
	 * @email:xdwangiflytek@gmail.com
	 * 
	 * @description 
	 *              设置闹钟的操作类,首先在PendingIntent类包裹一个要执行闹钟响起的Intent操作,之后将此PendingIntent对象设置到闹钟中
	 *              ,设置成功后会提示用户操作成信息
	 * 
	 */
	private class SetOnClickListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			Intent intent = new Intent(Broadcast04Activity.this,
					MyAlarmReceiver.class);// 指定跳转的Intent
			intent.setAction("com.iflytek.action.setalarm");// 定义广播的Action
			PendingIntent sender = PendingIntent.getBroadcast(
					Broadcast04Activity.this, 0, intent,
					PendingIntent.FLAG_UPDATE_CURRENT);// 指定PendingIntent
			Broadcast04Activity.this.alarm
					.set(AlarmManager.RTC_WAKEUP,
							Broadcast04Activity.this.calendar.getTimeInMillis(),
							sender);// 设置闹钟
			Broadcast04Activity.this.msg.setText("闹钟响起的时间是:"
					+ Broadcast04Activity.this.hourOfDay + "时"
					+ Broadcast04Activity.this.minute + "分。");// 提示信息
			Toast.makeText(Broadcast04Activity.this, "闹钟设置成功!",
					Toast.LENGTH_LONG).show();// 显示提示信息
		}

	}

	/**
	 * 
	 * @author xdwang
	 * 
	 * @create 2012-10-29 下午10:18:24
	 * 
	 * @email:xdwangiflytek@gmail.com
	 * 
	 * @description 闹钟设置成功后也可以删除指定的闹钟
	 * 
	 */
	private class DeleteOnClickListener implements OnClickListener {

		@Override
		public void onClick(View v) {
			if (Broadcast04Activity.this.alarm != null) {
				Intent intent = new Intent(Broadcast04Activity.this,
						MyAlarmReceiver.class);
				intent.setAction("com.iflytek.action.setalarm");
				PendingIntent sender = PendingIntent.getBroadcast(
						Broadcast04Activity.this, 0, intent,
						PendingIntent.FLAG_UPDATE_CURRENT);
				Broadcast04Activity.this.alarm.cancel(sender); // 取消
				Broadcast04Activity.this.msg.setText("当前没有设置闹钟。");
				Toast.makeText(Broadcast04Activity.this, "闹钟删除成功!",
						Toast.LENGTH_LONG).show();
			}
		}

	}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" 
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TimePicker
		android:id="@+id/time"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content" />
	<TextView 
		android:id="@+id/msg"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content" 
		android:text="当前没有设置闹钟" />
	<Button 
		android:id="@+id/set"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content" 
		android:text="设置闹钟" />
	<Button 
		android:id="@+id/delete"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content" 
		android:text="删除闹钟" />
</LinearLayout>

AndroidManifest.xml

    <activity android:name=".AlarmMessage" />

        <!-- android:process=":remote"表示单独开票一个进程处理程序 -->

        <receiver
            android:enabled="true"
            android:name="MyAlarmReceiver"
            android:process=":remote" >
            <intent-filter >
                <action android:name="com.iflytek.action.setalarm" />
            </intent-filter>
        </receiver>

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics