音频管理器
振动器
手机闹钟服务
接收广播消息
接收系统广播消息
音频管理器
使用Android提供的AudioManager来管理系统音量,或者直接让系统静音。程序中首先要通过getSystemService()方法来获取系统的音频管理器,然后就可以调用AudioManager的方法来控制手机音频了。
获取AudioManager对象之后,就可以调用如下方法来控制手机音频了。
adjustStreamVolume(int streamType, int direction, int flags):调整手机指定类型的声音。三个参数说明如下:
setMode(int mode):设置声音模式,可设置的值有NORMAL、RINGTONE和IN_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也是调用Context的getSystemService()方法,接下来就调用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应用程序中也是通过Context的getSystemService()方法来获取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,与应用程序启动Activity、Service相同的是,程序启动BroadcastReceiver也只需要两步。
创建需要启动的BroadcastReceiver的Intent。
调用Context的sendBroadcast()或sendOrderedBroadcast()方法来启动指定BroadcastReceiver。
当应用程序发出一个Broadcast Intent后,所有匹配该Intent的BroadcastReceiver都可能被启动。
由于BroadcastReceiver本质上属于一个监听器,因此实现BroadcastReceiver的方法也十分简单,只要重写BroadcastReceiver的onReceive(Context context, Intent intent)方法即可。
一旦实现了BroadcastReceiver,接下来应该指定该BroadcastReceiver能匹配的Intent,此时有两种方法:
使用代码进行指定,调用BroadcastReceiver的Context的registerReceiver(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 发送广播
在程序中发送广播非常简单,只要调用Context的sendBroadcast(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();
}
}
}
本文详细介绍了Android中Service的应用,包括音频管理器、振动器和手机闹钟服务。同时,深入讲解了BroadcastReceiver组件,如何发送和接收广播消息,以及有序广播的概念。还展示了如何通过BroadcastReceiver接收系统广播,如开机自动运行服务和短信提醒。

640

被折叠的 条评论
为什么被折叠?



