那个小生怕怕 电影是不是可以实现自动录音啊

金融之家4月1日讯,重庆市公安局、众安保险和深圳位置网日前共同在重庆召开&互联网失踪失联人员&怕怕&安全搜救平台&启动仪式。在此次启动会上,一款防身APP&-&众安怕怕&无偿向重庆市公安局提供救援救助平台和相关数据服务。
重庆市公安局率先引入互联网救援能力,既丰富百姓的报警方式,又提升事中救助效率,减少警务资源浪费。
众安怕怕作为国内首款专业人身安全定位求助APP,2015年底上线以来,已为上百万用户提供事前、事中、事后完整的安全救助方案。未来,怕怕还将致力于与警方开展深入合作,共同优化治安环境,守护公众安全,并在个性化保障服务、智能穿戴设备等多领域加以探索。
重庆110联手众安怕怕开启互联网防护新模式
互联网技术的运用,让百姓的生活越来越便利,互联网技术与警务系统的对接,也让安全防护更加触手可及。
据介绍,众安怕怕与重庆市警务系统对接后,用户在使用APP的过程中,如果遇上危险,可直接在App中进行求助,众安怕怕会通过系统后台算法及人工双重处理机制,通过分析用户位置、录音等信息,进行判断。如果有异常,便会将求助人的联系方式、所在坐标、现场图像、录音等,实时传输到重庆市公安局110报警服务台。
这种报警模式更加方便、高效,且适用于紧急情况,尤其适合年轻女性、老人、儿童、聋哑人等弱势人群。这种互联网新型防护模式也将打破传统电话报警要求求助人完全了解自身位置、有足够时间清晰陈述等诸多限制。
科技助力打通&防护+救助&
众安怕怕出自国内首家互联网保险&众安保险&之手&,众安一直在倡导做有温度的保险,众安怕怕便是一款可以让大家感知温度的产品。
&可能不是每个人都需要保险,但人人都需要安全感、需要保障。&众安怕怕负责人如是指出,基于这样的需求,我们在2015年决定开发众安怕怕这一产品,致力于为用户提供触手可及的安全防护,为用户第一时间提供事前、事中、事后全套救助方案。
众安怕怕负责人还介绍道,当用户独自走夜路、晚间打车、夜跑时,可在出行前提前开启&定时防护&模式,众安怕怕后台会自动记录用户行程轨迹。
到了定时防护约定时点,如果用户没有关闭防护;众安怕怕会自动将其所在位置和录音发给预先设定的紧急联系人,第一时间确定用户安全与否。
一旦用户遭遇危险,可以通过App来一键报警,众安怕怕将根据用户在危急时发出的呼喊救命等求救信号唤醒后台,通过用户&GPS +基站+WIFI&等信息,对用户精准定位,并综合录音、照片信息进行后台预先处理,如确认用户存在风险,将即时向警方反映事件内容和细节。
简单易得的安全防护功能受到越来越多用户的认可,截至今年2月底数据显示,众安怕怕用户数量已经突破百万。为了保证第一时间响应用户的需求,众安怕怕配备了专业的应急客服处理团队,在后方7*24小时全天候地守护用户安全。
警务互联网+ 营造&智慧、安全&大环境
警务互联网+模式的开启,也推动了今年两会报告中&互联网+政务&的落实步伐。
据了解,近几年来,重庆市公安局主动拥抱互联网,率先开放报警平台互联网接入能力,探索建立&警务互联网+&工作新模式。
重庆市公安系统与众安怕怕、深圳位置网展开合作,致力于进一步丰富百姓的报警方式,提高报警的便利及准确性。
依托三方合作经验,伴随着用户量增长以及后台大数据的积累,众安怕怕接下来还将与警务系统开展深入合作,如协助警方出台应对措施,发力个性化保障服务、智能穿戴设备等多个领域,未来众安怕怕还将致力于为全国更多地区警务系统无偿提供有价值的预警信息,营造&智慧、安全&的大环境。(文/和讯保险)
免责声明:[
金融之家-JRZJ.COM刊发此文目的在于传递更多信息,文章内容仅供参考,不构成投资建议。投资者据此操作,风险自担
责任编辑:冯青
发表回复 金豆+2
|还可以输入 500 字
金融之家客户端
点击或扫描下载
金融之家客户端下载苹果手机如何实现通话自动录音?注意:是自动,而不是手动。 - 知乎43被浏览<strong class="NumberBoard-itemValue" title="4分享邀请回答23 条评论分享收藏感谢收起44 条评论分享收藏感谢收起做你的随行使者,回家路再也不怕怕—一款免费APP安利_使用评测_什么值得买
做你的随行使者,回家路再也不怕怕—一款免费APP安利
最近发现一个新鲜玩意儿,迫不及待的想和大家分享一下,好东西就应该众乐乐!今天的主角一款APP——怕怕,它打出的口号是:每天晚上护送你回家的防身求救软件。这是我某天在微博刷到的,一个po主不经意的安利,居然猝不及防的被各种转发评论。我觉得能引起这么高的转发量和关注度,有些原因是这两年爆出的一些女性失踪案对社会的影响,一些无规律的案发确实挺让人心惊胆战的,其中有一个被害人当时还是和我一个大学的同学,以前这种事情看起来离我很远,但时刻有防范意识是很重要的。微博上介绍时说是可以在定好的时间内实时监测你的信息有危险时会自动发出求救信号,这么一听,是不是感觉很适合小仙女们,当然小仙男也可以down来备用。被安利后我马上去下载了一个,并在当天下班路上就开始用了,下面就来仔细说一下这款APP的使用情况吧~·使用情况APP的图标长这样,蓝底白字,感觉中规中矩,现在它在我心中已经和农药是一个级别的了&话说,我钻4,有一起上分的小伙伴嘛&打开APP后,出现的是几P对怕怕的简单介绍,可以选择三种登录方式——、微信、QQ。一般都要绑一下手机号,所以我直接就选择的是手机登录,写好短信验证码就OK啦。它的运作流程如下图,开启防护→有求助需求时在系统5s倒计时结束后自动录音→通知紧急联系人→若是确认安全就直接输入安全密码结束防护。所以初次使用是会你先让填写一个紧急联系人联系方式,推荐的是填写同城靠谱的朋友或是室友,作为有需要时自动发送你的求助信息到ta手机上,这里我不是很明白,当时是需要我填写联系人的真实姓名,姓名+电话信息都录进去了,对个人信息安全会有些小担心...接着会设置一个安全密码,用于结束保护时手动确认输入。初步设置好了以后,联系人会收到短信,可以看出怕怕的合作企业是众安,之后的短信都是由众安保险发过来的。然后就可以使用怕怕了,进入主界面,页面上有四种防护模式、有可选择的保护时间、还有直接一键求助模式。还有一个守护TA的模式,像是一个实时位置的功能。先说说主页面最下方的一键求助,按下后倒计时5s后就会自动录音并向联系人发出信号,这是在你来不及设置行程时的SOS,一般情况下是不用按下的。来说说常用流程:防护模式分打夜车、见生人、走夜路、其他四种,我个人常用的会是打夜车及走夜路两种。保护时间可以设置10min-120min或是自定义时间,选择好防护模式后就可以开始保护了。选择30min时间,页面上直接出现的是你的实时位置,并有一个倒计时,在计时结束时你都没有手动结束防护的话就会自动发起求助。页面上还出现了“伪装来电”、“伪装语音”,下方有“语音救助”、“拍照留言”、“分享行程”,还有“立即救助”、“结束防护”。伪装来电——按下后会系统给马上自动造一个来电界面,很高级!真的有来电铃声,接听后还有正常的计时显示,不过电话那头并没有真的亲爱哒而已&伪装语音——点一点就会出现一个男生的语音:“哎你到哪儿啦,还有多长时间到啊,要不要过去接你一下”,这功能很好用,挺适合单身仙女们,当然有男友的仙女也可以用来做备用。就昨晚我回家时楼下坐了大叔,我进门等电梯时他也一起进来了,我闻到了一些酒气,顿时各种脑洞打开的我把自己吓得有点忐忑&,然后进电梯后就马上开了APP,播放了这段语音,自己也装着回复了一句,听到语音后他朝这边看了一下,到了他的楼层他就出去了。我可能是有些小题大做,但是有时候有些防范意识还是好的。我会在晚上自己打车或者走夜路后面有脚步声的时候顿时紧张起来(初中时有一次我一个人爬,后面跟着一个大叔,我一口气跑上了8楼&),虽然多数时刻是自己吓自己,但还是希望小仙女小仙男们都有警惕之心,保护好自己!语音救助——这个功能需要提前开启,在开启保护后,APP会自动识别周围的声音,当你说出关键词“救命啊”“别伤害我”“别碰我”后,先是会有启动震动,然后自动开始30s的录音,录音结束后,就会通知你的紧急联系人。我和朋友试了一次,说出关键词后界面如下,有一段30s的录音,界面上提示我的实时位置已经上传了(如果中途确认安全就直接点击“我安全了”这个选择,输入安全密码后功能停止)接着朋友那边就收到了怕怕平台的电话也来了,接起来是30s的录音内容。然后还会接到平台发出的短信,告诉朋友我发出求助时的大致位置。当发起求助后再确认安全的话,朋友也接到了一条报平安的信息。我们实验了一遍,所有跟求助有关的按键都是以上的步骤进行的,包括开启防护页面的语音求助、立即求助还有主页面上的SOS一键求助。拍照留言——这个功能可以先把要和你对接的人、车或者周边事物拍下来然后留言,作为有求助需求时的一项证据。分享行程——可以把你的规划行程通过微信、短信和QQ三种形式一键分享给朋友。结束防护——当开启防护并且后台在线时,防护功能一直存在的,如果倒计时结束没有手动关掉就会自动开启求助模式,所以当你安全到达后记得关掉哦~手动结束防护时会因为确认安全而需要输入一个预先设好的安全密码,证明确实是出自自身意愿关掉防护的,这里有个小细节也做得很好,在输入密码界面直接有拨出110报警电话的按键,算是多层保护吧。如果一直没有确认的话,怕怕后台会直接发出求助信号,↓官博的某一条&ps.当后台运作时记得不要划掉APP,这句话也感觉暖暖的呢。疑问点这款软件设计得很有心,不过我会担心个人的信息安全,针对这一点官方的回复是这样的——从日期可以看出算是很新鲜的一条微博了,2015年开始做这个项目,2017年8月底才突然火起来。我在官博评论下看到有些小仙女说登录不上或者网络错误等bug,怕怕小编回复说是就在当天暴增了几十万用户导致都快崩了&,这算是一夜成名了吧...我也是前两天才知道这款APP的,目前它算是还处于一个扩大了认知后考验后期服务的一个阶段吧,还在成长中,有bug及时修复是可以谅解的,并且基本需求可以满足,所以我也没有太多要求。好啦~这款APP的介绍就到这里啦,目前支持的是安卓和iOS两个版本,而且是免费哒,我试了一下在一般的应用商城是可以搜到的,海外版貌似还在制作中。这几天我有加班情况的话回家路上都会开启怕怕,真的会感觉比较踏实。安利给大家,希望能为你一个人的回家路打打气。更希望大家的安全意识能时刻开启,做智慧美貌并存的小仙女!&
推荐关注:
鼠标移到标签上方,
尝试关注标签~
相关热门原创
作者其他原创(7)
嘉实多磁护/嘉实多磁护启停保全合成润滑油
小米 6X 智能手机 6+64G版
魅族POP真无线蓝牙耳机
唯斯特姆(Wastemaid)X食物垃圾处理器
便洁宝 BWA420G 智能马桶盖
Libratone小鸟音响Track 无线智能降噪耳机
唱吧 G1无线喇叭麦克风
MEIZU 魅族 15 智能手机
OE E60P 平面振膜入耳式耳机
D-Link DIR-882 AC2600 MU-MIMO双频千兆无线路由
小沐智能马桶盖
Fresh馥蕾诗亮活维他果萃面膜
GOURMETmaxx 西餐厨师机
腾讯听听 TS-T1 人工智能音箱
赞180评论328
赞184评论166
赞154评论79
赞662评论125
赞646评论303
赞360评论304
赞386评论82
赞461评论143
扫一下,分享更方便,购买更轻松
用户名/邮箱
两周内免登录Android 实现电话来去自动录音的功能_Android
作者:用户
本文讲的是Android 实现电话来去自动录音的功能_Android,
我们在使用Android手机打电话时,有时可能会需要对来去电通话自动录音,本文就详细讲解实现Android来去电通话自动录音的方法,大家按照文中的方法编写程序就可以完成此功能。
来去电自动录音的关键在于如何监听手机电话状态的
我们在使用Android手机打电话时,有时可能会需要对来去电通话自动录音,本文就详细讲解实现Android来去电通话自动录音的方法,大家按照文中的方法编写程序就可以完成此功能。
来去电自动录音的关键在于如何监听手机电话状态的转变:
1)来电的状态的转换如下(红色标记是我们要用到的状态)
空闲(IDEL)——& 响铃(RINGING)——& 接听(ACTIVE)——& 挂断(经历DISCONNECTING——DISCONNECTED)——& 空闲(IDEL)
空闲(IDEL)——& 响铃(RINGING)——& 拒接 ——& 空闲(IDEL)
2)去电状态的转换如下
空闲(IDEL)——& 拨号 (DIALING)——& (对方)响铃(ALERTING) ——& 建立连接(ACTIVE)—— 挂断(经历DISCONNECTING——DISCONNECTED)——& 空闲(IDEL)
或者 空闲(IDEL)——& 拨号 (DIALING)——& (对方)响铃(ALERTING)——& 挂断/对方拒接 ——& 空闲(IDEL)
下面就分别就来电和去电这两种状态分析并实现。
1、先进行来电的分析和实现。
相对去电来说,来电状态的转换检测要简单些。android api 中的PhoneStateListener 类提供了相应的方法,但我们需要覆盖其中的 onCallStateChanged(int state, String incomingNumber) 方法即可实现来电状态的检测,并在此基础上添加录音功能即可。其中 state 参数就是各种电话状态,到时我们将它跟下面我们要用到的状态进行比较,若是电话处在我们想要的状态上,则进行一系列操作,否则就不管他。想要获取这些状态,还需要另一个电话相关类,那就是 TelephonyManager, 该类 提供了一些电话状态,其中我们要用到的是:TelephonyManager.CALL_STATE_IDLE(空闲)、TelephonyManager.CALL_STATE_OFFHOOK(摘机)和 TelephonyManager.CALL_STATE_RINGING(来电响铃)这三个状态。判别这三种状态,可以继承 android.telephony.PhoneStateListener 类,实现上面提到的 onCallStateChanged(int state, String incomingNumber) 方法,请看如下代码:
public class TelListener extends PhoneStateListener {
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 空闲状态,即无来电也无去电
Log.i("TelephoneState", "IDLE");
//此处添加一系列功能代码
case TelephonyManager.CALL_STATE_RINGING: // 来电响铃
Log.i("TelephoneState", "RINGING");
//此处添加一系列功能代码
case TelephonyManager.CALL_STATE_OFFHOOK: // 摘机,即接通
Log.i("TelephoneState", "OFFHOOK");
//此处添加一系列功能代码
Log.i("TelephoneState", String.valueOf(incomingNumber));
有了以上来电状态监听代码还不足以实现监听功能,还需要在我们的一个Activity或者Service中实现监听,方法很简单,代码如下:
* 在activity 或者 service中加入如下代码,以实现来电状态监听
TelephonyManager telMgr = (TelephonyManager)context.getSystemService(
Context.TELEPHONY_SERVICE);
telMgr.listen(new TelListener(), PhoneStateListener.LISTEN_CALL_STATE);
这样就实现了来电状态监听功能,但要能够在设备中跑起来,这还不够,它还需要两个获取手机电话状态的权限:
&uses-permission android:name="android.permission.READ_PHONE_STATE" /&
&uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /&
这样的话就可以跑起来了。
说到这,我想如果你可以实现录音功能的话,在此基础上实现来电自动录音就应该没什么问题了,不过请容我简单罗嗦几句。既然是来电,那么要想录音的话,那么应该就是在监听到 TelephonyManager.CALL_STATE_OFFHOOK 的状态时开启录音机开始录音, 在监听到TelephonyManager.CALL_STATE_IDLE 的状态时关闭录音机停止录音。这样,来电录音功能就完成了,不要忘记录音功能同样需要权限:
&uses-permission android:name="android.permission.RECORD_AUDIO"/&
&!-- 要存储文件或者创建文件夹的话还需要以下两个权限 --&
&uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/&
&uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&
2、介绍完了来电自动录音,下面就来介绍去电自动录音的实现方法。
上面说过,相比来电状态的监听,去电的要麻烦些,甚至这种方法不是通用的,这个主要是因为android api 中没有提供去电状态监听的相应类和方法(也许我刚接触,没有找到)。刚开始网上搜索了一通也没有找到对应的解决方法,大多是 来电监听的,也就是上面的方法。不过中途发现一篇博文(后来就搜不到了),记得是查询系统日志的方式,从中找到去电过程中的各个状态的关键词。无奈之中,最终妥协了此方法。
我的(联想A65上的)去电日志内容如下:
过滤关键词为 mforeground
01-06 16:29:54.225: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:54.245: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:54.631: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:54.645: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:54.742: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:54.766: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:54.873: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:54.877: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:55.108: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:55.125: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DIALING
01-06 16:29:57.030: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE
01-06 16:29:57.155: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE
01-06 16:29:57.480: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE
01-06 16:29:57.598: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE
01-06 16:29:59.319: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING
01-06 16:29:59.373: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING
01-06 16:30:00.392: D/InCallScreen(251): - onDisconnect: currentlyIdle: mForegroundCall.getState():DISCONNECTED
01-06 16:30:00.399: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): - onDisconnect: currentlyIdle: mForegroundCall.getState():DISCONNECTED
01-06 16:30:01.042: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE
01-06 16:30:01.070: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : IDLE
01-06 16:30:01.558: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE
01-06 16:30:01.572: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mForegroundCall.getState() : IDLE
过滤关键词
mbackground
01-06 16:29:54.226: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:54.256: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:54.638: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:54.652: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:54.743: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:54.770: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:54.875: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:54.882: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:55.109: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:55.142: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:57.031: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:57.160: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:57.481: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:57.622: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:59.319: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:29:59.373: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:30:01.042: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:30:01.070: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:30:01.559: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
01-06 16:30:01.573: V/LogInfo OutGoing Call(2492): D/InCallScreen( 251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE
从上面的日志可以看到,每一行的末尾的大写英文词就是去电的状态,状态说明如下:
DIALING 拨号,对方还未响铃
对方接通,通话建立
DISCONNECTING 通话断开时
DISCONNECTED
通话已断开,可以认为是挂机了
由于我拨打的是10010,没有响铃过程(电脑自动接通的够快),还少了一个状态,状态是ALERTING ,这个就是对方正在响铃的状态。
有了这几个去电状态就好办了,现在我们要做的就是读取系统日志,然后找到这些状态,提取的关键词就是上面提到的 mforeground(前台通话状态) 和 mbackground (后台通话状态)(可能不一样的设备生成的不一样,根据自己具体设备设置,这里只提取前台的),如果读取的这一行日志中 包含 mforground ,再看看是否包含上面的状态的单词。既然说的如此,那么看看读取系统日志的代码吧。
package com.sdvdxl.
import java.io.BufferedR
import java.io.IOE
import java.io.InputS
import java.io.InputStreamR
import com.sdvdxl.outgoingcall.OutgoingCallS
import android.content.C
import android.content.I
import android.util.L
* @author sdvdxl
* 找到 日志中的
* onPhoneStateChanged: mForegroundCall.getState() 这个是前台呼叫状态
* mBackgroundCall.getState() 后台电话
* 若 是 DIALING 则是正在拨号,等待建立连接,但对方还没有响铃,
* ALERTING 呼叫成功,即对方正在响铃,
* 若是 ACTIVE 则已经接通
* 若是 DISCONNECTED 则本号码呼叫已经挂断
* 若是 IDLE 则是处于 空闲状态
public class ReadLog extends Thread {
private int logC
private static final String TAG = "LogInfo OutGoing Call";
* 前后台电话
* @author sdvdxl
private static class CallViewState {
public static final String FORE_GROUND_CALL_STATE = "mForeground";
* 呼叫状态
* @author sdvdxl
private static class CallState {
public static final String DIALING = "DIALING";
public static final String ALERTING = "ALERTING";
public static final String ACTIVE = "ACTIVE";
public static final String IDLE = "IDLE";
public static final String DISCONNECTED = "DISCONNECTED";
public ReadLog(Context ctx) {
this.ctx =
* 读取Log流
* 取得呼出状态的log
* 从而得到转换状态
public void run() {
Log.d(TAG, "开始读取日志记录");
String[] catchParams = {"logcat", "InCallScreen *:s"};
String[] clearParams = {"logcat", "-c"};
Process process=Runtime.getRuntime().exec(catchParams);
InputStream is = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line =
while ((line=reader.readLine())!=null) {
logCount++;
//输出所有
Log.v(TAG, line);
//日志超过512条就清理
if (logCount&512) {
//清理日志
Runtime.getRuntime().exec(clearParams)
.destroy();//销毁进程,释放资源
logCount = 0;
Log.v(TAG, "-----------清理日志---------------");
/*---------------------------------前台呼叫-----------------------*/
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.IDLE)) {
Log.d(TAG, ReadLog.CallState.IDLE);
//正在拨号,等待建立连接,即已拨号,但对方还没有响铃,
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.DIALING)) {
Log.d(TAG, ReadLog.CallState.DIALING);
//呼叫对方 正在响铃
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.ALERTING)) {
Log.d(TAG, ReadLog.CallState.ALERTING);
//已接通,通话建立
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.ACTIVE)) {
Log.d(TAG, ReadLog.CallState.ACTIVE);
//断开连接,即挂机
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.DISCONNECTED)) {
Log.d(TAG, ReadLog.CallState.DISCONNECTED);
} //END while
} catch (IOException e) {
e.printStackTrace();
} //END try-catch
} //END run
} //END class ReadLog
以上代码中,之所以用线程,是为了防止读取日志过程中阻滞主方法的其他方法的执行,影响到程序捕捉对应的电话状态。
好了,捕捉到了去电过程中各个状态的转变,那么,如何通知给程序呢,我采用的方法是捕获后立马给系统发送广播,然后程序进行广播接收,接收后再处理录音事件。要发送广播,就要发送一个唯一的广播,为此,建立如下类:
package com.sdvdxl.
import com.sdvdxl.phonerecorder.ReadL
import android.content.C
import android.util.L
public class OutgoingCallState {
public OutgoingCallState(Context ctx) {
this.ctx =
* 前台呼叫状态
* @author sdvdxl
public static final class ForeGroundCallState {
public static final String DIALING =
"com.sdvdxl.phonerecorder.FORE_GROUND_DIALING";
public static final String ALERTING =
"com.sdvdxl.phonerecorder.FORE_GROUND_ALERTING";
public static final String ACTIVE =
"com.sdvdxl.phonerecorder.FORE_GROUND_ACTIVE";
public static final String IDLE =
"com.sdvdxl.phonerecorder.FORE_GROUND_IDLE";
public static final String DISCONNECTED =
"com.sdvdxl.phonerecorder.FORE_GROUND_DISCONNECTED";
* 开始监听呼出状态的转变,
* 并在对应状态发送广播
public void startListen() {
new ReadLog(ctx).start();
Log.d("Recorder", "开始监听呼出状态的转变,并在对应状态发送广播");
程序需要读取系统日志权限:
XML/HTML代码
&uses-permission android:name="android.permission.READ_LOGS"/&
然后,在读取日志的类中检测到去电各个状态的地方发送一个广播,那么,读取日志的完整代码如下:
package com.sdvdxl.
import java.io.BufferedR
import java.io.IOE
import java.io.InputS
import java.io.InputStreamR
import com.sdvdxl.outgoingcall.OutgoingCallS
import android.content.C
import android.content.I
import android.util.L
* @author mrloong
* 找到 日志中的
* onPhoneStateChanged: mForegroundCall.getState() 这个是前台呼叫状态
* mBackgroundCall.getState() 后台电话
* 若 是 DIALING 则是正在拨号,等待建立连接,但对方还没有响铃,
* ALERTING 呼叫成功,即对方正在响铃,
* 若是 ACTIVE 则已经接通
* 若是 DISCONNECTED 则本号码呼叫已经挂断
* 若是 IDLE 则是处于 空闲状态
public class ReadLog extends Thread {
private int logC
private static final String TAG = "LogInfo OutGoing Call";
* 前后台电话
* @author sdvdxl
private static class CallViewState {
public static final String FORE_GROUND_CALL_STATE = "mForeground";
* 呼叫状态
* @author sdvdxl
private static class CallState {
public static final String DIALING = "DIALING";
public static final String ALERTING = "ALERTING";
public static final String ACTIVE = "ACTIVE";
public static final String IDLE = "IDLE";
public static final String DISCONNECTED = "DISCONNECTED";
public ReadLog(Context ctx) {
this.ctx =
* 读取Log流
* 取得呼出状态的log
* 从而得到转换状态
public void run() {
Log.d(TAG, "开始读取日志记录");
String[] catchParams = {"logcat", "InCallScreen *:s"};
String[] clearParams = {"logcat", "-c"};
Process process=Runtime.getRuntime().exec(catchParams);
InputStream is = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line =
while ((line=reader.readLine())!=null) {
logCount++;
//输出所有
Log.v(TAG, line);
//日志超过512条就清理
if (logCount&512) {
//清理日志
Runtime.getRuntime().exec(clearParams)
.destroy();//销毁进程,释放资源
logCount = 0;
Log.v(TAG, "-----------清理日志---------------");
/*---------------------------------前台呼叫-----------------------*/
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.IDLE)) {
Log.d(TAG, ReadLog.CallState.IDLE);
//正在拨号,等待建立连接,即已拨号,但对方还没有响铃,
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.DIALING)) {
//发送广播
Intent dialingIntent = new Intent();
dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.DIALING);
ctx.sendBroadcast(dialingIntent);
Log.d(TAG, ReadLog.CallState.DIALING);
//呼叫对方 正在响铃
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.ALERTING)) {
//发送广播
Intent dialingIntent = new Intent();
dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.ALERTING);
ctx.sendBroadcast(dialingIntent);
Log.d(TAG, ReadLog.CallState.ALERTING);
//已接通,通话建立
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.ACTIVE)) {
//发送广播
Intent dialingIntent = new Intent();
dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.ACTIVE);
ctx.sendBroadcast(dialingIntent);
Log.d(TAG, ReadLog.CallState.ACTIVE);
//断开连接,即挂机
if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)
&& line.contains(ReadLog.CallState.DISCONNECTED)) {
//发送广播
Intent dialingIntent = new Intent();
dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.DISCONNECTED);
ctx.sendBroadcast(dialingIntent);
Log.d(TAG, ReadLog.CallState.DISCONNECTED);
} //END while
} catch (IOException e) {
e.printStackTrace();
} //END try-catch
} //END run
} //END class ReadLog
发送了广播,那么就要有接收者,定义接收者如下(关于录音机的代码可以先忽略):
package com.sdvdxl.
import android.content.BroadcastR
import android.content.C
import android.content.I
import android.util.L
import com.sdvdxl.outgoingcall.OutgoingCallS
public class OutgoingCallReciver extends BroadcastReceiver {
static final String TAG = "Recorder";
private MyR
public OutgoingCallReciver() {
recorder = new MyRecorder();
public OutgoingCallReciver (MyRecorder recorder) {
this.recorder =
public void onReceive(Context ctx, Intent intent) {
String phoneState = intent.getAction();
if (phoneState.equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String phoneNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);//拨出号码
recorder.setPhoneNumber(phoneNum);
recorder.setIsCommingNumber(false);
Log.d(TAG, "设置为去电状态");
Log.d(TAG, "去电状态 呼叫:" + phoneNum);
if (phoneState.equals(OutgoingCallState.ForeGroundCallState.DIALING)) {
Log.d(TAG, "正在拨号...");
if (phoneState.equals(OutgoingCallState.ForeGroundCallState.ALERTING)) {
Log.d(TAG, "正在呼叫...");
if (phoneState.equals(OutgoingCallState.ForeGroundCallState.ACTIVE)) {
if (!recorder.isCommingNumber() && !recorder.isStarted()) {
Log.d(TAG, "去电已接通 启动录音机");
recorder.start();
if (phoneState.equals(OutgoingCallState.ForeGroundCallState.DISCONNECTED)) {
if (!recorder.isCommingNumber() && recorder.isStarted()) {
Log.d(TAG, "已挂断 关闭录音机");
recorder.stop();
其中有这么一段代码:
String phoneState = intent.getAction();
if (phoneState.equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String phoneNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);//拨出号码
recorder.setPhoneNumber(phoneNum);
recorder.setIsCommingNumber(false);
Log.d(TAG, "设置为去电状态");
Log.d(TAG, "去电状态 呼叫:" + phoneNum);
这里是接收系统发出的广播,用于接收去电广播。这样,就获得了去电状态。
3、有了以上主要代码,可以说,来去电监听功能算是完成了,下面创建一个service来运行监听:
package com.sdvdxl.
import android.app.S
import android.content.C
import android.content.I
import android.content.IntentF
import android.os.IB
import android.telephony.PhoneStateL
import android.telephony.TelephonyM
import android.util.L
import android.widget.T
import com.sdvdxl.outgoingcall.OutgoingCallS
import com.sdvdxl.phonerecorder.MyR
import com.sdvdxl.phonerecorder.OutgoingCallR
import com.sdvdxl.phonerecorder.TelL
public class PhoneCallStateService extends Service {
private OutgoingCallState outgoingCallS
private OutgoingCallReciver outgoingCallR
private MyR
public void onCreate() {
super.onCreate();
//------以下应放在onStartCommand中,但2.3.5以下版本不会因service重新启动而重新调用--------
//监听电话状态,如果是打入且接听 或者 打出 则开始自动录音
//通话结束,保存文件到外部存储器上
Log.d("Recorder", "正在监听中...");
recorder = new MyRecorder();
outgoingCallState = new OutgoingCallState(this);
outgoingCallReciver = new OutgoingCallReciver(recorder);
outgoingCallState.startListen();
Toast.makeText(this, "服务已启动", Toast.LENGTH_LONG).show();
IntentFilter outgoingCallFilter = new IntentFilter();
outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.IDLE);
outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.DIALING);
outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.ALERTING);
outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.ACTIVE);
outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.DISCONNECTED);
outgoingCallFilter.addAction("android.intent.action.PHONE_STATE");
outgoingCallFilter.addAction("android.intent.action.NEW_OUTGOING_CALL");
//注册接收者
registerReceiver(outgoingCallReciver, outgoingCallFilter);
TelephonyManager telmgr = (TelephonyManager)getSystemService(
Context.TELEPHONY_SERVICE);
telmgr.listen(new TelListener(recorder), PhoneStateListener.LISTEN_CALL_STATE);
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
public void onDestroy() {
super.onDestroy();
unregisterReceiver(outgoingCallReciver);
Toast.makeText(
this, "已关闭电话监听服务", Toast.LENGTH_LONG)
Log.d("Recorder", "已关闭电话监听服务");
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
注册以下service:
XML/HTML代码
&service android:name="com.sdvdxl.service.PhoneCallStateService" /&
到此为止,来去电状态的监听功能算是完成了,剩下一个录音机,附上录音机代码如下:
package com.sdvdxl.
import java.io.F
import java.io.IOE
import java.text.SimpleDateF
import java.util.D
import android.media.MediaR
import android.os.E
import android.util.L
public class MyRecorder {
private String phoneN
private MediaR
private boolean started = //录音机是否已经启动
private boolean isCommingNumber =//是否是来电
private String TAG = "Recorder";
public MyRecorder(String phoneNumber) {
this.setPhoneNumber(phoneNumber);
public MyRecorder() {
public void start() {
mrecorder = new MediaRecorder();
File recordPath = new File(
Environment.getExternalStorageDirectory()
, "/My record");
if (!recordPath.exists()) {
recordPath.mkdirs();
Log.d("recorder", "创建目录");
String callDir = "呼出";
if (isCommingNumber) {
callDir = "呼入";
String fileName = callDir + "-" + phoneNumber + "-"
+ new SimpleDateFormat("yy-MM-dd_HH-mm-ss")
.format(new Date(System.currentTimeMillis())) + ".mp3";//实际是3gp
File recordName = new File(recordPath, fileName);
recordName.createNewFile();
Log.d("recorder", "创建文件" + recordName.getName());
} catch (IOException e) {
e.printStackTrace();
mrecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mrecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mrecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mrecorder.setOutputFile(recordName.getAbsolutePath());
mrecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
mrecorder.start();
Log.d(TAG , "录音开始");
public void stop() {
if (mrecorder!=null) {
mrecorder.stop();
mrecorder.release();
mrecorder =
} catch (IllegalStateException e) {
e.printStackTrace();
Log.d(TAG , "录音结束");
public void pause() {
public String getPhoneNumber() {
return phoneN
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneN
public boolean isStarted() {
public void setStarted(boolean hasStarted) {
this.started = hasS
public boolean isCommingNumber() {
return isCommingN
public void setIsCommingNumber(boolean isCommingNumber) {
this.isCommingNumber = isCommingN
到此,来去电通话自动录音的所有功能就完成了,大家可以自己试着编写并实现。
以上就是对Android 电话录音的,希望能帮助有需要的朋友,谢谢大家对本站的支持!
以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
电话自动录音
电话路由功能
android 录音功能实现、android实现长按录音、android实现录音、android实现双向录音、html5实现录音功能,以便于您获取更多的相关知识。
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
40+云计算产品,6个月免费体验
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
云服务器9.9元/月,大学必备
云栖社区(yq.aliyun.com)为您免费提供相关信息,包括
,所有相关内容均不代表云栖社区的意见!

我要回帖

更多关于 小生怕怕国语 的文章

 

随机推荐