如何在Android应用中实现点击按钮录制10秒视频并存储至内部存储?
实现Android点击按钮录制10秒视频并存储到内部存储
步骤1:添加权限到清单文件
在AndroidManifest.xml中添加相机、录音权限及相机功能声明:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
步骤2:布局文件(activity_main.xml)
添加触发录制的按钮和相机预览的SurfaceView:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:id="@+id/recordBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="32dp" android:text="开始录制" /> </RelativeLayout>
步骤3:核心逻辑实现(MainActivity.java)
import android.Manifest; import android.content.pm.PackageManager; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Handler; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; import java.io.File; import java.io.IOException; public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback { private Button recordBtn; private SurfaceView surfaceView; private SurfaceHolder surfaceHolder; private MediaRecorder mediaRecorder; private boolean isRecording = false; private Handler handler = new Handler(); private static final int RECORD_DURATION = 10000; // 10秒 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recordBtn = findViewById(R.id.recordBtn); surfaceView = findViewById(R.id.surfaceView); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); // 动态申请权限(Android 6.0+) if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, 100); } recordBtn.setOnClickListener(v -> { if (!isRecording) { startRecording(); recordBtn.setText("录制中..."); // 10秒后自动停止录制 handler.postDelayed(() -> { stopRecording(); recordBtn.setText("开始录制"); }, RECORD_DURATION); } }); } private void startRecording() { mediaRecorder = new MediaRecorder(); // 配置录制源 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 配置输出格式与编码 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 配置视频参数 mediaRecorder.setVideoSize(1280, 720); mediaRecorder.setVideoFrameRate(30); // 绑定预览Surface mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); // 设置内部存储输出路径(仅当前应用可访问) File outputFile = new File(getFilesDir(), "recorded_video.mp4"); mediaRecorder.setOutputFile(outputFile.getAbsolutePath()); try { mediaRecorder.prepare(); mediaRecorder.start(); isRecording = true; } catch (IOException e) { e.printStackTrace(); } } private void stopRecording() { if (mediaRecorder != null && isRecording) { try { mediaRecorder.stop(); } catch (RuntimeException e) { // 处理录制未正常启动的异常,清理无效文件 File outputFile = new File(getFilesDir(), "recorded_video.mp4"); if (outputFile.exists()) outputFile.delete(); } finally { mediaRecorder.release(); mediaRecorder = null; isRecording = false; } } } @Override public void surfaceCreated(SurfaceHolder holder) {} @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mediaRecorder != null) { mediaRecorder.release(); mediaRecorder = null; } } @Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacksAndMessages(null); if (mediaRecorder != null) { mediaRecorder.release(); mediaRecorder = null; } } }
关键说明
- 内部存储特性:使用
getFilesDir()获取应用专属内部目录,无需申请外部存储权限,文件仅当前应用可访问。 - MediaRecorder配置顺序:必须严格遵循「设置源→输出格式→编码→参数→输出文件→prepare→start」的流程,否则会抛出异常。
- 异常处理:录制停止时需捕获RuntimeException,避免因录制未正常启动导致的崩溃,并清理无效文件。
内容的提问来源于stack exchange,提问作者Adnan Siddique
相关产品推荐
相关产品推荐

