系统服务详解之时间服务3

4、全局定时器:AlermManager

全局定时器是与应用程序独立的系统时间服务,并不依赖应用程序而存在。

该对象通过

AlarmManage alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
获得。

通过PendingIntent指定一个Activity,再通过setRepeating方法设置定时器

                                intent = new Intent(this, MyActivity.class);
				pendingActivityIntent = PendingIntent.getActivity(this, 0,
						intent, 0);				
				alarmManager.setRepeating(AlarmManager.RTC, 0, 5000,
						pendingActivityIntent);

通过全局定时器,我们来演示一个每5秒更换手机壁纸的程序:

更换壁纸的Service类:

public class ChangeWallpaperService extends Service
{
	private static int index = 0;
	private int[] resIds = new int[]
	{ R.raw.wp1, R.raw.wp2, R.raw.wp3, R.raw.wp4, R.raw.wp5

	};
	

	@Override
	public void onStart(Intent intent, int startId)
	{

		if(index == 5)
			index = 0;
		InputStream inputStream = getResources().openRawResource(resIds[index++]);
		try
		{
			setWallpaper(inputStream);
		}
		catch (Exception e)
		{

		}
		super.onStart(intent, startId);
	}

	@Override
	public void onCreate()
	{
		super.onCreate();
	}

	@Override
	public IBinder onBind(Intent intent)
	{
		// TODO Auto-generated method stub
		return null;
	}
在mainfirst中配置

	<uses-permission android:name="android.permission.SET_WALLPAPER" />

全局定时器:

public class Main extends Activity implements OnClickListener
{
	private Button btnStart;
	private Button btnStop;
	@Override
	public void onClick(View view)
	{
		AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
		PendingIntent pendingIntent = PendingIntent.getService(this, 0,
				new Intent(this, ChangeWallpaperService.class), 0);
		switch (view.getId())
		{
			case R.id.btnStart:
				alarmManager.setRepeating(AlarmManager.RTC, 0, 5000,
						pendingIntent);				
				btnStart.setEnabled(false);
				btnStop.setEnabled(true);
				break;

			case R.id.btnStop:
				alarmManager.cancel(pendingIntent);
				btnStart.setEnabled(true);
				btnStop.setEnabled(false);
				break;
		}
	}
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		btnStart = (Button) findViewById(R.id.btnStart);
		btnStop = (Button) findViewById(R.id.btnStop);
		btnStop.setEnabled(false);
		btnStart.setOnClickListener(this);
		btnStop.setOnClickListener(this);
	}
}

在创建PendingIntent对象时与service绑定,那么AlarmManager在执行时就会执行service的onStart方法(不是onCreate方法,因为他只会执行一次),获得Service的PendingIntent对象是使用getService方法,同理getActivity,getBroadcast。

下面演示另一个全局定时器的例子,本例是实现多次定时提醒功能。

定时提醒的原理:在添加时间节点后,需要将所添加的时间节点保存在文件或数据库中。本例使用前面介绍过的SharedPreferances来保存。然后使用AlarmManager每隔一分钟扫描一次,在扫描过程中获得当前时间的value,如果成功则说明当前时间为时间点,否则继续扫描。

本例使用BroadcastReceiver来处理定时提醒任务:

public class AlarmReceiver extends BroadcastReceiver
{

	@Override
	public void onReceive(Context context, Intent intent)
	{
		SharedPreferences sharedPreferences = context.getSharedPreferences(
				"alarm_record", Activity.MODE_PRIVATE);
		String hour = String.valueOf(Calendar.getInstance().get(
				Calendar.HOUR_OF_DAY));
		String minute = String.valueOf(Calendar.getInstance().get(
				Calendar.MINUTE));
		String time = sharedPreferences.getString(hour + ":" + minute, null);
		if (time != null)
		{			
			MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.ring);
			mediaPlayer.start();
		}
		
	}

}

配置文件:

	<receiver android:name=".AlarmReceiver" android:enabled="true" />
主程序中每添加一个时间点就会在XML文件中保存所添加的时间点:
public class Main extends Activity implements OnClickListener
{
	private TextView tvAlarmRecord;
	private SharedPreferences sharedPreferences;

	@Override
	public void onClick(View v)
	{
		View view = getLayoutInflater().inflate(R.layout.alarm, null);
		final TimePicker timePicker = (TimePicker) view
				.findViewById(R.id.timepicker);
		timePicker.setIs24HourView(true);
		new AlertDialog.Builder(this).setTitle("设置提醒时间").setView(view)
				.setPositiveButton("确定", new DialogInterface.OnClickListener()
				{

					@Override
					public void onClick(DialogInterface dialog, int which)
					{
						String timeStr = String.valueOf(timePicker
								.getCurrentHour())
								+ ":"
								+ String.valueOf(timePicker.getCurrentMinute());
						tvAlarmRecord.setText(tvAlarmRecord.getText()
								.toString()
								+ "\n" + timeStr);
						sharedPreferences.edit().putString(timeStr, timeStr)
								.commit();

					}
				}).setNegativeButton("取消", null).show();
	}

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Button btnAddAlarm = (Button) findViewById(R.id.btnAddAlarm);
		tvAlarmRecord = (TextView) findViewById(R.id.tvAlarmRecord);
		btnAddAlarm.setOnClickListener(this);
		sharedPreferences = getSharedPreferences("alarm_record",
				Activity.MODE_PRIVATE);

		AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
		Intent intent = new Intent(this, AlarmReceiver.class);
		PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
				intent, 0);
		alarmManager
				.setRepeating(AlarmManager.RTC, 0, 60 * 1000, pendingIntent);

	}
}



上一篇:业务SQL那些事--慎用LIMIT


下一篇:Glide 阅读源码解疑