安卓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
相关产品推荐
相关产品推荐

