You need to enable JavaScript to run this app. 安卓APP通过Intent调用系统录像按录制键后录制立即停止
优惠活动
大模型
产品
解决方案
定价
更多

安卓APP通过Intent调用系统录像按录制键后录制立即停止

安卓录像功能异常问题

问题描述

  • 正在开发个人第一款安卓应用,核心功能是录制45秒视频,基于视频内容计算脉搏值
  • 采用轻量方案实现录像:通过startActivityForResult()调用系统自带的录像界面,实现逻辑与常规的Intent录视频开发范式一致
  • 运行异常:系统录像界面可正常启动,但按下录制按钮后,视频刚启动录制就立刻停止;Logcat无相关报错信息,日志中完全不涉及项目自身的源码逻辑
  • 状态验证:录像界面启动后,按下录制按钮时,界面短暂显示录制计时与运行状态,随即自动跳回未录制的初始页面,全程无明显报错提示

项目相关实现代码

1. MainActivity.java

public class MainActivity extends AppCompatActivity implements SensorEventListener {
    private Camera c;
    private CameraView cv1;
    private FrameLayout view_camera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (!(getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))) {
            this.finish();
            System.exit(0);
        }

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        VideoCapture video_capture;

        Button button_symptoms = (Button)findViewById(R.id.button_symptoms);
        Button button_upload_signs = (Button)findViewById(R.id.button_upload_signs);
        Button button_measure_heart_rate = (Button)findViewById(R.id.button_measure_heart_rate);
        Button button_measure_respiratory_rate = (Button)findViewById(R.id.button_measure_respiratory_rate);

        cv1 = new CameraView(getApplicationContext(), this);
        view_camera = (FrameLayout)findViewById(R.id.view_camera);
        view_camera.addView(cv1);

        TextView finger_on_sensor = (TextView)findViewById(R.id.text_finger_on_sensor);
        finger_on_sensor.setVisibility(View.INVISIBLE);
        finger_on_sensor.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View arg_view, MotionEvent arg_me) {
                finger_on_sensor.setVisibility(View.INVISIBLE);
                File file_video = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/video_finger.mp4");
                final int VIDEO_CAPTURE = 1;
                StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
                StrictMode.setVmPolicy(builder.build());
                Intent intent_record_video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                intent_record_video.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 45);
                Uri fileUri = FileProvider.getUriForFile(MainActivity.this, "com.example.cse535a1.provider", file_video);
                List<ResolveInfo> resInfoList = getApplicationContext().getPackageManager().queryIntentActivities(intent_record_video, PackageManager.MATCH_DEFAULT_ONLY);
                for (ResolveInfo resolveInfo : resInfoList) {
                    String packageName = resolveInfo.activityInfo.packageName;
                    getApplicationContext().grantUriPermission(packageName, fileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
                intent_record_video.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
                startActivityForResult(intent_record_video, VIDEO_CAPTURE);
                return false;
            }

        });

        button_symptoms.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg_view) {
                Intent intent = new Intent(getApplicationContext(), Loggin_symptoms.class);
                startActivity(intent);
            }
        });

        button_upload_signs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg_view) {

            }
        });

        button_measure_heart_rate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg_view) {
                finger_on_sensor.setVisibility(View.VISIBLE);
            }
        });

        button_measure_respiratory_rate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg_view) {
                SensorManager manager_sensor = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
                Sensor sensor_accelerometer = manager_sensor.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
                manager_sensor.registerListener(MainActivity.this, sensor_accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
            }
        });
    }

    public void setCam(Camera arg_camera) {
        c = arg_camera;
    }

    @Override
    public void onSensorChanged(SensorEvent arg_event) {
        float x = arg_event.values[0];
        float y = arg_event.values[1];
        float z = arg_event.values[2];
        Log.i("ACCELEROMETER", String.valueOf(x) + ' ' + String.valueOf(y) + ' ' + String.valueOf(z));
    }

    @Override
    public void onAccuracyChanged(Sensor arg_sensor, int arg_accuracy) {

    }

    public Camera getcam() {
        Camera c = null;
        try { c = Camera.open(0); }
        catch (Exception e) {
        }
        return c;
    }

    @Override
    protected void onPause() {
        super.onPause();
        c.unlock();
//        if (c != null) {
//            c.stopPreview();
//            c.release();
//            c = null;
//        }
    }

    @Override
    protected void onResume() {
        super.onResume();
//        if (c != null) {
//            c.stopPreview();
//            c.release();
//            c = null;
//        }
//        cv1 = new CameraView(getApplicationContext(), this);
//        view_camera.addView(cv1);
    }

    @Override
    protected void onDestroy() {
        if (c != null) {
            c.stopPreview();
            c.release();
            c = null;
        }
        super.onDestroy();
    }

}

2. CameraView.java

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder holder_surface;
    private Camera camera_selected;
    MainActivity act1;

    public CameraView(Context arg_context, MainActivity arg_activity) {
        super(arg_context);
        act1 = arg_activity;
        // 注册SurfaceHolder回调,监听底层Surface创建与销毁状态
        holder_surface = getHolder();
        holder_surface.addCallback(this);
        // 兼容Android 3.0以下版本的必填配置
        holder_surface.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder arg_holder) {
        // Surface创建完成,绑定相机预览渲染目标
        try {
            Camera c = null;
            try {
                c = Camera.open(0);
            } catch (Exception e) {
                Log.e("CAMERA", "Camera not opened");
            }
            act1.setCam(c);
            camera_selected = c;
            camera_selected.setPreviewDisplay(arg_holder);
        } catch (IOException e) {
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // 预留:在Activity中统一处理相机预览释放逻辑
    }

    public void surfaceChanged(SurfaceHolder arg_holder, int arg_format, int arg_width, int arg_height) {
        // 处理预览尺寸、旋转角度变化场景,调整前后先停止现有预览
        if (holder_surface.getSurface() == null){
            // 预览Surface不存在,直接返回
            return;
        }

        try {
            camera_selected.stopPreview();
        } catch (Exception e){
            // 忽略停止不存在预览的异常
        }

        // 配置新的预览参数后重新启动预览
        try {
            camera_selected.setPreviewDisplay(holder_surface);
            camera_selected.startPreview();
        } catch (Exception e){
        }
    }
}

3. AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cse535a1">

    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    <application
        android:requestLegacyExternalStorage="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.CSE535A1">
        <activity android:name=".Loggin_symptoms"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.cse535a1.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths">
            </meta-data>
        </provider>
    </application>

</manifest>

内容的提问来源于stack exchange,提问作者Vishwad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 14:15:01