布局文件:两个按钮,一个选择播放的文件,一个播放/暂停按钮;一个可拖动的进度条,用来显示当前播放进度;一个TextView用来显示当前播放的时间;一个SurfaceView用来显示视频内容;
<? version=\"1.0\" encoding=\"utf-8\"?>
<LinearLayout ns:android=\"http://schemas.android.com/apk/res/android\"
ns:app=\"http://schemas.android.com/apk/res-auto\"
ns:tools=\"http://schemas.android.com/tools\"
android:layout_width=\"match_parent\"
android:layout_height=\"match_parent\"
tools:context=\".MainActivity\"
android:orientation=\"vertical\">
<LinearLayout
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\"
android:gravity=\"center\">
<Button
android:id=\"@+id/openfile\"
android:layout_width=\"100dp\"
android:layout_height=\"wrap_content\"
android:text=\"选择文件\"/>
<Button
android:id=\"@+id/playorpause\"
android:layout_width=\"100dp\"
android:layout_height=\"wrap_content\"
android:layout_marginLeft=\"50dp\"
android:text=\"播放/暂停\"/>
</LinearLayout>
<SeekBar
android:id=\"@+id/playprogress\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\" />
<TextView
android:id=\"@+id/currenttime\"
android:layout_width=\"wrap_content\"
android:layout_height=\"wrap_content\" />
<SurfaceView
android:id=\"@+id/surfaceview\"
android:layout_width=\"match_parent\"
android:layout_height=\"wrap_content\" />
</LinearLayout>
MainActivity
package com.example.ceshi;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaP ;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity implements View. Listener {
MediaP mediaP ;
SeekBar playProgress;
boolean seekBarIsChanging = false;
TextView showTime;
SurfaceView surfaceView;
HandleFilePath handleFilePath = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button openFile = findViewById(R.id.openfile);
Button playOrPause = findViewById(R.id.playorpause);
openFile.set Listener(this);
playOrPause.set Listener(this);
playProgress = findViewById(R.id.playprogress);
playProgress.setOnSeekBarChangeListener(new MySeekBar());
showTime = findViewById(R.id.currenttime);
surfaceView = findViewById(R.id.surfaceview);
surfaceView.setVisibility(View.GONE);
}
@Override
public void (View v) {
switch (v.getId()) {
case R.id.openfile:
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
else
openFile();
break;
case R.id.playorpause:
if (mediaP .isPlaying()) {
mediaP .pause();
} else {
if (handleFilePath.isVideo())
surfaceView.setVisibility(View.VISIBLE);
mediaP .start();
playProgress.setMax(mediaP .getDuration());
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!seekBarIsChanging)
playProgress.setProgress(mediaP .getCurrentPosition());
}
}, 0, 1000);
}
break;
}
}
class MySeekBar implements SeekBar.OnSeekBarChangeListener {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
updateTimeShow();
}
@Override
public void TrackingTouch(SeekBar seekBar) {
seekBarIsChanging = true;
}
@Override
public void TrackingTouch(SeekBar seekBar) {
mediaP .seekTo(playProgress.getProgress());
seekBarIsChanging = false;
}
}
private void updateTimeShow() {
int currentTime = playProgress.getProgress();
int totalTime = (mediaP .getDuration() == -1) ? 0 : mediaP .getDuration();
showTime.setText(String.format(\"当前时间:%02d:%02d/%02d:%02d\", currentTime / 60000, (currentTime % 60000) / 1000, totalTime / 60000, (totalTime % 60000) / 1000));
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
openFile();
break;
}
}
private void openFile() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(\"*/*\");
startActivityForResult(intent, 1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
playProgress.setProgress(0);
handleFilePath = new HandleFilePath(this, data.getData());
String filePath = handleFilePath.getFilePath();
if(surfaceView.getVisibility() == View.VISIBLE)
surfaceView.setVisibility(View.GONE);
if (filePath != null && (handleFilePath.isAudio() || handleFilePath.isVideo())) {
try {
if(mediaP != null) {
mediaP .reset();
mediaP .release();
mediaP = null;
}
mediaP = new MediaP ();
mediaP .setDataSource(filePath);
if (handleFilePath.isVideo()) {
surfaceView.getHolder().addCallback(new mySurfaceCallback());
}
mediaP .prepare();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
Log.d(\"zhangfy\", \"\" + (mediaP == null));
}
}
updateTimeShow();
}
break;
}
}
class mySurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder holder) {
mediaP .setDisplay(surfaceView.getHolder());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
}
获取文件真实路径的代码:
package com.example.ceshi;
import android.annotation.TargetApi;
import android.content.Context;
import android.data .Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
class HandleFilePath {
Context context;
String path = null;
@TargetApi(Build.VERSION_CODES.KITKAT)
HandleFilePath(Context context, Uri uri) {
this.context = context;
if (DocumentsContract.isDocumentUri(context, uri)) {
String documentId = DocumentsContract.getDocumentId(uri);
if (isMediaDocument(uri)) {
String id = documentId.split(\":\")[1];
String selection = \"_id = \" + id;
String type = documentId.split(\":\")[0];
if (type.equals(\"audio\"))
path = uriToPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, selection);
else if (type.equals(\"video\"))
path = uriToPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, selection);
else if (type.equals(\"image\"))
path = uriToPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
} else if (isDownloadsDocument(uri)) {
path = documentId.substring(documentId.indexOf(\":\") + 1);
} else if (isExternalStorageDocument(uri)) {
path = Environment.getExternalStorageDirectory() + \"/\" + documentId.split(\":\")[1];
}
} else if (\"content\".equalsIgnoreCase(uri.getScheme())) {
path = uriToPath(uri, null);
} else if (\"file\".equalsIgnoreCase(uri.getScheme())) {
path = uri.getPath();
}
}
private String uriToPath(Uri uri, String selection) {
Cursor cursor = context.getContentResolver().query(uri, null, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
return cursor.getString(cursor.getColumnIndex(\"_data\"));
}
cursor.close();
}
return null;
}
private static boolean isExternalStorageDocument(Uri uri) {
return \"com.android.externalstorage.documents\".equals(uri.getAuthority());
}
private static boolean isDownloadsDocument(Uri uri) {
return \"com.android.providers.downloads.documents\".equals(uri.getAuthority());
}
private static boolean isMediaDocument(Uri uri) {
return \"com.android.providers.media.documents\".equals(uri.getAuthority());
}
private String getFileType(){
String type = path.substring(path.lastIndexOf(\".\")+1);
String[] audio = {\"MP3\",\"AAC\",\"WAV\",\"WMA\",\"CDA\",\"FLAC\",\"M4A\",\"MID\",\"MKA\",
继续阅读与本文标签相同的文章
下一篇 :
AI独角兽云从如何冲破重庆互联网迷雾
-
Aliyun Serverless VSCode Extension v1.8.0 发布
2026-05-18栏目: 教程
-
日本丰田和美国通用等8家企业联合开发自动驾驶技术
2026-05-18栏目: 教程
-
发布K12教育机械臂,越疆完成全龄段AI教育布局
2026-05-18栏目: 教程
-
有人试图用AI解读《未命名的鹅戏》里的鹅
2026-05-18栏目: 教程
-
MongoDB副本集
2026-05-18栏目: 教程
您的足迹:
