移动应用开发,写一个activity文件,要求:设置外部存储pemission。d)在代码中实现按钮点击功能,在OnCreate方法中添加外部存储访问请求。点击选择文件按钮,打开文件选择框,选择相应的音频文件,返回文件路径,在点击播放、传播、暂停等按钮时,实现相应的功能,实现视频播放功能,要求如下:(1)新建视频操作类,实现SurfaceHolder.Callback, MediaController.MediaPlayerControl, MediaPlayer.OnBufferingUpdateListener。 (2)变量声明MediaPlayer、MediaController、Context、bufferupdateing。 (3)创建操作类的构造方法,初始化MediaPlayer、MediaController、Context,设置播放控制按钮的锚定位置。 (4)完善SurfaceHolder.Callback的覆写方法, (5)完善MediaController.MediaPlayerControl的覆写方法。 (6)完善实现MediaPlayer.OnBufferingUpdateListener (7)在Activity中点击播放按钮实现播放 (8)在Activity中覆写SurfaceView的OnTouchEvent方法,实现Controller显示。
时间: 2023-12-14 14:40:21 浏览: 83
以下是一个简单的实现:
首先,在 AndroidManifest.xml 文件中添加外部存储权限:
```xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
```
然后,在 Activity 的布局文件中添加一个按钮和一个 SurfaceView:
```xml
<Button
android:id="@+id/select_file_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择文件" />
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
```
接下来,在 Activity 的 Java 文件中实现按钮点击和视频播放功能:
```java
import android.Manifest;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaController.MediaPlayerControl, MediaPlayer.OnBufferingUpdateListener {
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static final String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private MediaPlayer mediaPlayer;
private MediaController mediaController;
private SurfaceHolder surfaceHolder;
private String videoPath;
private boolean bufferUpdating;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 检查外部存储权限
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}
// 获取 SurfaceView 和按钮
SurfaceView surfaceView = findViewById(R.id.surface_view);
Button selectFileButton = findViewById(R.id.select_file_button);
// 设置 SurfaceView 的 Holder 和 Callback
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
// 设置按钮的点击事件
selectFileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 打开文件选择框
// 选择相应的音频文件,返回文件路径
videoPath = Environment.getExternalStorageDirectory() + "/video.mp4";
}
});
}
@Override
protected void onPause() {
super.onPause();
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 初始化 MediaPlayer 和 MediaController
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaController = new MediaController(this);
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(findViewById(R.id.surface_view));
try {
mediaPlayer.setDataSource(videoPath);
} catch (IOException e) {
e.printStackTrace();
}
// 设置 MediaPlayer 的 Surface 和 PrepareAsync
mediaPlayer.setDisplay(holder);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaController.setEnabled(true);
mediaPlayer.start();
}
});
mediaPlayer.prepareAsync();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Do nothing
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Do nothing
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
// 更新缓存状态
bufferUpdating = true;
mediaController.show();
mediaController.setSecondaryProgress(percent * mediaPlayer.getDuration() / 100);
bufferUpdating = false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 显示或隐藏 Controller
mediaController.show();
return false;
}
@Override
public void start() {
mediaPlayer.start();
}
@Override
public void pause() {
mediaPlayer.pause();
}
@Override
public int getDuration() {
return mediaPlayer.getDuration();
}
@Override
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
@Override
public void seekTo(int pos) {
mediaPlayer.seekTo(pos);
}
@Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
@Override
public int getBufferPercentage() {
return bufferUpdating ? 0 : 100;
}
@Override
public boolean canPause() {
return true;
}
@Override
public boolean canSeekBackward() {
return true;
}
@Override
public boolean canSeekForward() {
return true;
}
@Override
public int getAudioSessionId() {
return mediaPlayer.getAudioSessionId();
}
}
```
注意,在点击播放按钮时,应该先检查视频路径是否为空,以及 MediaPlayer 是否已经准备好了。如果没有准备好,应该等待 OnPreparedListener 回调再开始播放。同时,应该在 onPause() 和 onDestroy() 中分别暂停和释放 MediaPlayer,以免造成资源浪费和内存泄漏。此外,实现 MediaController.MediaPlayerControl 接口可以让 Controller 自动显示和隐藏,并且可以通过 Controller 控制视频的播放和暂停,以及拖动进度条跳转到指定时间。
阅读全文