You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:31:03