第一篇:Android录音MediaRecorderAudioRecorder相关总结
Android录音MediaRecorderAudioRecorder相关总结
这学期,笔者在制作一款Android音乐应用中需要用到录音功能,将MediaRecorder与AudioRecorder总结如下,如有纰误,望包涵并纠正。
一、MediaRecorder使用MediaRecorder进行声音录制简单方便,不需要理会中间录制过程。结束录制后可以直接得到音频文件进行播放。由于MediaRecorder较为简单,就不详细介绍,各位看官可自行搜索并试验。可参考如下博客:Android MediaRecorder录制音频:http://aina-hk55hk.iteye.com/blog/706793Andriod MediaRecorder小结:http://Android MediaRecorder框架介绍:http://forest606.blog.163.com/blog/static/***102834914/
二、AudioRecorder在声音录制过程中,有可能我们需要得到采集的声音数据并进行处理,比如降噪,合成等。MediaRecorder明显不能符合要求。而AudioRecorder恰能满足这种要求。过程为一段一段进行录制然后得到数据分别进行处理。AudioRecorder可以有2种处理方式:
1.设置AudioRecorder的UpdateListener和NotificationPeriod [java] view plaincopyaudioRecorder.setRecordPositionUpdateListener(updateListener);
audioRecorder.setPositionNotificationPeriod(framePeriod);
然后在UpdateListener中进行处理。2.另外开启一线程得到录制数据然后进行处理第一种方式简单明了,是在主线程中处理,可以很方便的进行其他操作,如更新UI。但实际使用过程中发现,即使没有进行其他操作也会造成程序崩溃,所以不推荐使用。
第二种方式较为麻烦,特别是需要在子线程中更新UI。但是效果很好。2种方式示例代码如下:1.UpdateListener[java] view plaincopyprivate AudioRecord.OnRecordPositionUpdateListener updateListener = new AudioRecord.OnRecordPositionUpdateListener()
{
private int x = 0;
public void onPeriodicNotification(AudioRecord recorder)
{
audioRecorder.read(buffer, 0, buffer.length);// Fill buffer
try
{
//randomAccessWriter.write(buffer);// Write buffer to file
//payloadSize += buffer.length;
if(bSamples == 16)
{
for(int i=0;i { // 16bit sample size short curSample = ExtAudioRecorder.this.getShort(buffer[2*i], buffer[2*i+1]); if(curSample > cAmplitude) { // Check amplitude cAmplitude = curSample; } } } else { // 8bit sample size for(int i=0;i { if(buffer[i] > cAmplitude) { // Check amplitude cAmplitude = buffer[i]; } } } } catch(Exception e) { Log.e(ExtAudioRecorder.class.getName(), “Error occured in updateListener, recording is aborted”); //stop(); } if(x%4 == 0) { mDrawingView.getEditingLayer().addSquare(x/4, 19(int)((cAmplitude/65535.0f)*19))); messageHandler.sendMessage(message); } } } Android四大组件: Activity—表现屏幕界面 Service—后台服务 BroadcastReceiver—实现广播机制 ContentProvider—实现数据存储 Intent类:用来启动程序并传递信息的类 用于Activity、Receiver、Service之间进行交互的类,通过无参构造方法创建对象,增加其action、category、data、extra等属性进行信息传递,并通过Activity中的startActivity(Intent intent)进行界面的跳转;通过Context中的StartService(Intent intent)进行服务跳转;通过Context中的registerReceive(Intent intent)对广播进行注册,并通过sendBroadcast()进行无序消息发送,或可以通过SendOrderedBroadcast()进行有序的消息发送。Handler类: 用来发送和处理消息,并配合主线程完成UI的更新;消息Message/Runnable传递通过MessageQueue(消息队列,先进先出)进行传递,并通过Lopper进行接收,传递的消息可以为Message对象,也可以是Runnable对象;接收方法通过HandleMessage(Message msg)进行获取。SharedPreferences类: 一般用于第一次登录时的设置,或者是各个界面的一些小型格式设置,如字体等。是本地的小型共享数据库,可以通过Context的静态方法getSharedPreferences获得其对象,对象内的值均为键值对进行储存。通过SharedPreferences对象调用editor()获取SharedPreferences.Editor对象,向共享数据库中增加数据,putString(),并提交数据,commit();通过SharedPreferences对象获取共享数据库中的数据,getString()。 ViewPager:实现界面滑动的类; 通过设置OnPagerChangedListener设置ViewPager的监听事件; 实现流程: ①布局文件中设置ViewPager控件; ②代码中进行绑定控件; ③通过继承PagerAdapter抽象类进行设置适配器,并传递数据源; ④适配器中实现两个抽象方法,两个重写方法:getCount()—获取滑动界面的数量,isViewFromObject()—判断视图是否是来自于Object文件中;重写两个方法,分别为destoryItem—销毁指定位置的视图;InstantiateItem(),设置指定位置的视图; Timer与TimerTask类: Timer为计时器的类,通过无参构造方法可以获取对象,通过Timer.schedule(TimerTask task,long time)进行设置多久后执行某任务,当任务执行完后,取消计时的功能,Timer.cancle();TimerTask类为抽象类,实例化时,必须重写run方法;执行的内容,均在run方法中进行设置,并且执行时,已在子线程中进行执行。自定义View:用到的类有Paint、Canvas、Spec、SpecF、Path、View.MeasureSpec、Timer、TimerTask; 抽象类,通过子类继承,获取对象;在布局文件中绑定后,通过代码,设置自定义View的属性;自定义View中,通过重写OnMeasure方法,对布局文件中的尺寸进行测量,并由View中的setMeasureDimenson()方法,进行数据的保存;通过重写Ondraw方法,进行绘图;当需要绘制动态图形时,使用计时器Timer的schedule(TimerTask,long time,delay time2)方法,在time时间后,每隔time2时间,重写执行run方法中的内容;将耗时的操作设置在run方法中,并通过View中的invalidate()方法刷新主线程中的绘的图形,通过postInvalidate()刷新子线程中的图形。数据库: 常用的数据库有Oracle,需要安装和配置的大型收费数据库;MySQL是中型数据库,同样需要安装配置,但不需要收费;Sqlite是小型免费的嵌入式数据库,占用内存低,最新版本为3.0。Sqlite数据库需要通过SqliteDatabaseOpenHelper进行创建数据库,并通过SqliteDatabase进行数据库的操作。辅助类是抽象类,通过继承,重写两个方法,并在子类的构造方法中通过OpenHelper的构造方法(Context context,String SqlName,SqliteDatabase.CursorFactory factory,int version)进行数据库的创建,在onCreate方法中,进行数据库表的创建,在onUpdate中进行数据库的版本更新。在数据库的操作类中,执行exect方法,通过sql语句对数据库进行操作。Create table student(_id integer primary key auto increament ,name text);insert into student(_id,name)values(1,zx);delete from student where _id=1;update student set _id=2 where name=zx;select *from student;ListView、GridView适配器的优化: 将布局文件中的控件进行封装,当视图加载时,判断可变视图是否存在,当不存在时,通过布局文件获取视图,并新建封装类,将地址通过setTag()进行发送;当视图存在时,重复利用地址—getTag()。反射: 存储数据的方式: 共享数据库、数据库、文件、网络、内容提供者 广播: 广播传播时,需要接收者、发送者、广播频道;根据发送者的发送方式不同,分为有序广播、无序广播;有序广播为接收者有接收顺序,根据设置的优先级不同,确定先后顺序,接收者同时也是发送者,向后面的广播发送消息,发送过程中,可以添加信息,也可以停止广播的传输;无序广播,接收者之间无联系,均从发送者处接收信息;广播在传输过程中,不能被添加信息,也不可能被停止。广播在发送前,需要对接收者进行注册,注册方式有两种,动态注册、静态注册。动态注册,是在代码中进行,通过Context对象调用静态方法进行注册,所有的广播均可以用动态注册,其生命周期依赖于应用,相对于静态注册,比较节省内存;静态方法在清单文件中进行注册,部分系统广播不能通过静态注册进行,其生命周期依赖于系统,当系统启动,即运行接收广播,较耗内存。广播接收者需要继承BroadcastReceiver,并实现抽象方法onReceive(),通过回调接口,进行数据的传输。注意:广播发送前,必须进行接收者的注册,并且,当显示跳转时,不需要意图过滤器。安卓布局:九种布局 线性布局,水平或垂直方向两种格式,主要特点为权重,即规定各控件在视图中的占有的比例; 相对布局,相对于父控件或兄弟控件的布局,各控件需指定相对位置; 绝对布局,指定各控件在视图中的绝对位置,几乎不再使用; 表格布局,子布局放在行中,列由控件表示(TableRow); 帧布局:覆盖前面布局的布局,一般用于暂停按钮等; 风格布局:可以跨行、跨列的布局,占满换行; 左右侧滑:可以实现左右侧滑,通过设置主菜单和二级菜单设置左右两个菜单; 下拉刷新:设置下拉刷新、上拉加载的功能; 抽屉布局; 安卓版本及对应的API: 1.6—4;2—7;3—11;4—15;4.3—18;5—20;5.1—21;6—23;7—25; 安卓四层架构: 应用层:Java语言开发,主要从事App开发; 运行库层:Java语言与C语言,View视图、管理类等的开发; 架构层:C语言与Linux语言,各种框架、浏览器等; 内核层:Linux、C语言,开发各种驱动; 安卓四大组件: Activity:界面,实现程序与用户之间的交换,有自己的生命周期,七个生命周期;4种启动模式 Service: BroadcastReceive:三要素,发送者、接收者、发送频道(Intent);类型:有序(接收有序,有数据传送,可以拦截数据)、无序广播(相对);注册方式:静态注册,持久监听,占用内存比较高生命周期跟随系统,动态注册(代码中),所有广播都可以动态注册,部分系统广播不能动态注册,临时监听,占用内存较少,生命周期随应用进行; ContentProvide:不能存放数据,五种存放数据方式之一,特点为:①为数据的获取等操作添加一个统一的接口②可以实现跨应用访问数据;③可以实现Android中通讯录、消息、音频、视频等的访问或操作;通过ContentReceive进行数据的访问,可以对数据进行增删改查操作。 动画: IO流: 序列化: AlertDialog: Set实现类: 手机电量检测: 自定义SurfaceView: 自定义View:三个构造方法的区别 Message:Handler.obtain/new/Message.obtain HttpUriConnection访问网络 gride 异步任务 动画 抽象类和接口 反射 克隆 序列化 侧滑的实现 数据库 Socket: Gson解析 异步任务和子线程区别 WebView 版本更新 照片的圆角化 Collection与Collections Sql语句 MVP框架与MVC: TCP与UDP的区别: 一键分享的流程: Http协议的理解: 不使用框架访问网络: List集合与set集合: 自定义View的流程: 线性布局的特点: ViewPager的原理: 服务的启动方式: Activity的启动方式: Xml数据解析: Android WebView总结 1、添加权限:AndroidManifest.xml中必须使用许可“Android.permission.INTERNET”,否则会出web page not available错误。 2、在要Activity中生成一个WebView组件:WebView webView = new WebView(this); 3、设置WebView基本信息: 如果访问的页面中有Javascript,则webview必须设置支持Javascript。 webview.getSettings().setJavaScriptEnabled(true); 触摸焦点起作用 requestFocus(); 取消滚动条 this.setScrollBarStyle(SCROLLBARS_OUTSIDE_OVERLAY); 4、设置WevView要显示的网页: 互联网用:webView.loadUrl("");本地文件存放在:assets文件中 5、如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。给WebView添加一个事件监听对象(WebViewClient) 并重写其中的一些方法 shouldOverrideUrlLoading:对网页中超链接按钮的响应。 当按下某个连接时WebViewClient会调用这个方法,并传递参数:按下的url onLoadResource onPageStart onPageFinish onReceiveError onReceivedHttpAuthRequest6、如果用webview点链接看了很多页以后,如果不做任何处理,点击系统“Back”键,整个浏览器会调用finish()而结束自身,如果希望浏览的网页回退而不是退出浏览器,需要在当前Activity中处理并消费掉该Back事件。 覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法。 public boolean onKeyDown(int keyCoder,KeyEvent event){ if(webView.canGoBack()&& keyCoder == KeyEvent.KEYCODE_BACK){ webview.goBack();//goBack()表示返回webView的上一页面 return true; } return false; } 一、Android开发环境的搭建。 1、Android SDK的安装; 2、ADT的安装和配置; 3、Android 模拟器的配置。 二、编写第一个Android程序───Hello World(1学时) 1、创建一个Android应用程序的步骤; 2、Android 应用程序目录结构; 3、AndroidManidest.xml文件的作用; 4、Android相关资源文件的作用。 三、Activity及Activity和Intent(2学时) 1、Activity的主要作用; 2、创建一个Activity的方法; 3、在AndroidManifest.xml文件中的注册应用Activity的方法; 4、在Activity中添加控件的方法; 5、多个Activity之间的切换; 6、Intent的基本作用; 7、在一个Activity中启动另一个Activity的方法; 8、使用Intent在Activity中传递数据的基本方法。 四、常见控件的使用方法(基础) 1、TextView的使用方法; 2、EditText的使用方法; 3、Button的使用方法; 4、Menu的使用方法。 五、Activity的生命周期(2学时) 1、Activity的七个周期: ① OnCreate();② OnDestroy();③ OnPause();④ OnRestart();⑤ OnResume();⑥ OnStart();⑦ OnStop(); 2、Task的基本概念; 3、Activity和Task之间的关系; 4、对话框风格的Activity的使用方法。 六、Activity的布局(3学时) 1、LinearLayout的使用方法; 2、TableLayout的使用方法; 3、LinearLayout和TableLayout的嵌套使用; 4、RelativeLayout的使用方法(重点、难点) 七、常用控件是使用方法二(2学时) 1、RadioGroup和RadioButton的使用方法; 2、CheckBox的使用方法; 3、Toast的基本用法。 4、ProgressBar的使用方法; 5、ListView的用法。 八、Handler的使用方法(2学时) 1、Handler的基本概念; 2、Handler的基本用法; 3、使用Handler更新ProgressBar 4、Handler与线程; 5、Bundle的用法; 6、在新线程中处理消息的方法。 九、SQLite使用方法 1、SQLite介绍; 2、SQLiteOpenHeper使用方法; 3、使用adb访问SQLite 4、增、删、改、查。 十、Android文件下载 1、使用HTTP协议下载文件; 2、将下载的文件写入SDCARD。 十一、Content Provider初步(2学时) 1、Content Provider的基本概念; 2、Uri; 3、Content Provider的实现方法。 十二、XML文件的解析方法 1、什么是SAX; 2、SAX的基本原理; 3、SAX常用接口; 4、SAX解析。 十三、广播机制(2学时) 1、Android的广播机制(图鉴); 2、BroadCastReceive的作用; 3、BroadCastReceive的编写方法; 4、BroadCastReceive的生命周期。 5、注册BroadCastReceive的方法; 6、Android内置BroadCastReceive Actions。 十四、WIFI网络的使用 1、什么是WIFI; 2、获取WIFI网卡的状态; 3、操作WIFI所需要的权限; 4、改变WIFI网卡的状态。 十五、Socket编程 1、什么是Socket; 2、Socket基本通信模型(见图); 3、使用基于TCP协议的Socket; 4、使用基于UDP协议的Socket。 十六、Service 1、Service是什么; 2、Service不是什么; 3、Service的生命周期; 4、启动和停止Service; 一、硬件描述 如上图,应用程序的开发过程中我们使用了飞思卡尔的i.MX51 EVK Hardware。设备提供的支持如下:多标准音频回放;多标准视频回放;开放的系统支持; 二、软体结构 1、Android系统的初始化流程图如下所示: BeginMkdir: /dev,/proc,/sys,/dev/pts,/dev/socketaction_for_each_trigger(“early-init”, action_add_queue_tail);property_set(ro.XXX)open_devnull_stdio():fd is 0,1,2device_initaction_for_each_trigger(“init”, action_add_queue_tail)log_init: /dev/__kmsg__property_initaction_for_each_trigger(“early-boot”, action_add_queue_tail);parse_config_file(“/init.rc”)Check have /dev/consoleaction_for_each_trigger(“boot”, action_add_queue_tail);import_kernel_cmdline: /proc/cmdlineload_565rle_image(INIT_IMAGE_FILE)queue_all_property_triggers()get_hardware_name: /proc/cpuinfoIf load okrestart_processes()Yparse_config_file(/init.%s.rc)Show Image, and Print “A N D R O I D”to ttyEnd 可以具体描述如下:(1).初始化log系统。 (2).解析/init.rc和/init.%hardware%.rc文件。 (3).执行 early-init action in the two files parsed in step 2。 (4).设备初始化,例如:在 /dev 下面创建所有设备节点,下载 firmwares。 (5).初始化属性服务器,Actually the property system is working as a share memory.Logically it looks like a registry under Windows system。 (6).执行 init action in the two files parsed in step 2。 (7).开启 属性服务。 (8).执行 early-boot and boot actions in the two files parsed in step 2。 (9).执行 Execute property action in the two files parsed in step 2。 (10).进入一个无限循环 to wait for device/property set/child process exit events。 2、方案基本框架,如下图所示: Native codeDaivik runtimeAndroidNDKappsJNIAndroidSDKappsAndroid app frameworkStandard librariesLinux kernel+Android extension (1)图中Native Code包含一系列运行与Linux内核之上,由C/C++语言写成的库,这些库提供基本的系统级功能。其为应用层提供了本地开发的可扩展性,在此次开发过程中,Native Code主要为我们提供了音视频的编解码(即我们在此层开发了我们自己的音视频的编解码)。系统中主要使用的是G711音频编解码,实现语音的本地录音及播放;FFMPEG视频解码,进行图像视频的解码,实现视频的实时播放。 (2)Dalvik runtime的相关介绍。Android系统的应用开发语言是Java,而保障这一点的就是Android runtime。Java语言的运行需要有虚拟机的存在,而Android runtime 的核心就是一个称之为Dalvik的虚拟机。另外,Android runtime还包含了一个强大的Java核心类库。这个类库从功能上涵盖了传统Java核心类库的大多数功能。应用程序调用Android 函数库(即Android runtime中的Java核心类库)中的函数时,其实只是调用的一个函数名,具体实现在Native Code中的Library中。即是Library为上层的应用提供API供开发使用。(3)关于JNI。Java Native Interface(JNI)标准,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。我们开发的音视频本地编解码库,就是通过JNI来使用的。如下,private static native void InitEnv();private static native int drawFrame(Bitmap bitmap, byte[] inbuffer, int buf_len);这是我们在程序中调用的本地函数,先要使用关键字native进行本地声明。static { System.loadLibrary(“decode”);} 这是用来加载我们的c动态库的,上面的native声明中的方法就是在我们加载的库中具体实现的。 (4)Linux kernel 和Android extension部分。这一部分主要为我们提供了诸如硬件设备驱动(如display driver、camera driver等)、进程管理、内存管理、电源管理等底层功能。这一层的Linux并不是标准的GNU/Linux,而是根据我们的商业需求进行大量的定制。第二篇:Android总结
第三篇:Android WebView总结
第四篇:Android 课程总结
第五篇:Android方案总结