Android笔记----Service应用和BroadcastReceiver组件

本文详细介绍了Android中Service的应用,包括音频管理器、振动器和手机闹钟服务。同时,深入讲解了BroadcastReceiver组件,如何发送和接收广播消息,以及有序广播的概念。还展示了如何通过BroadcastReceiver接收系统广播,如开机自动运行服务和短信提醒。

音频管理器

振动器

手机闹钟服务

接收广播消息

接收系统广播消息

 

 

 

音频管理器

使用Android提供的AudioManager来管理系统音量,或者直接让系统静音。程序中首先要通过getSystemService()方法来获取系统的音频管理器,然后就可以调用AudioManager的方法来控制手机音频了。

获取AudioManager对象之后,就可以调用如下方法来控制手机音频了。

adjustStreamVolume(int streamType, int direction, int flags):调整手机指定类型的声音。三个参数说明如下:

setMode(int mode):设置声音模式,可设置的值有NORMALRINGTONEIN_CALL

setMicrophoneMute(boolean on):设置是否让麦克风静音。

setRingerMode(int ringerMode):设置手机电话铃声的模式。可支持如下属性值。

RINGER_MODE_NORMAL:正常的手机铃声。

RINGER_MODE_SILENT :手机铃声静音。

RINGER_MODE_VIBRATE:手机振动。

setStreamMute(int streamType, boolean state):将手机的指定类型的声音调整为静音。

setSpeakerphoneOn(boolean on):设置是否打开扩音器。

setStreamVolume(int streamType, int index, int flags):设置手机的指定类型的音量值。

例:使用AudioManager控制手机音频:

AudioTest.java

public class AudioTest extends Activity
{
	Button play, up , down;
	ToggleButton mute;
	AudioManager aManager;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取系统的音频服务
		aManager = (AudioManager)getSystemService(
			Service.AUDIO_SERVICE);
		// 获取界面中3个按钮和一个ToggleButton控件
		play = (Button) findViewById(R.id.play);
		up = (Button) findViewById(R.id.up);
		down = (Button) findViewById(R.id.down);
		mute = (ToggleButton) findViewById(R.id.mute);
		// 为play按钮的单击事件绑定监听器
		play.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 初始化MediaPlayer对象,准备播放音乐
				MediaPlayer mPlayer = MediaPlayer.create(AudioTest.this,
					R.raw.earth);
				// 设置循环播放
				mPlayer.setLooping(true);
				// 开始播放
				mPlayer.start();
			}
		});

		up.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 指定调节音乐的音频,增大音量,而且显示音量图形示意
				aManager.adjustStreamVolume(
					AudioManager.STREAM_MUSIC
					, AudioManager.ADJUST_RAISE
					, AudioManager.FLAG_SHOW_UI);
			}
		});
		down.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				// 指定调节音乐的音频,降低音量,而且显示音量图形示意
				aManager.adjustStreamVolume(
					AudioManager.STREAM_MUSIC
					, AudioManager.ADJUST_LOWER
					, AudioManager.FLAG_SHOW_UI);
			}
		});
		mute.setOnCheckedChangeListener(new OnCheckedChangeListener()
		{
			@Override
			public void onCheckedChanged(CompoundButton source
				, boolean isChecked)
			{
				// 指定调节音乐的音频,根据isChecked确定是否需要静音
				aManager.setStreamMute(AudioManager.STREAM_MUSIC
					, isChecked);
			}
		});
	}
}


 

振动器

在某些时候,程序需要启动系统振动器,振动是除了视频、声音之外的另一种“多媒体”,充分利用的系统的振动器会给用户更好的体验。

系统获取Vibrator也是调用ContextgetSystemService()方法,接下来就调用Vibrator的方法来控制手机振动了。

Vibrator的使用比较简单,它只有以下几个简单的方法来控制手机的振动。

 

例:使用Vibrator控制手机振动:

VibratorTest.java

public class VibratorTest extends Activity
{
	Vibrator vibrator;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取系统的Vibrator服务
		vibrator = (Vibrator)getSystemService(Service.VIBRATOR_SERVICE);
	}
	// 重写onTouchEvent方法,当用户触碰触摸屏时触发该方法
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		Toast.makeText(this, "手机振动" , 5000).show();
		// 控制手机震动2秒
		vibrator.vibrate(2000);
		return super.onTouchEvent(event);
	}
}


 

程序控制手机振动需要得到相应的权限,因此,需要在配置文件AndroidManifest.xml文件中增加如下授权配置代码:

<!-- 授予程序访问振动器的权限 -->
	<uses-permission android:name="android.permission.VIBRATE"/>

 

手机闹钟服务

AlarmManager通常的用途就是用来开发手机闹钟,但实际上它的作用不止于此。它的本质是一个全局的定时器,AlarmManager可在指定时间或指定周期启动其他组件。在Android应用程序中也是通过ContextgetSystemService()方法来获取AlarmManager对象,一旦获得该对象,就可以调用它的如下方法来设置定时启动指定组件。

void set(int type, long triggerAtTime, PendingIntent operation):设置在triggerAtTime时间启动由operation参数指定的组件。其中第一个参数指定服务的类型,可接受的参数如下:

ELAPSED_REALTIME:指定从现在开始时间过了一定时间后启动operation所对应的组件。

ELAPSED_REALTIME_WAKEUP:指定从现在开始时间过了一定时间后启动operation所对应的组件。即使系统关机也会执行operation所对应的组件。

RTC:指定当系统调用System.currentTimeMillis()方法返回值与triggerAtTime相等时启动operation所对应的组件。

RTC_WAKEUP:指定当系统调用System.currentTimeMillis()方法返回值与triggerAtTime相等时启动operation所对应的组件。即使系统关机也会执行operation所对应的组件。

void setInexactRepeating(int type, long triggerAtTime, long interval, PendingIntent operation) :设置一个非精确的周期性任务。

void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation):设置一个周期性性执行的定时服务。

void cancel(PendingIntent operation):取消AlarmManager的定时服务。

例:设置闹钟:


AlarmTest.java

public class AlarmTest extends Activity
{
	Button setTime;
	AlarmManager aManager;
	Calendar currentTime = Calendar.getInstance();
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取程序界面的按钮
		setTime = (Button) findViewById(R.id.setTime);
		// 获取AlarmManager对象
		aManager = (AlarmManager) getSystemService(Service.ALARM_SERVICE);
		//为“设置闹铃”按钮绑定监听器。
		setTime.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View source)
			{
				Calendar currentTime = Calendar.getInstance();
				// 创建一个TimePickerDialog实例,并把它显示出来。
				new TimePickerDialog(AlarmTest.this,
					0, // 绑定监听器
					new TimePickerDialog.OnTimeSetListener()
					{
						@Override
						public void onTimeSet(TimePicker tp, int hourOfDay,
							int minute)
						{
							// 指定启动AlarmActivity组件
							Intent intent = new Intent(AlarmTest.this
								, AlarmActivity.class);
							// 创建PendingIntent对象
							PendingIntent pi = PendingIntent.getActivity(
								AlarmTest.this, 0, intent, 0);
							Calendar c = Calendar.getInstance();
							c.setTimeInMillis(System.currentTimeMillis());
							// 根据用户选择时间来设置Calendar对象
							c.set(Calendar.HOUR , hourOfDay);
							c.set(Calendar.MINUTE , minute);
							// 设置AlarmManager将在Calendar对应的时间启动指定组件
							aManager.set(AlarmManager.RTC_WAKEUP
								, c.getTimeInMillis(), pi); 
							// 显示闹铃设置成功的提示信息
							Toast.makeText(AlarmTest.this , 
								"闹铃设置成功啦" , 5000).show();
						}
					}, currentTime.get(Calendar.HOUR_OF_DAY)
					, currentTime.get(Calendar.MINUTE), false)
					.show();				
			}
		});
	}
}

 

AlarmActivity.java

public class AlarmActivity extends Activity
{
	MediaPlayer alarmMusic;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 加载指定音乐,并为之创建MediaPlayer对象
		alarmMusic = MediaPlayer.create(this, R.raw.alarm);
		alarmMusic.setLooping(true);
		// 播放音乐
		alarmMusic.start();
		// 创建一个对话框
		new AlertDialog.Builder(AlarmActivity.this)
			.setTitle("闹钟")
			.setMessage("闹钟响了,Go!Go!Go!")
			.setPositiveButton(
				"确定" ,
				new OnClickListener()
				{
					@Override
					public void onClick(DialogInterface dialog , int which)
					{
						// 停止音乐
						alarmMusic.stop();
						// 结束该Activity
						AlarmActivity.this.finish();
					}
				}
			)
			.show();
	}
}


 

接收广播消息

Android系统的四大组件还有一种BroadcastReceiver,这种组件本质上就是一种全局的监听器,用于监听系统全局的广播消息,因此可以借助BroadcastReceiver实现系统中不同组件之间的通信。

 

4.1 BroadcastReceiver简介

BroadcastReceiver用于接收程序所发出的Broadcast Intent,与应用程序启动ActivityService相同的是,程序启动BroadcastReceiver也只需要两步。

创建需要启动的BroadcastReceiverIntent

调用ContextsendBroadcast()sendOrderedBroadcast()方法来启动指定BroadcastReceiver

当应用程序发出一个Broadcast Intent后,所有匹配该IntentBroadcastReceiver都可能被启动。

由于BroadcastReceiver本质上属于一个监听器,因此实现BroadcastReceiver的方法也十分简单,只要重写BroadcastReceiveronReceive(Context context, Intent intent)方法即可。

一旦实现了BroadcastReceiver,接下来应该指定该BroadcastReceiver能匹配的Intent,此时有两种方法:

使用代码进行指定,调用BroadcastReceiverContextregisterReceiver(BroadcastReceiver receiver , IntentFilter filter)方法指定。

 

AndroidManifest.xml文件中配置。例如:

<receiver android:name=".MyReceiver">
			<intent-filter>
				<action android:name="com.xxx.action.CRAZY_BROADCAST" />
			</intent-filter>		
		</receiver>

 

每次系统Broadcast事件发生后,系统就会创建对应的BroadcastReceiver的实例,并自动触发它的onReceive()方法, onReceive()方法执行后, BroadcastReceiver的实例就会被销毁。

 

4.2 发送广播

在程序中发送广播非常简单,只要调用ContextsendBroadcast(Intent intent)方法即可,这条广播将会启动intent参数所对应的BroadcastReceiver

例:发送广播:

BroadcastMain.java

public class BroadcastMain extends Activity
{
	Button send;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		// 获取程序界面中的按钮
		send = (Button) findViewById(R.id.send);
		send.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				// 创建Intent对象
				Intent intent = new Intent();
				// 设置Intent的Action属性
				intent.setAction("com.xxx.action.CRAZY_BROADCAST");
				intent.putExtra("msg" , "简单的消息");
				// 发送广播
				sendBroadcast(intent);
			}	
		});
	}
}


 

MyReceiver.java

public class MyReceiver extends BroadcastReceiver
{
	@Override
	public void onReceive(Context context, Intent intent)
	{
		Toast.makeText(context , "接收到的Intent的Action为:"
			+ intent.getAction() 
			+ "\n消息内容是:" + intent.getStringExtra("msg")
			, 5000)
			.show();
	}
}


 

4.3 有序广播

BroadcastReceiver所对应的广播分两类:普通广播和有序广播。

Normal Broadcast(普通广播)通过Context.sendBroadcast()方法来发送。它是完全异步的,传递消息的效率比较高。接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播。

Orderd Broadcast(有序广播)是通过Context.sendOrderedBroadcast()来发送。所有的receiver依次执行。BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。可以通过在intent-filter中设置android:priority属性来设置receiver的优先级。

例:有序广播:

 

接收系统广播消息

除了接收用户发送的广播之外, BroadcastReceiver还可以接收系统广播。如果应用需要在系统特定时刻执行某些操作,就可以通过监听系统广播来实现。Android的大量系统事件都会对外发送标准广播。Android常见的广播Action常量API文档

例: 开机自动运行的Service

LaunchReceiver.java

public class LaunchReceiver extends BroadcastReceiver
{
	@Override
	public void onReceive(Context context, Intent intent)
	{
		Intent tIntent = new Intent(context , LaunchService.class);
		// 启动指定Service
		context.startService(tIntent);
	}
}


 

LaunchService.java

public class LaunchService extends Service
{
	@Override
	public IBinder onBind(Intent intent)
	{
		return null;
	}
	@Override
	public void onCreate()
	{
		// 定义1秒执行一行输出
		new Timer().schedule(new TimerTask()
		{

			@Override
			public void run()
			{
				System.out.println("-----"
					+ new Date() + "-----");	
			}
		}, 0, 1000);
	}
}

 

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	  package="com.boby.broadcast"
	  android:versionCode="1"
	  android:versionName="1.0">
	<application android:icon="@drawable/icon" android:label="@string/app_name">
		<service android:name=".LaunchService">
		</service>
		<!-- 定义一个BroadcastReceiver,监听系统开机广播  -->
		<receiver android:name=".LaunchReceiver">    
		    <intent-filter>    
		       <action android:name="android.intent.action.BOOT_COMPLETED" />   
		    </intent-filter>    
		</receiver>
	</application>
	<!-- 授予应用程序访问系统开机事件的权限 -->
	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
</manifest>


 

例:短信提醒:

 

SmsReceiver.java

public class SmsReceiver extends BroadcastReceiver
{	
	// 当接收到短信时被触发
	@Override
	public void onReceive(Context context, Intent intent)
	{
		// 如果是接收到短信
		if (intent.getAction().equals(
			"android.provider.Telephony.SMS_RECEIVED"))
		{
			// 取消广播(这行代码将会让系统收不到短信)
			abortBroadcast();
			StringBuilder sb = new StringBuilder();
			// 接收由SMS传过来的数据
			Bundle bundle = intent.getExtras();
			// 判断是否有数据
			if (bundle != null)
			{
				//  通过pdus可以获得接收到的所有短信消息
				Object[] pdus = (Object[]) bundle.get("pdus");
				// 构建短信对象array,并依据收到的对象长度来创建array的大小 
				SmsMessage[] messages = new SmsMessage[pdus.length];
				for (int i = 0; i < pdus.length; i++)
				{
					messages[i] = SmsMessage
						.createFromPdu((byte[]) pdus[i]);
				}
				// 将送来的短信合并自定义信息于StringBuilder当中 
				for (SmsMessage message : messages)
				{
					sb.append("短信来源:");
					// 获得接收短信的电话号码
					sb.append(message.getDisplayOriginatingAddress());
					sb.append("\n------短信内容------\n");
					// 获得短信的内容
					sb.append(message.getDisplayMessageBody());
				}
			}
			Toast.makeText(context, sb.toString()
				, 5000).show();
		}	
	}
}


 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值