`
stephen830
  • 浏览: 3010638 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

[Android实例]通话接通后震动提示

 
阅读更多

[Android实例]通话接通后震动提示

 

转载自 http://blog.csdn.net/tyfjy/article/details/6452126

 

今天介绍一下在Android 中实现通话接通后震动提示, 这里通话主要是针对拨出的电话. 想要在接通的时候给出震动提示那么我们就需要知道通话何时是被接通的. 这样才能在进入该状态后给出提示.SDK 中并没有直接获得这种状态的方式. 首先我们看一下SDK 中电话服务类为我们提供了哪些通话状态.

SDK 中的TelephonyManager 类提供了3 种电话的状态.

CALL_STATE_IDLE 空闲状态

CALL_STATE_OFFHOOK 摘机状态

CALL_STATE_RINGING  响铃状态

这几个状态很容易理解, 其中摘机状态即拿起话筒( 对于座机电话而言的动作), 但这个状态可能发生在拨入电话接通时, 也可能是拨出电话时. 但是却不能说明拨出电话接通时. 通过以上3 种状态我们仅能组合出: 挂机, 来电接通. 这两个状态. 而今天我们要实现的功能却无法做到.

看来我们需要寻找其他方法来实现了,SDK 靠不住啊……

 

还好Android 在运行时会有大量的log 产生, 看看我们能不能从这上面找到突波口呢. 我们选择AndroidRadio 模块的日志来分析. 首先我们需要写一段代码来读取Radio 相关的log. 读取log 就不得不用到logcat.

 

	Process process;
		InputStream inputstream;
		BufferedReader bufferedreader;
		try {
			process = Runtime.getRuntime().exec("logcat -v time -b radio");
			inputstream = process.getInputStream();
			InputStreamReader inputstreamreader = new InputStreamReader(
					inputstream);
			bufferedreader = new BufferedReader(inputstreamreader);
	String str = "";
while ((str = bufferedreader.readLine()) != null) {
       log.i("mLogcat",str);
}
} catch (Exception e) {
			
		}
 

另外,要让程序能够读取系统log需要指定权限,在AndroidManifest.xml文件中加入一下内容.

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

 

通过上面这段代码我们就可以将Radiolog 输出到了, 这样我们就可以通过在DDMS 中查看这些log, 分析其中的通话过程. 具体抓到的log 就不贴出来了. 大家可以自己编写程序通过上面的代码来抓取和分析. 我只说一下我的分析结果.

通过分析log 发现了一些蛛丝马迹. 其中有几条日志很有用.

GET_CURRENT_CALLS  id=1,DIALING

GET_CURRENT_CALLS  id=1,ALERTING

GET_CURRENT_CALLS  id=1,ACTIVE

由于log 较长我只拿了每条log 的开头部分, 真实的会多很多内容. 当我们拨出电话的时候, 会输入这么几条log.

拨号-> 提醒-> 活动.

 

大致是这么个过程. 经过几次测试发现, 电话接通时会进入活动状态, 并会输出:GET_CURRENT_CALLS  id=1,ACTIVE  这条log, 至此我们已经接近成功了.

不过之后我又发现在拨号开始到电话接通这段时间内会经过多次的

拨号-> 提醒-> 活动, 这样的状态变化, 仅当话筒中嘟声响起后GET_CURRENT_CALLS 这条日志会锁定在ALERTING. 在电话接通前便不再出现

GET_CURRENT_CALLS 日志了.

可能上面的这段表述大家不是很清楚, 换句话说在通话接通之前会出现多次的

GET_CURRENT_CALLS ACTIVE 这样的日志, 而仅有一次是电话接通产生的. 这就给我们造成了麻烦. 不能只是单纯的抓取GET_CURRENT_CALLS ACTIVE 这样的信息来判断了.

我们只能通过一些逻辑上的判断来实现了.下面看我的代码.

class TestThread implements Runnable {
	//振动器
	Vibrator mVibrator;
	//电话服务
	TelephonyManager telManager;
	public TestThread(Vibrator mVibrator, TelephonyManager telManager) {
		this.mVibrator = mVibrator;
		this.telManager = telManager;
	}
	@Override
	public void run() {
		//获取当前话机状态
		int callState = telManager.getCallState();
		Log.i("TestService", "开始.........." + Thread.currentThread().getName());
		//记录拨号开始时间
		long threadStart = System.currentTimeMillis();
		Process process;
		InputStream inputstream;
		BufferedReader bufferedreader;
		try {
			process = Runtime.getRuntime().exec("logcat -v time -b radio");
			inputstream = process.getInputStream();
			InputStreamReader inputstreamreader = new InputStreamReader(
					inputstream);
			bufferedreader = new BufferedReader(inputstreamreader);
			String str = "";
			long dialingStart = 0;
			boolean enableVibrator = false;
			boolean isAlert = false;
			while ((str = bufferedreader.readLine()) != null) {
				//如果话机状态从摘机变为空闲,销毁线程
				if (callState == TelephonyManager.CALL_STATE_OFFHOOK
						&& telManager.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
					break;
				}
				// 线程运行5分钟自动销毁
				if (System.currentTimeMillis() - threadStart > 300000) {
					break;
				}
				Log.i("TestService", Thread.currentThread().getName() + ":"
						+ str);
				// 记录GSM状态DIALING
				if (str.contains("GET_CURRENT_CALLS")
						&& str.contains("DIALING")) {
					// 当DIALING开始并且已经经过ALERTING或者首次DIALING
					if (!isAlert || dialingStart == 0) {
						//记录DIALING状态产生时间
						dialingStart = System.currentTimeMillis();
						isAlert = false;
					}
					continue;
				}
				if (str.contains("GET_CURRENT_CALLS")
						&& str.contains("ALERTING")&&!enableVibrator) {
					
					long temp = System.currentTimeMillis() - dialingStart;
					isAlert = true;
					//这个是关键,当第一次DIALING状态的时间,与当前的ALERTING间隔时间在1.5秒以上并且在20秒以内的话
					//那么认为下次的ACTIVE状态为通话接通.
					if (temp > 1500 && temp < 20000) {
						enableVibrator = true;
						Log.i("TestService", "间隔时间....." + temp + "....."
								+ Thread.currentThread().getName());
					}
					continue;
				}
				if (str.contains("GET_CURRENT_CALLS") && str.contains("ACTIVE")
						&& enableVibrator) {
					mVibrator.vibrate(100);
					enableVibrator = false;
					break;
				}
			}
			Log.i("TestService", "结束.........."
					+ Thread.currentThread().getName());
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
}

 

我的这个方法比较牵强,是通过判断第一次DIALING与每一次ALERTING之间的间隔,当间隔大于1.5秒.那么认为已经进入了"嘟"声提示 的时候了,那么下一个ACTIVE将是电话接通.这个1.5秒是通过分析日志得出的.但是这种方法我始终觉得不太靠谱.如果大家有好的方法可以交流交流.

剩下的就是让这个线程在电话拨出时触发,并且常驻在电话中时候准备这就可以了.可以采用Service配合Receiver来实现.Service来实现常驻,Receiver来实现监听拨出电话.基本就可以完成,我们想要的功能了.

以上代码我都测试过99%有效,哈哈.这里面提到了一些Android的基础内容像logcat,Service,Receiver.这些如果大家不了解的话可以到网上搜一下.有很多写的很不错的文章介绍Android的基础内容.我这里就不一一介绍了.

希望我写的东西对大家有所帮助.OK,就到这里吧.

 

 

 

 

分享到:
评论

相关推荐

    Android 视频通话demo

    在Android平台上,开发一款视频通话应用是一项复杂但充满挑战性的任务。腾讯云视频SDK为开发者提供了便捷的工具,使得这一过程变得更为顺畅。本篇将深入解析基于腾讯云视频SDK的Android视频通话demo,帮助你理解和...

    [Android实例] Android 竖着的SeekBar

    android[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] Android 竖着的SeekBar[Android实例] ...

    Android 通话双向录音

    在Android平台上实现通话双向录音是一项技术挑战,因为涉及到系统权限、音频流的处理以及与通话服务的交互。本文将深入探讨如何在Android设备上实现这一功能,并提供相关的知识点。 首先,我们要了解Android的权限...

    android 视频通话实例源码

    android 视频通话 实例源码,采用网易云信sdk开发,开发环境idea.

    [Android实例] 面试题集

    android[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] 面试题集[Android实例] ...

    Android实例开发完全手册 pdf

    全书分为16个章,分别讲解了UI布局实例、控件实例、自动化服务实例、数据存储实例、电话和短信实例、图形图像实例和网络有关的实例,以及多媒体实例、Google地图实例。Google API实例、平板电脑应用开发、游戏应用、...

    android 实例源码 集合

    在Android开发领域,掌握实例源码是提升技能和理解系统工作原理的重要途径。"android 实例源码 集合" 提供了多种Android应用程序的源代码,这为我们提供了宝贵的参考资源,帮助开发者深入理解Android应用开发的各种...

    android通话时间统计器[实例,源代码].rar

    本实例提供了一个完整的源代码实现,这为我们提供了深入理解Android应用程序开发,特别是通话记录相关API的使用,以及如何处理用户数据的机会。 首先,Android的通话时间统计器应用通常会集成到系统的电话服务中,...

    Android通话记录开发

    2、 练习目标 ... 使用广播处理处理事件 3、 需求分析 手机最重要的功能就是通话功能,同样储存通话记录也是必不可少的。该案例使用广播接收者自己实现通话记录...包括呼出电话、已接来电、未接来电以及通话产生的时间。

    Android实例开发完全手册

    Android实例开发完全手册

    Android实例helloworld

    Android实例helloworldAndroid实例helloworldAndroid实例helloworldAndroid实例helloworldAndroid实例helloworldAndroid实例helloworldAndroid实例helloworld

    基于Android平台下的通话录音软件,帮助用户轻松实现通话录音和留言录音

    开发者需要监听电话状态,当电话接通时启动录音服务,挂断时停止录音。这可以通过注册BroadcastReceiver监听`TelephonyManager`的电话状态变化来实现。录音过程则可以通过AudioRecord类来完成,设置合适的音频源...

    android震动传感器之摇一摇

    在Android平台上,开发一个“摇一摇”功能的应用程序,主要涉及到的是设备的传感器技术,尤其是加速度计和震动传感器。下面将详细讲解这个过程涉及的技术点。 首先,我们需要了解Android系统的传感器框架。Android...

    精通ANDROID实例开发.part1

    精通ANDROID实例开发.part1 由于上传限制,此书籍采用分卷压缩,需要与 精通ANDROID实例开发.part2一起才能正常解压使用

    基于Android调用OpenAI接口的ChatGPT实例.zip

    基于Android调用OpenAI接口的ChatGPT实例基于Android调用OpenAI接口的ChatGPT实例 基于Android调用OpenAI接口的ChatGPT实例基于Android调用OpenAI接口的ChatGPT实例 基于Android调用OpenAI接口的ChatGPT实例基于...

    android实例开发完全手册

    《Android实例开发完全手册》是一本深度探讨Android应用开发的实战型书籍,旨在通过丰富的实例帮助读者掌握Android开发的核心技术和实践技巧。这本书涵盖了从基础到高级的各个方面,为开发者提供了全面的学习路径。 ...

    Android实现监听电话呼叫状态的方法

    // 当电话接通时,用户正在通话 break; case TelephonyManager.CALL_STATE_RINGING: // 当电话响铃,有来电时 break; default: break; } super.onCallStateChanged(state, incomingNumber); } }; ``` 在这...

    分享45个android实例源码.pdf

    "分享45个android实例源码.pdf" Android实例源码是Android应用程序开发中非常重要的一部分。通过分享45个Android实例源码,我们可以学习和掌握Android应用程序开发的各种技术和技巧。 首先,让我们来看一下...

    Android串口通信实例

    这个“Android串口通信实例”项目是基于Android Studio的一个实战项目,已经过测试,能够有效地执行串口的各种操作,如配置、开启、发送和接收数据。下面将详细讲解Android串口通信的相关知识点。 1. **Android串口...

Global site tag (gtag.js) - Google Analytics