除了前面介绍的个各种XML文件、图片文件之外,Android应用可能还需要用到大量其他类型的资源,比如声音资源等。实际上,声音对于Android应用非常重要,选择合适的音效可以让Android应用增色不少。
类似声音文件及其他各种类型的文件,只要Android没有为之提供专门的支持,这种资源都被称为原始资源。Android的原始资源可以放在如下两个地方。
- 位于/res/raw目录下,Android SDK会处理该目录下原始资源,Android SDK会在R清单类中为该目录下的资源生成一个索引项。
- 位于/assets/目录下,该目录下的资源是更彻底的原始资源。Android应用需要通过AssetManager来管理该目录下的原始资源。
Android SDK会为位于/res/raw/目录下的资源在R类中生成一个索引项,接下来在XML文件中可通过如下语法格式来访问它:
@[<package_name>:]raw/file_name
在Java代码中则按如下语法格式来访问它:
[<package_name>.]R.raw.<file_name>
通过上面的索引项,Android应用就可以非常方便地访问/res/raw目录下的原始资源,至于获取资源后如何处理,则完全取决于实际项目的需要。
AssetManager是一个专门管理/assets/目录下原始资源的管理类,AssetManager提供了如下两个方法来访问Assets资源。
- InputStream open(String fileName):根据文件名来获取原始资源对应的输入流。
- AssetFileDescriptor openFd(Stirng fileName):根据文件名来获取原始资源对应的AssetFileDescriptor。AssetFileDescriptor代表了一项原始资源的描述,应用程序可通过AssetFileDescriptor来获取原始资源。
下面的程序示范了如何使用声音,先在应用的/res/raw/目录下放入一个bomp.mp3文件——Android SDK会自动处理该目录下的资源,会在R清单类中为它生成一个索引项:R.raw.bomp。
接下来我们再往/assets/目录下放入一个shot.mp3文件——需要通过AssetManager进行管理。
下面的程序中定义了两个按钮,一个按钮用于播放/res/raw/目录下的声音文件,另一个用于播放/assets/目录下的声音文件。
界面布局文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/playRaw" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放Raw音乐"/> <Button android:id="@+id/playAsset" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放Asset音乐"/> </LinearLayout>
后台代码文件如下:
package com.example.studyresources; import java.io.IOException; import android.media.MediaPlayer; import android.os.Bundle; import android.app.Activity; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class RawResTest extends Activity { MediaPlayer mediaPlayer1=null; MediaPlayer mediaPlayer2=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_raw_res_test); //直接根据声音文件的ID来创建MeidaPlayer mediaPlayer1=MediaPlayer.create(this, R.raw.bomb); //获取该应用的AssetManager AssetManager am=getAssets(); try { //获取指定文件对应的AssetFileDescriptor AssetFileDescriptor afd=am.openFd("shot.mp3"); mediaPlayer2=new MediaPlayer(); //使用MediaPlayer加载指定的声音文件 mediaPlayer2.setDataSource(afd.getFileDescriptor()); mediaPlayer2.prepare(); } catch(IOException e) { e.printStackTrace(); } //获取第一个按钮,并为它绑定事件监听器 Button playRaw=(Button)findViewById(R.id.playRaw); playRaw.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub //播放声音 mediaPlayer1.start(); } }); //获取第二个按钮,并为它绑定事件监听器 Button playAsset=(Button)findViewById(R.id.playAsset); playAsset.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub mediaPlayer2.start(); }}); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.raw_res_test, menu); return true; } }
上面的程序中第一行粗体字代码用于获取/res/raw/目录下的原始资源文件;第二段粗体字代码则利用了AssetManager来获取/assets/目录下的原始资源文件。
运行程序如下效果: