Android之路之十七(重要组件之Service)
今天我们来学习Service(Android的隐形管理员)
Service是在一段不定的时间运行在后台,不和用户交互应用组件。每个Service必须在manifest中 通过
Service和其他的应用组件一样,运行在进程的主线程中。这就是说如果service需要很多耗时或者阻塞的操作,需要在其子线程中实现。
service的两种模式(startService()/bindService()不是完全分离的):
本地服务Local Service 用于应用程序内部。
远程服务Remote Service用于android系统内部的应用程序之间。
Service的生命周期:
Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用了onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy()方法,这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法。
而启动service,根据onStartCommand的返回值不同,有两个附加的模式:
1. START_STICKY 用于显示启动和停止service。
2. START_NOT_STICKY或START_REDELIVER_INTENT用于有命令需要处理时才运行的模式。
下面附一副官方给出的比较流程示意图:
下面我们利用服务实现电话监听:
首先在AndroidManifest.xml清单中设置一些权限:
然后实现电话监听器服务类:PhoneListenerService.java:
package cn.class3g.phonelistener;import java.io.File;import java.io.IOException;import android.app.Service;import android.content.Context;import android.content.Intent;import android.media.MediaRecorder;import android.os.Environment;import android.os.IBinder;import android.telephony.PhoneStateListener;import android.telephony.TelephonyManager;import android.util.Log;public class PhoneListenerService extends Service {public void onCreate() {super.onCreate();Log.i("TAG", "服务启动了");// 对电话的来电状态进行监听TelephonyManager telManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);// 注册一个监听器对电话状态进行监听telManager.listen(new MyPhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);}private class MyPhoneStateListener extends PhoneStateListener {MediaRecorder recorder;File audioFile;String phoneNumber;public void onCallStateChanged(int state, String incomingNumber) {switch (state) {case TelephonyManager.CALL_STATE_IDLE: // 无任何状态时if (recorder != null) {recorder.stop();// 停止刻录recorder.reset();// 重设recorder.release();// 刻录完成一定要释放资源}break;case TelephonyManager.CALL_STATE_OFFHOOK: // 接起电话时 try {recorder = new MediaRecorder();recorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置音频采集原recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// 内容输出格式recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 音频编码方式// recorder.setOutputFile("/sdcard/myvoice.amr");audioFile = new File(Environment.getExternalStorageDirectory(),phoneNumber + "_" + System.currentTimeMillis()+ ".3gp");recorder.setOutputFile(audioFile.getAbsolutePath());Log.i("TAG", audioFile.getAbsolutePath());recorder.prepare(); // 预期准备recorder.start();} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}break;case TelephonyManager.CALL_STATE_RINGING: // 电话进来时 phoneNumber = incomingNumber;break;default:break;}super.onCallStateChanged(state, incomingNumber);}}public IBinder onBind(Intent arg0) {return null;}}
利用开机启动广播启动服务器(实验环境中为了方便起见可以先改用短消息广播)
开机启动完成广播action
package cn.class3g.phonelistener;public class BootBroadcastReceiver extends BroadcastReceiver {public void onReceive(Context context, Intent intent) {Log.i("TAG", "广播被接收了");Intent serviceIntent = new Intent(context, PhoneListenerService.class);context.startService(serviceIntent);}}
更多相关文章
- Fedora17 64位 android "failed to create the SD card" 解决方
- Android的adapter总结和深入研究
- android获取控件宽和高
- Android事件和监听器详细的介绍
- Android中自定义数据适配器Adapter
- android 4.2.2提示 unauthorized终极解决办法,很粗暴
- Android(安卓)ADB超简单的安装方法
- Android(安卓)UI开发详解之Fragment
- Android(安卓)开发之多线程处理、Handler 详解