Playing Audio in Android: The MediaPlayer Class
In this chapter, we will take the digital audio assets that we optimized in the previous chapter and teach you how to implement them for playback in your Hello_World AttackPlanet.java Activity event handling code.
Wersquo;ll add sound effects to the Attack a Planet user interface ImageButton elements, so that when users click these animated buttons the digital audio will playback, adding to the already impressive visual effects we created in the graphics design and animation chapters previously.
Now that you know how to optimize audio for use in Android, wersquo;ll also use some higher-quality audio from world-renowned sound designer and music composer Frank Serafine, who is a friend of mine and was gracious enough to give me a few audio samples for us to use for this book.
These sound effects, background music, and ambient environment sounds will allow us to greatly enhance our other Activity screens to yet again take our user interface and user experience to an entirely new level.
We will also take a look at some more concepts in digital audio playback, which are very similar to those which we observed in the digital video and the frame and vector animation chapters, such as seamless audio looping, where you canrsquo;t tell where the background audio loop (seam) is in the audio playback cycle.
Since wersquo;ve already gone over the basic origins of the Android MediaPlayer class in the previous chapter, we will now go ahead and cover the various Java methods that are available in this advanced class. We will do this in the first part of this chapter, and then wersquo;ll get into writing some code that implements some of these core MediaPlayer functions. Once we do this, wersquo;ll be able to give some of our user interface elements and our Activity screens some really cool digital audio features thanks to Mr. Serafine.
The Android Media Player: Methods and the State Engine
In Android, the MediaPlayer class is what could be termed a state machine, that is, a digital file playback entity that has certain states that it is in at any given time. I have generously included the state machine diagram from the developer.android.com website in this section (see Figure 14-1), so that you can reference it here, along with the text in this section, which discusses it in detail. You can find it on the developer website here:
http://developer.android.com/reference/android/media/MediaPlayer.html
Figure 14-1. Diagram of MediaPlayer State Engine (from the MediaPlayer Class page on developer.android.com) 1
1 Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
http://developer.android.com/reference/android/media/MediaPlayer.html
We learned about states in one of the earliest chapters in this book, when we reviewed our Java programming principles. Your Android MediaPlayer will always be in one of these following states: Idle, Initialized (loaded with your audio or video data), Preparing, Prepared, Started (Playing), Paused, Completed (Playback has Completed), and Stopped.
There are also End and Error MediaPlayer states. Letrsquo;s cover these two special states first and get them out of the way. End happens once the MediaPlayer object has been released from the memory needed to use it in the first place, and Error is used for when something goes wrong with the media playback process.
The MediaPlayer End state comes about when the Java method .release( ) is called. So if our MediaPlayer object is named bombPlayer, as it will be, for our bombButton ImageButton object in the next section of this chapter, you would release the MediaPlayer from memory using this code statement:
bombPlayer.release();
This clears the MediaPlayer object named bombPlayer from main memory, so that this memory can be utilized for other purposes.
The MediaPlayer Error state comes about when the OnErrorListener interface .onError( ) method is called via the following Java callback construct public abstract boolean onError (MediaPlayer mp, int what, int extra).
The mp parameter contains the name of the MediaPlayer object, for instance bombPlayer, the what parameter contains the type of error constant, and the extra parameter contains the error-specific code constant.
What constants include MEDIA_ERROR_UNKNOWN and MEDIA_ERROR_SERVER_DIED and extra constants can include MEDIA_ERROR_IO, MEDIA_ERROR_MALFORMED, MEDIA_ERROR_TIMED_OUT, and MEDIA_ERROR_UNSUPPORTED.
Information on the OnErrorListener public static interface is located at:
developer.android.com/reference/android/media/MediaPlayer.OnErrorListener.html
Now letrsquo;s start at the top of the MediaPlayer state engine diagram, shown in Figure 14-1, and work our way down the state tree logic diagram by one state at a time, starting with the Idle state and its reset( ) Java method.
If you use the .reset( ) method via a bombPlayer.reset( ); line of code, the MediaPlayer object resets itself (simulates its initial launch) and goes into Idle state or mode. The next mode after Idle is the Initialized state or mode; this is achieved by using the .setDataSource( ) method to set the data source reference to the media file you want to use.
For data resources in the /res/raw folder, you should use the .onCreate( ) method (which we will implement in the next section), and specify the data file resource path using the second parameter in the format R.raw.filename.
The Preparing state is utilized when accessing data files from an external server, and is used in conjunction w
剩余内容已隐藏,支付完成后下载完整资料
在安卓上播放音频: MediaPlayer类
在这一章中,我们将使用我们在前一章中优化得到的数字音频资源教你如何在你的Hello_World AttackPlanet.java Activity事件处理代码中来实现他们的播放。
我们将为一个形状为星球的用户界面图片按钮元素添加声音特效,那样的话当用户点击这些动画按钮的时候数字音频就会播放,并且增加了我们在前面的图形设计和动画章节中已经学到的所创建的视觉效果。
现在你已经知道如何在安卓的使用当中优化音频,我们也将使用一些更高质量的音频,这些音频来自世界知名的音效设计师和作曲家Frank Serafine,同时他也是我的朋友并且很慷慨地给我一些音频样本来作为本书中的例子来使用。
这些声音效果,背景音乐,和环绕我们周围的令人轻松的声音,将使我们能够大大增强我们的其他Activity屏幕的使用效果,然后使我们的用户界面和用户体验达到一个全新水平。
我们也将在数字音频播放中尝试一些其他的概念,这些概念和我们在数字视频帧和矢量动画的章节所见到的非常相似,如无缝的音频循环,这样你就不能在音频循环播放时分辨出背景音频在哪个地方循环了。
既然我们已经在之前的章节中回顾了Android MediaPlayer类的基本组成 ,我们就继续我们的课程,学习包括多种在这高级课程中需要使用的java方法。我们将在本章的第一部分做这件事,然后我们将开始写一些代码来实现媒体播放器的一些核心功能。我们这样做了之后,就可以给我们的用户界面元素和我们的Activity界面添加一些非常酷的数字音频效果,最后再次感谢我们的Serafine先生。
安卓媒体播放器:方法和状态引擎
在Android中,MediaPlayer类可被称为一个状态机器,即数字文件播放的实体,它任何给定的时间内有一定的状态。我已慷慨地在这段章节中包括了从developer.android.com网站找到的状态机器图(见图14-1),因此,你可以在这里引用它,同时通过这一节中的文本来详细地讨论它。你可以在这里的开发者网站找到它:
http://developer.android.com/reference/android/media/MediaPlayer.html
图14-1。MediaPlayer状态机图(出自developer.android.com网站中MediaPlayer Class页)1
1此页的部分内容是由安卓开源项目创建和共享的,并根据知识共享2.5署名许可协议许可使用。
http://developer.android.com/reference/android/media/MediaPlayer.html
我们在这本书最早的某一章节中了解到了安卓的状态机制,那是我们在复习我们的java 编程原则的时候。你的Android媒体播放器总是会处于以下这些状态之一: 空闲的,初始化的(加载您的音频或视频数据),准备中,准备好了,开始(播放),暂停,完成(播放已完成),还有停止。
也有结束和错误这两种MediaPlayer状态。让我们先来讲讲这两个特殊的状态然后就不再理会它们。结束状态是一旦MediaPlayer对象已经从一开始需要使用的内存中被释放时被调用,而错误状态是在当媒体播放过程中发生了错误时被调用。
MediaPlayer的结束状态是当java方法.release( )被调用的时候出现。所以,如果我们的媒体播放器 对象被命名为bombPlayer,那么同样的,在这章的下一节中我们的图片按钮对象就会叫bombButton,你也将会使用此代码语句将MediaPlayer从内存中释放: bombPlayer.release();
这将从主内存中清除被命名为bombPlayer的MediaPlayer对象命,这样这这块内存就能被用于其他用途。
当OnErrorListener 接口中 .onError( ) 方法通过接下来的java回调结构public abstract boolean onError (MediaPlayer mp, int what, int extra)被调用时,MediaPlayer的错误状态就会发生。
mp参数包含MediaPlayer对象的名称,例如bombPlayer,what参数包含错误常量的类型,extra参数包含特定的错误代码常量。
what常量包含了MEDIA_ERROR_UNKNOWN 和MEDIA_ERROR_SERVER_DIED,
extra 常量包括 MEDIA_ERROR_IO, MEDIA_ERROR_MALFORMED,MEDIA_ERROR_TIMED_OUT, 和MEDIA_ERROR_UNSUPPORTED。
关于公共静态接口OnErrorListener的信息能在下面的网址找到:
developer.android.com/reference/android/media/MediaPlayer.OnErrorListener.html
现在让我们从图14-1所示的MediaPlayer状态机图的顶部开始,然后从状态逻辑关系树图往下一次一个状态 ,首先从空闲状态开始 还有它的reset( ) Java方法。
如果你通过一行代码bombPlayer.reset( ); 来使用.reset( ) 方法,MediaPlayer对象就会重置它自己(模拟其初始化启动),并进入空闲状态或模式。空闲后的下一个模式是初始化状态或模式,这是利用 .setDataSource( ) 方法设置你想使用媒体文件数据源来实现。
为了得到在/res/raw folder的数据资源,你应该使用 .onCreate( ) 方法(我们将在下一节中实现),并在使用格式为R.raw.filename的第二种参数指定数据文件资源路径。
在从外部服务器访问数据文件时,使用准备状态,或是在Uri.parse( ) 方法分析与外部服务器的URL连接时使用准备状态。即使我们使用在我们的应用程序内部的媒体数据资源,我会告诉你在这里要写的代码,也完全在我这个MediaPlayer状态图范围里。
你要用.setOnPreparedListener( )调用一个新建的OnPreparedListener( ),通过如下的使用了onPrepared( )方法的java代码块来实现:
MediaPlayer mp = MediaPlayer.create(this,Uri.parse('http://www.url.com/file.mp3'));
player.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
一旦媒体播放器已经达到准备状态,通过.onCreate( ) 方法或者其他的类似于上面指定的代码块,你就可以调用 .start( )方法来使MediaPlayer进入启动状态(或模式,如果你更喜欢把它叫做模式)。
请注意,这些状态与我们之前在本书中讨论的模式相似,除了我们讨论的模式,还有多种数字成像模式,需要被考虑,当我们在同一时间使用GIMP 2的时候。
图中的下一个层次是暂停和停止状态,这取决于 .pause( )方法是否被调用或.stop( )方法是否被调用。正如你在状态图中可以看到的,一旦一个MediaPlayer对象暂停,你可以使用 .start( )方法来重新启动媒体播放。
当您的媒体文件结束播放时,就处于播放完成状态(或被设置)。如果循环标志设置为false(默认的),然后onCompletion( )方法就会通过OnCompletionListener被调用(如果你在你的代码里定义过),接下来的那些歌曲播放任务将被继续执行。
注意,一旦你的MediaPlayer达到初始化或停止状态,.prepareAsync( ) 方法可以用来把你的MediaPlayer对象进入准备状态。
准备状态通常发生在你的媒体数据文件从远程位置被获取(传输)时,通常是某种形式的媒体服务器,如Amazon S3或Akamai或你自定义数据服务器。
注意,如果你要集中你的应用程序的功能在mediaplayer类,而不是用它来播放音频或视频资源,那你应该回顾本节开头引用的MediaPlayer 开发者那一页。使用MediaPlayer类来创建你自己的先进的媒体播放器是超出一本入门级的安卓教材范围的,比如这一本书,因为Android中 MediaPlayer功能有足够复杂到得有专门写的关于它的书。
在Android里面还有一个数字音频序列类叫SoundPool类,这如果你的应用程序使用了大量的声音,而这些声音是需要混合和实时匹配的,这个类可能实际上是获得最佳的使用效果的工具,比如你在做的游戏或动画电子书或类似的强大新媒体应用,你会使用到这个类的。
这个Android SoundPool类将在下一章,所以接下来请确保你完全沉浸在关键的学习中,这本书这一节中的初级数字音频类和安卓工作实现的过程。
建立一个MediaPlayer对象并和数字音频数据一起加载
在实施我们的MediaPlayer对象时我们需要做的第一件事就是在我们的AttackPlanet.java Activity 子类的顶部声明它,用一行代码来声明它是一个私有访问对象并且将它设置为一个空值(直到我们以后再使用),通过下面的代码:
private MediaPlayer bombPlayer = null;
你会注意 Eclipse ADT会用红色波浪线在单词MediaPlayer下做下划线。这是因为我们没有在我们代码的最上面引用它的参考出处。把我们的鼠标放在红色波浪下划线上,选择引用android.media.MediaPlayer包的引用链接然后我们就能让Eclipse为我们来写这句代码。
这个导入语句和MediaPlayer对象的声明可以在图14-2看到。
图14-2。声明一个命名为bombPlayer的MediaPlayer对象并且设置它的值为null
接下来,我们需要写一个方法设置我们的MediaPlayer对象中使用我们的Attack a Planet用户界面的图片按钮图标。我们将这样做来达到当每一个按钮被点击的时候,不同的声音效果就会播放。
自定义我们的setAudioPlayers( ) java方法
让我们把这称为自定义的java方法叫做setAudioPlayers( ) ,把它加入到我们的第一个bombPlayer MediaPlayer对象,它将会后台播放我们的音频资源。
首先,让我们在我们的AttackPlanet Activity顶部用一行代码引用我们的新方法,就在setContentView( ) 方法之后,使用下面的java方法调用语句:
setAudioPlayers();
接下来我们需要写setAudioPlayers( ) 方法本身,我们会编辑屏幕很底部的地方做这件事,就在我们所有的其他 ImageView, ImageButton, Animation和AnimationDrawawble对象的代码之后。
我们声明setAudioPlayers( ) 方法作为私人方法,只有这个类能够使用它来设置我们所有的数字音频样本的MediaPlayer对象,并设置属性void,因为在它被调用的时候它不返回任何值。
括号里面我们加入MediaPlayer对象的创建代码,使用MediaPlayer类中的 .create( )方法。这种方法需要联系当前的上下文,代码写法如下:
AttackPlanet.this
或者,你也可以利用getApplicationContext( ) 方法,我们将在这里实现它 ,这样你就可以看到这种方法的使用。 .create( )方法需要的第二个参数是资源文件的引用,这我们都知道是R.raw.blast,所以创建我们的bombPlayer MediaPlayer 对象并把它与我们的数字音频数据一起加载的代码写法如下:
bombPlayer = MediaPlayer.create(getApplicationContext( ), R.raw.blast);
就和我们添加其他声音效果数字音频资源一样,我们为这个方法里的其他效果每一个都添加相似的几行代码。这样,当我们的Activity启动时,这个方法被调用,MediaPlayer对象都将首先被创建并且做好使用的准备。
然后,我们在我们的个人用户界面按钮的代码中所需要做的是在用户点击各个按钮的时候从我们的事件处理代码调用每一个MediaPlayer对象(数字音频样本)。新方法的调用和方法的主体与它的第一个MediaPlayer对象已经如图14-3所示编写代码。
图14-3。编写setAudioPlayers() 方法来建立起我们的MediaPlayer对象的音效
下一步我们将添加启动MediaP
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[28792],资料为PDF文档或Word文档,PDF文档可免费转换为Word
课题毕业论文、外文翻译、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。