耗时的,运行在后台的,可以看作是没有界面的activity。设置服务可以提高程序的优先级(第三级),使程序在用户手机运行更久。
第一次开启服务:onCreate() onstartCommand()
随后开启服务:onstartCommand()
开启服务需要先创建服务onCreate(),若是已经创建了服务,则调用onstartCommand()开启服务。
停止服务onDestory() , 然后再次开启服务需要重新创建。直接退出当前应用,后台服务不会关闭,只有当onDestory()方法调用后,服务才会关闭,更具体一点说,是手动调用stopService 或 在应用管理器中关闭 service 服务才会关闭。
开启服务 Intent service=new Intent(this,MyService.class); startService(service);
停止服务 Intent intent=new Intent(this,MyService.class); stopService(intent);
电话录音机:
接电话只能由服务接收到,广播接收者只能接收往外打电话的广播。
而且打电话是一件比较耗时的操作,只能用服务来完成录音,广播一般只用来处理耗时少的简单逻辑。
首先创建一个Service
public class RecordService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
super.onCreate();
//创建一个电话管理器对象,通过这个对象,可以监听电话状态。
TelephonyManager manager=(TelephonyManager) getSystemService(Service.TELEPHONY_SERVICE);
//调用电话管理器的listen方法,注册监听
manager.listen(new PhoneStateListener(){
private MediaRecorder recorder;
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch(state){
case TelephonyManager.CALL_STATE_IDLE:System.out.println("空闲状态,录音结束");
if(recorder!=null){
recorder.stop();
recorder.reset(); // You can reuse the object by going back to setAudioSource() step
recorder.release(); // Now the object cannot be reused
}
break;
case TelephonyManager.CALL_STATE_RINGING:System.out.println("响铃"+incomingNumber);
recorder = new MediaRecorder();
//MIC只能录自己的音 VOICE_CALL可以录双方的音,但外国不允许录别人的音。
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置音频输出的格式3gp效果不太好,体积小
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//设置音频编码,amr早期使用的音频格式AMR_NB效果不太好,体积小 好一点是WB
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//输出文件的保存路径
recorder.setOutputFile(getCacheDir()+"/"+incomingNumber+".3gp");
try {
recorder.prepare();
} catch (Exception e) {
e.printStackTrace();
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:System.out.println("接电话了"+incomingNumber);
recorder.start(); // Recording is now started
break;
}
}}, PhoneStateListener.LISTEN_CALL_STATE);
}
}
在清单文件中配置service
<service android:name="com.haowan.RecordService"></service>
赋予权限
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
最后在MainActivity中添加两个监听事件,startService后便会调用onCreate()方法
public void start(View v){
Toast.makeText(getApplicationContext(), "点击start按钮", Toast.LENGTH_SHORT).show();
Intent service=new Intent(getApplication(),RecordService.class);
startService(service);
}
public void stop(View v){
Intent name=new Intent(getApplication(),RecordService.class);
stopService(name);
}
注意,若来了电话直接挂掉,则会报错。这是因为MediaRecorder没有执行start ,就直接执行了 stop ,没有按照一定的顺序,这里只是稍作修改,将stop用try catch包起来。
这个功能可以作为开机自启动:
用一个广播接收器来收听开机的广播,然后开启电话录音机服务。
先建一个BroadcastReceiver,context调用startService,开启服务
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context,com.haowan.RecordService.class));
}
}
然后配置清单文件
<receiver android:name="com.haowan.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>