一、 广播:
广播也是一种信息的发送机制,在 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>