浏览代码

add: 新增录像接口

huwanxiao 1 年之前
父节点
当前提交
9b4f012424

+ 1 - 0
app/src/main/AndroidManifest.xml

@@ -11,6 +11,7 @@
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
     <uses-feature android:name="android.hardware.camera.any" />
 
     <application

+ 109 - 17
app/src/main/java/com/naz/sdkdemo/MainActivity.java

@@ -45,13 +45,11 @@ import com.naz.sdkdemo.base.BaseActivity;
 import com.naz.sdkdemo.bean.PrintModule;
 import com.naz.sdkdemo.bean.PrintModule2;
 import com.naz.sdkdemo.bean.PrintModule3;
-import com.naz.sdkdemo.comm.Constants;
 import com.naz.sdkdemo.helper.SerialPortManager;
 import com.naz.sdkdemo.http.ApiHelper;
 import com.naz.sdkdemo.utils.MyTools;
-import com.naz.sdkdemo.utils.SPUtils;
-import com.naz.sdkdemo.utils.SerialUtil;
 import com.naz.sdkdemo.weight.UserCache;
+import com.naz.sdkdemo.weight.XToast;
 //import com.tencent.smtt.export.external.interfaces.WebResourceError;
 //import com.tencent.smtt.export.external.interfaces.WebResourceRequest;
 //import com.tencent.smtt.sdk.WebSettings;
@@ -68,11 +66,10 @@ import java.io.File;
 import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Objects;
+import java.util.Locale;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -82,6 +79,11 @@ import androidx.camera.core.ImageCapture;
 import androidx.camera.core.ImageCaptureException;
 import androidx.camera.core.Preview;
 import androidx.camera.lifecycle.ProcessCameraProvider;
+import androidx.camera.video.MediaStoreOutputOptions;
+import androidx.camera.video.Recorder;
+import androidx.camera.video.Recording;
+import androidx.camera.video.VideoCapture;
+import androidx.camera.video.VideoRecordEvent;
 import androidx.camera.view.PreviewView;
 import androidx.core.app.ActivityCompat;
 import androidx.core.content.ContextCompat;
@@ -114,6 +116,9 @@ public class MainActivity extends BaseActivity {
     private ProcessCameraProvider cameraProvider;
     private ImageCapture imageCapture;
 
+    private VideoCapture videoCapture;
+    private Recording recording;
+
     private String bleName;
     private int code=0;//0默认值,1未搜索到设备,2连接失败,3连接成功,4断开了,5打开通知失败,6打开通知成功
 
@@ -367,6 +372,12 @@ public class MainActivity extends BaseActivity {
         }
 
         @JavascriptInterface
+        public void openRecorder(boolean isShowPreview) {
+            Log.e(TAG, "openRecorder");
+            toOpenRecorder(isShowPreview);
+        }
+
+        @JavascriptInterface
         public void getAllPort() {
             // 遍历串口
             SerialPortFinder finder = new SerialPortFinder();
@@ -520,6 +531,10 @@ public class MainActivity extends BaseActivity {
         if(previewViewLayout.getVisibility() == View.VISIBLE) {
             previewViewLayout.setVisibility(View.GONE);
         }
+        // 关闭的时候摄像头还在录像
+        if(recording!=null) {
+            openAndCloseVideo();
+        }
         if (cameraProvider!=null){
             cameraProvider.unbindAll();
         }
@@ -533,7 +548,7 @@ public class MainActivity extends BaseActivity {
         cameraProviderFuture.addListener(() -> {
             try {
                 ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
-                bindPreview(cameraProvider, isShowPreview);
+                bindPreview(cameraProvider, isShowPreview, 1);
             } catch (Exception e) {
                 // No errors need to be handled for this Future.
                 // This should never be reached.
@@ -542,6 +557,23 @@ public class MainActivity extends BaseActivity {
         }, ContextCompat.getMainExecutor(this));
     }
 
+    private void toOpenRecorder(boolean isShowPreview) {
+        cameraIsOpening = true;
+        // 请求 CameraProvider
+        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
+        //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
+        cameraProviderFuture.addListener(() -> {
+            try {
+                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
+                bindPreview(cameraProvider, isShowPreview, 2);
+            } catch (Exception e) {
+                // No errors need to be handled for this Future.
+                // This should never be reached.
+                Log.i(TAG, "toOpenRecorder: exception: " + e.getMessage());
+            }
+        }, ContextCompat.getMainExecutor(this));
+    }
+
     private void toTakePhoto(String path, String name) {
         Log.e("-------->","------>toTakePhoto");
         long timeStamp = System.currentTimeMillis();
@@ -585,6 +617,51 @@ public class MainActivity extends BaseActivity {
                 });
     }
 
+    private void openAndCloseVideo() {
+        if (videoCapture != null) {
+            if (recording != null) {
+                recording.stop();
+                recording = null;
+                return;
+            }
+            String name = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS", Locale.SIMPLIFIED_CHINESE).format(System.currentTimeMillis()) + ".mp4";
+            ContentValues contentValues = new ContentValues();
+            contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
+            contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+                contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, "Movies/CameraX-Video");
+            }
+            MediaStoreOutputOptions mediaStoreOutputOptions = new MediaStoreOutputOptions
+                    .Builder(getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
+                    .setContentValues(contentValues)
+                    .build();
+            Recorder recorder = (Recorder) videoCapture.getOutput();
+            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
+                return;
+            }
+            recording = recorder.prepareRecording(this, mediaStoreOutputOptions)
+                    .withAudioEnabled()
+                    .start(ContextCompat.getMainExecutor(this), videoRecordEvent -> {
+                        if (videoRecordEvent instanceof VideoRecordEvent.Start) {
+                           // 开始录像
+                            XToast.showToast("开始录制");
+                        } else if (videoRecordEvent instanceof VideoRecordEvent.Finalize) {
+                            if (((VideoRecordEvent.Finalize) videoRecordEvent).hasError()) {
+                                // 中途意外结束
+                                if (recording != null) {
+                                    recording.close();
+                                    recording = null;
+                                }
+                            } else {
+                                // 正常结束
+                                String msg = "视频为" + ((VideoRecordEvent.Finalize) videoRecordEvent).getOutputResults().getOutputUri();
+                                XToast.showToast("录像保存成功");
+                            }
+                        }
+                    });
+        }
+    }
+
     boolean isStart = false;
     ExecutorService fixedThreadPool;
     private void savePicture(File file, String path, String name) {
@@ -778,8 +855,9 @@ public class MainActivity extends BaseActivity {
         }
     }
 
-    //选择相机并绑定生命周期和用例
-    private void bindPreview(@NonNull ProcessCameraProvider cp, boolean isShowPreview) {
+    // 选择相机并绑定生命周期和用例
+    // bindType: 1-绑定照相机, 2-绑定录像机
+    private void bindPreview(@NonNull ProcessCameraProvider cp, boolean isShowPreview, int bindType) {
         this.cameraProvider=cp;
         Preview preview = new Preview.Builder()
                 .build();
@@ -788,20 +866,34 @@ public class MainActivity extends BaseActivity {
         CameraSelector cameraSelector = new CameraSelector.Builder()
                 .requireLensFacing(CameraSelector.LENS_FACING_BACK)//CameraSelector.LENS_FACING_EXTERNAL
                 .build();
-        // 创建一个 ImageCapture 对象,用于拍摄照片。
-        // 设置拍照模式为最小化延迟模式,这意味着拍照时将尽可能快地捕获图像。
-        imageCapture = new ImageCapture.Builder()
-                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
-                    // 设置JPEG的质量为85%
-                .setJpegQuality(85)
-                .build();
         // 打开摄像头的同时是否显示预览界面
         if(isShowPreview) {
            preview.setSurfaceProvider(previewView.getSurfaceProvider());
            previewViewLayout.setVisibility(View.VISIBLE);
         }
         cameraProvider.unbindAll();//解绑组件
-        cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture);
+        if(bindType == 1) {
+            // 创建一个 ImageCapture 对象,用于拍摄照片。
+            // 设置拍照模式为最小化延迟模式,这意味着拍照时将尽可能快地捕获图像。
+            videoCapture = null;
+            imageCapture = new ImageCapture.Builder()
+                    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
+                    // 设置JPEG的质量为85%
+                    .setJpegQuality(85)
+                    .build();
+            cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture);
+        }else if(bindType == 2) {
+            // 创建一个 videoCapture 对象,用于录像
+            // 打开后自动录像
+            boolean isAutoTake = true;
+            imageCapture = null;
+            Recorder recorder = new Recorder.Builder().build();
+            videoCapture = VideoCapture.withOutput(recorder);
+            cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, videoCapture);
+            if(isAutoTake) {
+                openAndCloseVideo();
+            }
+        }
 //        preview.setSurfaceProvider(previewView.getSurfaceProvider());
     }
 

+ 2 - 1
app/src/main/java/com/naz/sdkdemo/SplashActivity.java

@@ -30,7 +30,8 @@ public class SplashActivity extends Activity {
         String[] PERMISSIONS_STORAGE = new String[]{
                 Manifest.permission.READ_EXTERNAL_STORAGE,
                 Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                Manifest.permission.CAMERA
+                Manifest.permission.CAMERA,
+                Manifest.permission.RECORD_AUDIO
         };
 
         if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {