Browse Source

add: 相机预览功能

huwanxiao 1 year ago
parent
commit
dc309c7829

+ 50 - 10
app/src/main/java/com/naz/sdkdemo/MainActivity.java

@@ -26,6 +26,7 @@ import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.Button;
 import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
 import android.widget.Toast;
 
 import com.clj.fastble.BleManager;
@@ -66,7 +67,6 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -76,6 +76,7 @@ import androidx.camera.core.ImageCapture;
 import androidx.camera.core.ImageCaptureException;
 import androidx.camera.core.Preview;
 import androidx.camera.lifecycle.ProcessCameraProvider;
+import androidx.camera.view.PreviewView;
 import androidx.core.app.ActivityCompat;
 import androidx.core.content.ContextCompat;
 import androidx.lifecycle.LifecycleOwner;
@@ -91,6 +92,7 @@ public class MainActivity extends BaseActivity {
     private LinearLayout ll_web;
 
     private Button printBtn;
+    private LinearLayout bottomToolBar;
     private Button connectBtn;
     private Button connectLight;
     private Button turnOnLight;
@@ -99,12 +101,17 @@ public class MainActivity extends BaseActivity {
 
     String savePath;
     private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
+    private PreviewView previewView;
+    private RelativeLayout previewViewLayout;
     private ProcessCameraProvider cameraProvider;
     private ImageCapture imageCapture;
 
     private String bleName;
     private int code=0;//0默认值,1未搜索到设备,2连接失败,3连接成功,4断开了,5打开通知失败,6打开通知成功
 
+    // 相机现在是否正在打开, 用于处理用户在照相机预览页面点击返回按钮的情况
+    private boolean cameraIsOpening = false;
+
     @Override
     protected int getLayoutResId() {
         return R.layout.activity_home_web;
@@ -112,9 +119,13 @@ public class MainActivity extends BaseActivity {
 
     @Override
     protected void initView() {
+
         ll_nonet = findViewById(R.id.ll_nonet);
         ll_web = findViewById(R.id.ll_web);
         mWebView = findViewById(R.id.webview);
+        previewView = findViewById(R.id.previewView);
+        previewViewLayout = findViewById(R.id.rl_preview);
+
         checkNet();
         findViewById(R.id.bt_ref).setOnClickListener(new View.OnClickListener(){
 
@@ -198,6 +209,14 @@ public class MainActivity extends BaseActivity {
             }
         });
 
+        // 照相机预览框底部工具栏
+        bottomToolBar = findViewById(R.id.ll_bottom_tool_bar);
+        bottomToolBar.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                toCloseCamera();
+            }
+        });
         printBtn = findViewById(R.id.print);
         printBtn.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -399,11 +418,11 @@ public class MainActivity extends BaseActivity {
         }
 
         @JavascriptInterface
-        public void openCamera() {
+        public void openCamera(boolean isShowPreview) {
             Log.e(TAG, "openCamera");
-            toOpenCamera();
+            // 打开摄像头
+            toOpenCamera(isShowPreview);
         }
-
         @JavascriptInterface
         public void closeCamera() {
             Log.e(TAG, "closeCamera");
@@ -478,22 +497,29 @@ public class MainActivity extends BaseActivity {
     }
 
     private void toCloseCamera() {
+        // 如果相机预览还开着, 则关闭
+        cameraIsOpening = false;
+        if(previewViewLayout.getVisibility() == View.VISIBLE) {
+            previewViewLayout.setVisibility(View.GONE);
+        }
         if (cameraProvider!=null){
             cameraProvider.unbindAll();
         }
     }
 
-    private void toOpenCamera() {
+    private void toOpenCamera(boolean isShowPreview) {
+        cameraIsOpening = true;
         // 请求 CameraProvider
         cameraProviderFuture = ProcessCameraProvider.getInstance(this);
         //检查 CameraProvider 可用性,验证它能否在视图创建后成功初始化
         cameraProviderFuture.addListener(() -> {
             try {
                 ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
-                bindPreview(cameraProvider);
-            } catch (ExecutionException | InterruptedException e) {
+                bindPreview(cameraProvider, isShowPreview);
+            } catch (Exception e) {
                 // No errors need to be handled for this Future.
                 // This should never be reached.
+                Log.i(TAG, "toOpenCamera: exception: " + e.getMessage());
             }
         }, ContextCompat.getMainExecutor(this));
     }
@@ -735,7 +761,7 @@ public class MainActivity extends BaseActivity {
     }
 
     //选择相机并绑定生命周期和用例
-    private void bindPreview(@NonNull ProcessCameraProvider cp) {
+    private void bindPreview(@NonNull ProcessCameraProvider cp, boolean isShowPreview) {
         this.cameraProvider=cp;
         Preview preview = new Preview.Builder()
                 .build();
@@ -744,16 +770,20 @@ public class MainActivity extends BaseActivity {
         CameraSelector cameraSelector = new CameraSelector.Builder()
                 .requireLensFacing(CameraSelector.LENS_FACING_BACK)//CameraSelector.LENS_FACING_EXTERNAL
                 .build();
-// 创建一个 ImageCapture 对象,用于拍摄照片。
+        // 创建一个 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);
-
 //        preview.setSurfaceProvider(previewView.getSurfaceProvider());
     }
 
@@ -941,6 +971,16 @@ public class MainActivity extends BaseActivity {
         }
     }
 
+    @Override
+    public void onBackPressed() {
+        if(cameraIsOpening) {
+            // 当前的摄像头正在打开状态
+            toCloseCamera();
+            return;
+        }
+        super.onBackPressed();
+    }
+
     private boolean checkGPSIsOpen() {
 //        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
 //        if (locationManager == null)

+ 6 - 0
app/src/main/res/drawable/round_conner_20.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+  <solid android:color="#ffffffff" />
+  <corners android:radius="10dp"/>
+
+</shape>

+ 32 - 0
app/src/main/res/layout/activity_home_web.xml

@@ -15,6 +15,38 @@
             android:id="@+id/webview"/>
     </LinearLayout>
 
+    <RelativeLayout
+        android:id="@+id/rl_preview"
+        android:layout_width="400dp"
+        android:layout_height="300dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="@+id/ll_web"
+        app:layout_constraintEnd_toEndOf="@+id/ll_web"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@+id/ll_web">
+        <!--预览画面-->
+        <androidx.camera.view.PreviewView
+            android:id="@+id/previewView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center" />
+        <!--底部工具栏-->
+        <LinearLayout
+            android:id="@+id/ll_bottom_tool_bar"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_alignParentBottom="true"
+            android:background="@color/black_half"
+            android:gravity="center"
+            android:orientation="horizontal">
+
+            <ImageView
+                android:layout_width="30dp"
+                android:layout_height="30dp"
+                android:layout_gravity="center"
+                android:src="@mipmap/icon_close2" />
+        </LinearLayout>
+    </RelativeLayout>
     <LinearLayout
         android:visibility="gone"
         android:id="@+id/ll_nonet"

BIN
app/src/main/res/mipmap-xxhdpi/icon_close2.png


+ 1 - 0
app/src/main/res/values/colors.xml

@@ -7,6 +7,7 @@
     <color name="light_purple">#db639b</color>
     <color name="light_blue">#0bbbf7</color>
     <color name="black">#000000</color>
+    <color name="black_half">#80000000</color>
     <color name="white">#ffffff</color>
     <color name="dark_green">#05a102</color>
     <color name="plain">#cccccc</color>