在Android中播放音频文件一般都使用MediaPlayer,但是一般都是比较长的音频文件,我们可以用soundpool可以播一些短的反应速度要求高的声音,比如通知提示音,消息提示音等。
①我们在创建SoundPool对象时,在API 21以下可以用
SoundPool pool=new SoundPool(2,AudioManager.STREAM_MUSIC,0);
其中第一个参数maxStream表示同时播放的流的最大数量,第二个参数streamType表示流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出),第三个参数srcQuality表示采样率转化质量,当前无效果,使用0作为默认值 。
在API 21及以上,要借助SoundPool.Builder来创建SoundPool对象。
首先创建SoundPool.Builder对象,然后设置一些播放的参数,最后调用build()方法来创建SoundPool对象。
SoundPool.Builder builder=new SoundPool.Builder();
builder.setMaxStreams(2);
AudioAttributes.Builder audioBuilder = new AudioAttributes.Builder();
audioBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(audioBuilder.build());
SoundPool pool=builder.build();
然后调用load()方法,得到voiceId的int值。如果我们要从APK资源中载入音频文件,那么我们要在res目录下新建文件夹raw,然后将播放的音频文件放入raw下。
int voiceId=pool.load(getApplicationContext(),R.raw.outgoing,1);
传入的3个参数依次为Context,目标音频资源ID,优先级。
②最后播放,则调用play()方法。
pool.play(voiceId,1,1,0,-1,1);
这里传入了6个参数,第一个为load()方法返回的id,第二个leftVolume表示左音量,第三个rightVolume表示右音量,第四个priority表示优先级,第五个loop表示循环次数,其中0表示一次,-1表示循环,第六个rate表示速率,速率最低0.5最高为2,1代表正常速度 。
注意:因为SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作,所以如果载入音乐文件多大,当我们执行play(),可能会播放不出来声音。所以我们尽量让加载文件和调用play()方法,放在不同的位置。比如加载放在onCreate()方法里,调用play()方法放在按钮的监听事件里!
这里我们在布局中添加一个按钮,点击按钮播放我们的音频。下面是MainActivity中的代码
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private SoundPool pool;
private int voiceId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
voiceId=initSoundPool();
Button button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pool.play(voiceId,1,1,0,-1,1);
}
});
}
private int initSoundPool(){
//API 21及以上使用
if (Build.VERSION.SDK_INT>=21){
SoundPool.Builder builder=new SoundPool.Builder();
builder.setMaxStreams(2);
AudioAttributes.Builder audioBuilder=new AudioAttributes.Builder();
audioBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(audioBuilder.build());
pool=builder.build();
//API 21以下使用
}else {
pool=new SoundPool(2,AudioManager.STREAM_MUSIC,0);
}
return pool.load(getApplicationContext(),R.raw.outgoing,1);
}
}
录制音频文件就需要借助MediaRecorder类。
这个图,很清楚的说明了MediaRecorder的工作流程,我们在用的时候,只要按照这个流程一步一步写下来就行了!
我们在布局中添加两个按钮,一个点击开始录音,一个点击结束录音。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<Button android:id="@+id/button_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始录音" />
<Button android:id="@+id/button_stop" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="结束录音" />
</LinearLayout>
然后是主活动的代码
import android.media.MediaRecorder;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private MediaRecorder mediaRecorder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button_start= (Button) findViewById(R.id.button_start);
button_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaRecorder=new MediaRecorder(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setOutputFile(Environment.getExternalStorageDirectory()+"/myrecorder.3gp");
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
});
Button button_stop= (Button) findViewById(R.id.button_stop);
button_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
}
});
}
}
最后要加上调用麦克风的权限和写入内存卡的权限
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
VideoView类将视频的显示和控制集于一身,可以让我们非常便捷的显示和控制视频的播放。
它的用法也非常简单,首先我们在布局中加入一个按钮和一个VideoView控件,点击按钮可以播放视频。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始播放" />
<VideoView android:id="@+id/videoview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />
</LinearLayout>
然后是MainActivity
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;
public class MainActivity extends AppCompatActivity {
private VideoView videoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//得到VideoView的实例
videoView= (VideoView) findViewById(R.id.videoview);
Button button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//设置VideoView的播放文件路径
videoView.setVideoPath(Environment.getExternalStorageDirectory()+"/aa.mp4");
//设置播放位置
videoView.setMediaController(new MediaController(MainActivity.this));
videoView.start();//开始播放
}
});
}
}
最后别忘了加入读取内存卡的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
同样的我们在布局中加入一个按钮和一个SurfaceView,点击按钮,播放视频!用法和前边将播放音频差不多。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="开始播放"/>
<SurfaceView android:id="@+id/surfaceview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/>
</LinearLayout>
然后是MainActivity
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private SurfaceView surfaceView;
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView= (SurfaceView) findViewById(R.id.surfaceview);
Button button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mediaPlayer==null){
mediaPlayer=new MediaPlayer();
}
mediaPlayer.reset();
try {
mediaPlayer.setDataSource(Environment.getExternalStorageDirectory()+"/aa.mp4");
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//SurfaceHolder是SurfaceView的控制接口,设置显示视频显示在SurfaceView上
mediaPlayer.setDisplay(surfaceView.getHolder());
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
这里我们也需要声明访问内存卡的权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
很多时候我们的应用程序可能会使用到摄像头的拍照功能,这时就需要我们调用系统摄像头来进行拍照,为我们的应用程序服务。
这里我们在布局中加入一个按钮,然后加入一个ImageView,点击按钮,调用摄像头拍照,然后把拍好的照片设置到ImageView上面显示。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="调用系统摄像头"/>
<ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>
MainActivity.java
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.File;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private Uri uri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView= (ImageView) findViewById(R.id.image);
Button button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//隐式启动相机
//创建File对象,来存储拍下的照片
File file=new File(Environment.getExternalStorageDirectory(),"hello.jpg");
if(!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
uri=Uri.fromFile(file);//将File对象转换为Uri对象
intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);//告诉系统相机,存储照片的位置
startActivityForResult(intent,0x23);//开始启动
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==0x23){
if (resultCode==RESULT_OK){
Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
imageView.setImageBitmap(bitmap);//得到图片
}
}
}
}