目前,任何对得起"智能"二字的智能手机都有音频播放的能力,可以和那些专门的便携式媒体设备,MP3随身听媲美。基于Android系统的设备当然也有这样的能力。这些能力允许你建造音乐播放器,有声读物,播客,以及任何以音频播放为主的应用程序。

在这一章里,我们将要从格式和编解码支持的角度来探索Android的能力,并且我们将建造几个不同的播放程序。此外我们将着眼于Android对音频格式和元数据方面的支持

 

音频播放

如上所述,Android有媲美于MP3随身听的音频播放能力。事实上它可能做的更好,因为它对音频格式的支持相当广泛,比大部分硬件播放器都要广泛。这就是智能手机其中的一个好处,它把要执行的功能预先委托给专门的硬件,因此它们有很好的能力来运行各种各样的软件。像电脑一样,它们为不同和不断变化的技术提供了广泛的支持,显然,把这些技术建造在以硬件为中心的固件设备里是不切实际的。

 

所支持的音频格式

对于播放,Android支持各种各样的音频文件格式和编解码。对于录音的支持少一些,以后我们学到录音部分将会讨论这点。

AAC:

高级音频编码(以及其扩展:HE AAC)编解码,.m4a,.3gp文件.AAC是一个流行的标准,IPOD和其他便携式媒体播放器都使用它。Android在MPEG4音频文件和3GP文件内(都是基于MPEG4格式)支持这种音频格式。最近AAC的附加规范HE AAC也被支持了。

MP3:

MPGE-1音频层3,.mp3文件。Android支持MP3,MP3可能是使用最广泛的音频编解码,这允许Android通过各种网站和音乐商店来使用大部分在线音频。

AMR:

自适应多速率编解码(AMR-NB,AMR-WB),.3gp,.amr文件。AMR音频编解码已经被标准化了,主要被3GPP(第三代合作伙伴项目)用于语音音频编解码。3GPP是一个为其合作伙伴创建规范的电信行业机构。换句话说,AMR编解码主要用于现代移动电话的语音呼叫程序,并且手机厂商和手机携带者普遍都支持这个格式。AMR这格式一般对语音编码很有用,但对更复杂的类型表现的不够好,比如音乐。

 

Ogg:

Ogg Vorbis,.ogg文件。Ogg Vorbis 是个开源的,无专利费的音频编解码。其品质可媲美商业性的,需缴纳专利费的编解码比如MP3,AAC。它由一群自愿者开发,当前由Xiph.Org基金会负责维护。

 

PCM:

脉冲编码调制通常被用在WAVE,WAV文件,.wav文件。PCM这技术主要用于音频在电脑和其他电子音频设备上的存储。它通常是个未压缩的音频文件,其数据代表随着时间流逝一段音频的振幅。“采样率”是多长时间一次一个振幅读取被存储起来。“位深度”是指多少位被用来代表一个单独的样本。一段16KHZ采样率,32位位深度的音频数据是指它包含每秒钟16000个的32位的数据用来表示音频振幅。采样率和位深度越高,数字化音频越精准。采样率和位深度也决定了音频文件的大小。Android在WAV文件内支持PCM音频数据。WAV是PC上的一个长期存在的标准音频格式。

 

 

通过Intent使用内建的音频播放器

正如使用摄像头,在一个应用程序里提供播放音频文件的能力,最容易的方法就是使用内建的“音乐”程序的功能。这个程序有个用户熟悉的界面,能播放所有Android支持的格式,并且能通过一个intent,被触发去播放一个指定的文件。

普通的android.content.Intent.ACTION_VIEW intent,其数据设置为一个音频文件的Uri,并指定其MIME类型,这样Android会自动选择一个合适的应用程序来播放。这个程序应该是内建的音乐播放程序,但用户可能被提供其他的选项,如果他/她安装了其他的音频播放软件。

 
  
  1. Intent intent = new Intent(android.content.Intent.ACTION_VIEW);   
  2. intent.setDataAndType(audioFileUri, "audio/mp3");   
  3. startActivity(intent); 

 

注解:MIME全称是Multipurpose Internet Mail Extensions(多用途互联网邮件扩展)。它起初专门用来帮助电子邮件客户端发送和接收附件。但它的使用范围从电子邮件极大地扩展到其他的通讯协议,包括HTTP,标准万维网服务。Android使用MIME类型来解析intent,并且用它来决定应该选择哪个应用程序来处理intent.
每个文件类型都有特定的(有时候不止一个)MIME类型。MIME类型通过至少由2部分组成,由斜杠分开的字符来指定。第一部分是更通用的类型,比如“audio”.第二部分是更具体的类型,比如"mpeg".一个通用的类型"audio"和一个更具体的类型"mpeg"将产生一个“audio/mpeg"MIME类型字符,这个MIME类型通常用于MP3文件。

这里有个通过一个intent触发内建的音频播放程序的完整例子。

 

 
  
  1. package com.apress.proandroidmedia.ch5.intentaudioplayer;   
  2. import java.io.File;   
  3. import android.app.Activity;   
  4. import android.content.Intent;   
  5. import android.net.Uri;   
  6. import android.os.Bundle;   
  7. import android.os.Environment;   
  8. import android.view.View;   
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  

我们的activity在触发音频播放之前会一直监听一个Botton是否被按下。

 
  
  1. public class AudioPlayer extends Activity implements OnClickListener {   
  2.     Button playButton;   
  3.        
  4.     @Override   
  5.     public void onCreate(Bundle savedInstanceState) {   
  6.         super.onCreate(savedInstanceState);   
  7.         setContentView(R.layout.main);  

我们将content view设置为我们的XML后,我们能得到一个Button的引用,并将我们的activity(this)设为OnClickListener.

 
  
  1. playButton = (Button) this.findViewById(R.id.Button01);          
  2. playButton.setOnClickListener(this);   

当我们的Button被点击,OnClick方法会被调用。在这个方法里,我们用一个普通的android.content.Intent.ACTION_VIEW 来构建intent,然后创建一个文件对象,这个对象是SD卡上已经存在的音频文件的索引。这种情况下,这个音频文件被手动放置到SD卡的“Music"目录下,这个目录通常放置和音乐相关的音频文件。

 
  
  1. public void onClick(View v) {   
  2.        Intent intent = new Intent(android.content.Intent.ACTION_VIEW);   
  3.        File sdcard = Environment.getExternalStorageDirectory();   
  4.        File audioFile = new File(sdcard.getPath() + "/Music/goodmorningandroid.mp3");  

接下来,我们设置intent的数据为来源于音频文件的Uri并将其类型设置为MIME类型,audio/mp3.最后传递我们的intent给startActivity来触发内建的音乐播放程序。

 
  
  1.     intent.setDataAndType(Uri.fromFile(audioFile), "audio/mp3");   
  2.     startActivity(intent);                   
  3. }  

下面是一个简单的XML布局文件,其中Button的文本为"Play Audio",前面所述的activity会用到这个Button.

 
  
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:orientation="vertical"   
  4.     android:layout_width="fill_parent"   
  5.     android:layout_height="fill_parent"   
  6.     >   
  7.     <Button android:text="Play Audio" android:id="@+id/Button01"    
  8.     android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>   
  9. </LinearLayout>  

 

图5-1:通过一个intent触发Android内建的音乐播放器来播放指定的音频文件。

待续