上接《Android传感器编程入门(二)》

三、实例:窈窈录音器

通过上面的例子我们学会了如何获得某种类型的传感器,下面我通过一个实例来学会如何使用某一个类型的传感器。我们这里使用加速度传感器来实现这样一个功能:开启我们的录音程序放在你的口袋或者提包里,需要录音的时候把衣服整理一下,或者把提包挪动个位置,那么此时手机就会感受到变化从而开始录音。由此达到神不知鬼不觉的录音效果。说起来似乎有点神,其实做起来很简单,让我们开始吧。

简单的录音程序已经在第28讲的时候做过了,我们在28讲程序的基础上写本讲的代码。

1、新建一个项目 Lesson37_YYRecorder , 主文件叫 MainActivity.java ,具体信息都可以参见第二十八讲的“窈窈录音”的例子。

001

  1. package basic.android.lesson37;
  2. 002
  3. 003
  4. import java.io.File;
  5. 004
  6. import java.io.IOException;
  7. 005
  8. import java.util.Calendar;
  9. 006
  10. import java.util.Locale;
  11. 007
  12. 008
  13. import android.app.Activity;
  14. 009
  15. import android.content.Context;
  16. 010
  17. import android.hardware.Sensor;
  18. 011
  19. import android.hardware.SensorEvent;
  20. 012
  21. import android.hardware.SensorEventListener;
  22. 013
  23. import android.hardware.SensorManager;
  24. 014
  25. import android.media.MediaRecorder;
  26. 015
  27. import android.os.Bundle;
  28. 016
  29. import android.text.format.DateFormat;
  30. 017
  31. import android.view.View;
  32. 018
  33. import android.widget.Button;
  34. 019
  35. import android.widget.TextView;
  36. 020
  37. import android.widget.Toast;
  38. 021
  39. 022
  40. public class MainActivity extends Activity {
  41. 023
  42. 024
  43. //录音和停止按钮
  44. 025
  45. private Button recordButton;
  46. 026
  47. private Button stopButton;
  48. 027
  49. 028
  50. //检测摇动相关变量
  51. 029
  52. private long initTime = 0;
  53. 030
  54. private long lastTime = 0;
  55. 031
  56. private long curTime = 0;
  57. 032
  58. private long duration = 0;
  59. 033
  60. 034
  61. private float last_x = 0.0f;
  62. 035
  63. private float last_y = 0.0f;
  64. 036
  65. private float last_z = 0.0f;
  66. 037
  67. 038
  68. private float shake = 0.0f;
  69. 039
  70. private float totalShake = 0.0f;
  71. 040
  72. 041
  73. //媒体录音器对象
  74. 042
  75. private MediaRecorder mr;
  76. 043
  77. 044
  78. //是否正在录音
  79. 045
  80. private boolean isRecoding = false;
  81. 046
  82. 047
  83. @Override
  84. 048
  85. public void onCreate(Bundle savedInstanceState) {
  86. 049
  87. super.onCreate(savedInstanceState);
  88. 050
  89. setContentView(R.layout.main);
  90. 051
  91. 052
  92. // UI组件
  93. 053
  94. recordButton = (Button) this.findViewById(R.id.Button01);
  95. 054
  96. stopButton = (Button) this.findViewById(R.id.Button02);
  97. 055
  98. final TextView tx1 = (TextView) this.findViewById(R.id.TextView01);
  99. 056
  100. 057
  101. // 录音按钮点击事件
  102. 058
  103. recordButton.setOnClickListener(new View.OnClickListener() {
  104. 059
  105. 060
  106. @Override
  107. 061
  108. public void onClick(View v) {
  109. 062
  110. //如果没有在录音,那么点击按钮可以开始录音
  111. 063
  112. if(!isRecoding){
  113. 064
  114. startRecord();
  115. 065
  116. }
  117. 066
  118. }
  119. 067
  120. });
  121. 068
  122. 069
  123. // 停止按钮点击事件
  124. 070
  125. stopButton.setOnClickListener(new View.OnClickListener() {
  126. 071
  127. 072
  128. @Override
  129. 073
  130. public void onClick(View v) {
  131. 074
  132. initShake();
  133. 075
  134. //如果正在录音,那么可以停止录音
  135. 076
  136. if (mr != null) {
  137. 077
  138. mr.stop();
  139. 078
  140. mr.release();
  141. 079
  142. mr = null;
  143. 080
  144. recordButton.setText("录音");
  145. 081
  146. Toast.makeText(getApplicationContext(), "录音完毕", Toast.LENGTH_LONG).show();
  147. 082
  148. isRecoding = false;
  149. 083
  150. 084
  151. }
  152. 085
  153. }
  154. 086
  155. });
  156. 087
  157. 088
  158. // 获取传感器管理器
  159. 089
  160. SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
  161. 090
  162. // 获取加速度传感器
  163. 091
  164. Sensor acceleromererSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  165. 092
  166. 093
  167. // 定义传感器事件监听器
  168. 094
  169. SensorEventListener acceleromererListener = new SensorEventListener() {
  170. 095
  171. 096
  172. @Override
  173. 097
  174. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  175. 098
  176. //什么也不干
  177. 099
  178. }
  179. 100
  180. 101
  181. //传感器数据变动事件
  182. 102
  183. @Override
  184. 103
  185. public void onSensorChanged(SensorEvent event) {
  186. 104
  187. 105
  188. //如果没有开始录音的话可以监听是否有摇动事件,如果有摇动事件可以开始录音
  189. 106
  190. if(!isRecoding){
  191. 107
  192. //获取加速度传感器的三个参数
  193. 108
  194. float x = event.values[SensorManager.DATA_X];
  195. 109
  196. float y = event.values[SensorManager.DATA_Y];
  197. 110
  198. float z = event.values[SensorManager.DATA_Z];
  199. 111
  200. 112
  201. //获取当前时刻的毫秒数
  202. 113
  203. curTime = System.currentTimeMillis();
  204. 114
  205. 115
  206. //100毫秒检测一次
  207. 116
  208. if ((curTime - lastTime) > 100) {
  209. 117
  210. 118
  211. duration = (curTime - lastTime);
  212. 119
  213. 120
  214. // 看是不是刚开始晃动
  215. 121
  216. if (last_x == 0.0f && last_y == 0.0f && last_z == 0.0f) {
  217. 122
  218. //last_x、last_y、last_z同时为0时,表示刚刚开始记录
  219. 123
  220. initTime = System.currentTimeMillis();
  221. 124
  222. } else {
  223. 125
  224. // 单次晃动幅度
  225. 126
  226. shake = (Math.abs(x - last_x) + Math.abs(y - last_y) + Math.abs(z - last_z)) / duration * 100;
  227. 127
  228. }
  229. 128
  230. 129
  231. //把每次的晃动幅度相加,得到总体晃动幅度
  232. 130
  233. totalShake += shake;
  234. 131
  235. 132
  236. // 判断是否为摇动,这是我自己写的标准,不准确,只是用来做教学示例,别误会了^_^
  237. 133
  238. if (totalShake > 10 && totalShake / (curTime - initTime) * 1000 > 10) {
  239. 134
  240. startRecord();
  241. 135
  242. initShake();
  243. 136
  244. }
  245. 137
  246. 138
  247. tx1.setText("总体晃动幅度="+totalShake+ "\n平均晃动幅度="+totalShake / (curTime - initTime) * 1000 );
  248. 139
  249. }
  250. 140
  251. 141
  252. last_x = x;
  253. 142
  254. last_y = y;
  255. 143
  256. last_z = z;
  257. 144
  258. lastTime = curTime;
  259. 145
  260. }
  261. 146
  262. }
  263. 147
  264. 148
  265. };
  266. 149
  267. 150
  268. //在传感器管理器中注册监听器
  269. 151
  270. sm.registerListener(acceleromererListener, acceleromererSensor, SensorManager.SENSOR_DELAY_NORMAL);
  271. 152
  272. 153
  273. }
  274. 154
  275. 155
  276. // 开始录音
  277. 156
  278. public void startRecord() {
  279. 157
  280. //把正在录音的标志设为真
  281. 158
  282. isRecoding = true;
  283. 159
  284. //存放文件
  285. 160
  286. File file = new File("/sdcard/" + "YY"
  287. 161
  288. + new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".amr");
  289. 162
  290. 163
  291. Toast.makeText(getApplicationContext(), "正在录音,录音文件在" + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
  292. 164
  293. 165
  294. // 创建录音对象
  295. 166
  296. mr = new MediaRecorder();
  297. 167
  298. 168
  299. // 从麦克风源进行录音
  300. 169
  301. mr.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
  302. 170
  303. 171
  304. // 设置输出格式
  305. 172
  306. mr.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
  307. 173
  308. 174
  309. // 设置编码格式
  310. 175
  311. mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
  312. 176
  313. 177
  314. // 设置输出文件
  315. 178
  316. mr.setOutputFile(file.getAbsolutePath());
  317. 179
  318. 180
  319. try {
  320. 181
  321. // 创建文件
  322. 182
  323. file.createNewFile();
  324. 183
  325. // 准备录制
  326. 184
  327. mr.prepare();
  328. 185
  329. } catch (IllegalStateException e) {
  330. 186
  331. e.printStackTrace();
  332. 187
  333. } catch (IOException e) {
  334. 188
  335. e.printStackTrace();
  336. 189
  337. }
  338. 190
  339. // 开始录制
  340. 191
  341. mr.start();
  342. 192
  343. recordButton.setText("录音中……");
  344. 193
  345. }
  346. 194
  347. 195
  348. //摇动初始化
  349. 196
  350. public void initShake() {
  351. 197
  352. lastTime = 0;
  353. 198
  354. duration = 0;
  355. 199
  356. curTime = 0;
  357. 200
  358. initTime = 0;
  359. 201
  360. last_x = 0.0f;
  361. 202
  362. last_y = 0.0f;
  363. 203
  364. last_z = 0.0f;
  365. 204
  366. shake = 0.0f;
  367. 205
  368. totalShake = 0.0f;
  369. 206
  370. }
  371. }

3、连接真机Milestone,编译并运行程序:

晃动机器,开始录音

查看录音文件,效果还可以:

4、我们小结一下:

到Android2.2版本为止,系统并没有给开发者提供多少可用的包装好的传感器信息,只是提供了传感器发出的原始数据,这些原始数据存放在  event.values 的数组里,开发人员需要从这些裸数据总自行发掘有用的信息,譬如从加速度传感器的3维裸数据中获得摇动的判断(我的摇动判断很弱智,有时间再改吧……)。

好了本讲就先到这里,关于传感器有机会我们展开再谈,下次再见吧。

转载于:https://blog.51cto.com/zhangyan1158/453445

Android传感器编程入门(三)相关推荐

  1. Android传感器编程入门

    一.前言 我很喜欢电脑,可是笔记本还是太大,笔记本电脑再小还是要弄个小包背起来的,智能手机则不同,它完全就是一个手机,可以随意装在一个口袋里随身携带.因此我在2002年左右时最喜欢玩装备是Dell的P ...

  2. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    为什么80%的码农都做不了架构师?>>>    本文原作者:"竹千代",原文由"玉刚说"写作平台提供写作赞助,原文版权归"玉刚说&q ...

  3. Android 4编程入门经典—开发智能手机与平板电脑应用

    Android 4编程入门经典 书名: Android 4编程入门经典 原书名: Beginning  Android 4 Application Development 重点指数 畅销书 作者: ( ...

  4. .Net 3.5 Remoting编程入门三

    VS2008 .Net 3.5 Remoting编程入门三 信道 什么是信道?信道有哪些类型呢? 信道顾名思意就是通信的通道.就想那些宣传标语说的,"要想富,先修路!".同理,要学 ...

  5. 《Android游戏编程入门经典》——1.7节小结

    本节书摘来自异步社区<Android游戏编程入门经典>一书中的第1章,第1.7节小结,作者[美]Jonathan S. Harbour,更多章节内容可以访问云栖社区"异步社区&q ...

  6. 免费分享:5本安卓开发经典书籍,Android 7编程入门经典(第4版),Android底层驱动分析和移植,底层驱动分析和移植

    1.Android 7编程入门经典(第4版) 使用Android Studio 2  PDF 下载 下载地址: http://www.askwinds.com/r-c/down-info-02/579 ...

  7. 《Android游戏编程入门经典》——1.1节Android 4简介

    本节书摘来自异步社区<Android游戏编程入门经典>一书中的第1章,第1.1节Android 4简介,作者[美]Jonathan S. Harbour,更多章节内容可以访问云栖社区&qu ...

  8. Android 4编程入门经典 开发智能手机与平板电脑

    查看书籍详细信息: Android 4编程入门经典--开发智能手机与平板电脑-- 编辑推荐 Wei-Meng Lee 最新作品,国内首本译著android 4入门宝典 内容简介 Android 4的问 ...

  9. Android网络编程入门解析

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

最新文章

  1. 零基础python从入门到精通 pdf-跟老齐学Python:从入门到精通PDF电子版
  2. jquery $.trim()方法使用介绍
  3. linux系统用户迁移
  4. ubuntu 14.04 将窗体button移到右边
  5. php公众号客服消息图文,微信公众号开发系列-发送客服消息(示例代码)
  6. asp.net 登录验证 mysql_Asp.net mvc验证用户登录之Forms实现详解
  7. Android 系统(252)---Android:BLE智能硬件开发详解
  8. 自动驾驶——标注工具的开发笔记(legacy)
  9. yml连接sqlserver_Mybatis-plus连接操作SQLServer数据库(基于Maven项目)
  10. 6寸照片的尺寸是多少_各类证件照标准尺寸大全
  11. HeadFirstJava
  12. hive下载安装与配置
  13. Android扫描局域网内所有的ip地址
  14. IR2104与IR2103区别
  15. 怎么给图片加边框线?图片加边框的方法
  16. 简单酷炫css3动画效果,CSS3使用Animate.css制作超炫的动画效果
  17. Filter_过滤器
  18. html css js知识整理,Html+Css+Js实用知识汇总(持续更新中...)
  19. 魔乐科技安卓开发教程----李兴华----06PendingIntent
  20. opencv 脸部识别_实时面部识别如何与OpenCV一起使用?

热门文章

  1. 苹果 “Find My” 功能中的漏洞可暴露用户的位置信息
  2. KindleDrip:从邮件地址到信用卡盗刷的严重漏洞,值$1.8万奖金
  3. 奇安信代码安全实验室帮助谷歌修复 Chrome 沙箱外高危漏洞,获官方致谢
  4. java版b2b2c社交电商spring cloud分布式微服务-服务提供与调用
  5. Ogre 3d 工具集
  6. 动态传参, 名称空间, 嵌套, gloabal, nonlocal
  7. ZABBIX 3.2.7 (源码包)安装部署
  8. python 调用 C++ code
  9. Debian 7 Gitlab `GLIBC_2.14 not found`
  10. 2010-2014总结 ____V_V____ hello-world