📁 项目名称:SimpleVideoPreviewer(Java 版)
技术栈
- 语言:Java(兼容 Android Studio 最新版本)
- 核心组件:
VideoView、Intent.ACTION_PICK、ActivityResultLauncher - 权限:
READ_EXTERNAL_STORAGE(适用于 Android 10 及以下;如需支持 Android 11+,建议后续升级到 SAF,但 Java 实现复杂度略高,实习生项目可暂不涉及)
📄 1. AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="视频预览器"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
⚠️ 注意:Android 13(API 33)起需使用
READ_MEDIA_VIDEO,但为简化,此处以通用权限为例。面试时可说明"了解新存储模型"。
📄 2. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<Button
android:id="@+id/btnPickVideo"
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="300dp"
android:layout_marginTop="16dp" />
</LinearLayout>
📄 3. MainActivity.java(核心逻辑 - Java 版)
package com.example.simplevideopreviewer;
import android.Manifest;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import android.widget.VideoView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE_PERMISSION = 100;
private VideoView videoView;
private ActivityResultLauncher<String> pickVideoLauncher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
videoView = findViewById(R.id.videoView);
Button btnPick = findViewById(R.id.btnPickVideo);
// 注册 Activity Result Launcher(替代 startActivityForResult)
pickVideoLauncher = registerForActivityResult(
new ActivityResultContracts.GetContent(),
uri -> {
if (uri != null) {
playVideo(uri);
} else {
Toast.makeText(this, "未选择视频", Toast.LENGTH_SHORT).show();
}
}
);
btnPick.setOnClickListener(v -> {
if (checkStoragePermission()) {
pickVideoLauncher.launch("video/*");
} else {
requestStoragePermission();
}
});
}
private boolean checkStoragePermission() {
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED;
}
private void requestStoragePermission() {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_CODE_PERMISSION
);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
pickVideoLauncher.launch("video/*");
} else {
Toast.makeText(this, "需要存储权限才能选择视频", Toast.LENGTH_SHORT).show();
}
}
}
private void playVideo(Uri uri) {
videoView.setVideoURI(uri);
videoView.start();
}
@Override
protected void onPause() {
super.onPause();
// 暂停视频,避免后台继续播放
if (videoView.isPlaying()) {
videoView.pause();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 停止并释放资源
videoView.stopPlayback();
}
}