RK Android7.1 Camera2 预览、内置客户SDK预览

 一.预览

1.SurfaceView 

  activity_main.xml

 AndroidManifest

Mainactivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.gatsby.ypcamerdemo;
 
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
 
import androidx.appcompat.app.AppCompatActivity;
 
import java.io.IOException;
 
public class MainActivity extends AppCompatActivity {
 
    private SurfaceView sfv_preview;
    private Camera camera = null;
    private SurfaceHolder.Callback cpHolderCallback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            startPreview();
        }
 
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
 
        }
 
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            stopPreview();
        }
    };
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }
 
    private void bindViews() {
        sfv_preview = (SurfaceView) findViewById(R.id.sfv_preview);
        sfv_preview.getHolder().addCallback(cpHolderCallback);
    }
 
    //开始预览
    private void startPreview() {
        camera = Camera.open();
        try {
            camera.setPreviewDisplay(sfv_preview.getHolder());
            camera.setDisplayOrientation(0);
            camera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    //停止预览
    private void stopPreview() {
        camera.stopPreview();
        camera.release();
        camera = null;
    }
 
}

2.TextureView

  • CameraManager: 管理手机上的所有摄像头设备,它的作用主要是获取摄像头列表和打开指定的摄像头
  • CameraDevice: 具体的摄像头设备,它有一系列参数(预览尺寸、拍照尺寸等),可以通过CameraManager的getCameraCharacteristics()方法获取。它的作用主要是创建CameraCaptureSession和CaptureRequest
  • CameraCaptureSession: 相机捕获会话,用于处理拍照和预览的工作(很重要)
  • CaptureRequest: 捕获请求,定义输出缓冲区以及显示界面(TextureView或SurfaceView)等  

activity_main.xml   

Mainactivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package com.gatsby.textureviewtest;
 
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
 
import androidx.appcompat.app.AppCompatActivity;
 
import java.util.Arrays;
 
public class MainActivity extends AppCompatActivity {
 
    private TextureView textureView;
    private String TAG="Gatsby";
 
    private HandlerThread mThreadHandler;
    private Handler mHandler;
 
    private CaptureRequest.Builder mPreviewBuilder;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mThreadHandler = new HandlerThread("CAMERA2");
        mThreadHandler.start();
        mHandler = new Handler(mThreadHandler.getLooper());
 
        textureView= (TextureView) findViewById(R.id.textureview);
        textureView.setSurfaceTextureListener(textureListener);
 
    }
 
    private TextureView.SurfaceTextureListener textureListener=new TextureView.SurfaceTextureListener() {
        @SuppressLint("MissingPermission")
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
            Log.e(TAG,"可用");
 
            //CameraManaer 摄像头管理器,用于检测摄像头,打开系统摄像头
            CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
            try {
                String[] CameraIdList=cameraManager.getCameraIdList();//获取可用相机列表
                Log.e(TAG,"可用相机的个数是:"+CameraIdList.length);
                //获取某个相机(摄像头特性)
                CameraCharacteristics cameraCharacteristics=cameraManager.getCameraCharacteristics(CameraIdList[0]);
                cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);//检查支持
                cameraManager.openCamera(CameraIdList[0],mCameraDeviceStateCallback, mHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
 
        }
 
        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
            Log.e(TAG,"change");
        }
 
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
            Log.e(TAG,"destroy");
            return false;
        }
 
        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
            Log.e(TAG,"update");
        }
    };
 
    //CameraDeviceandroid.hardware.Camera也就是Camera1的Camera
    private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice camera) {
            try {
                startPreview(camera);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }
 
        @Override
        public void onDisconnected(CameraDevice camera) {
 
        }
 
        @Override
        public void onError(CameraDevice camera, int error) {
 
        }
    };
 
    /**
     * @param camera
     * @throws CameraAccessException
     * 开始预览
     */
    private void startPreview(CameraDevice camera) throws CameraAccessException {
        SurfaceTexture texture = textureView.getSurfaceTexture();
        texture.setDefaultBufferSize(textureView.getWidth(), textureView.getHeight());
        Surface surface = new Surface(texture);
        try {
            //CameraRequest表示一次捕获请求,用来对z照片的各种参数设置,比如对焦模式、曝光模式等。CameraRequest.Builder用来生成CameraRequest对象
            mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
 
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        mPreviewBuilder.addTarget(surface);
        camera.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, mHandler);
    }
 
    //CameraCaptureSession 这个对象控制摄像头的预览或者拍照
    //setRepeatingRequest()开启预览,capture()拍照
    //StateCallback监听CameraCaptureSession的创建
    private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(CameraCaptureSession session) {
            Log.e(TAG,"相机创建成功!");
            try {
                session.capture(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);//拍照
                session.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);//返回结果
            } catch (CameraAccessException e) {
                e.printStackTrace();
                Log.e(TAG,"这里异常");
            }
        }
 
        @Override
        public void onConfigureFailed(CameraCaptureSession session) {
            Log.e(TAG,"相机创建失败!");
        }
    };
 
 
    //CameraCaptureSession.CaptureCallback监听拍照过程
    private CameraCaptureSession.CaptureCallback mSessionCaptureCallback = new CameraCaptureSession.CaptureCallback() {
 
        @Override
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
            Log.e(TAG,"这里接受到数据"+result.toString());
        }
 
        @Override
        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult){
 
        }};
}

 

二.Android camera2预览界面流程  https://blog.csdn.net/fireness/article/details/50594706

2.1.找到布局

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<com.android.camera.ui.MainActivityLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_root_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@null">
 
    <include layout="@layout/camera" />
    <include layout="@layout/camera_filmstrip" />
    <com.android.camera.ui.ModeTransitionView
        android:id="@+id/mode_transition_view"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
</com.android.camera.ui.MainActivityLayout>

 预览布局 camera.xml 

1
2
3
4
5
6
7
8
9
10
11
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/camera_app_root"
    android:background="@android:color/black"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <TextureView
        android:id="@+id/preview_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

2.1.CameraActivity.java  onCreateTasks() 准备预览mCameraAppUI.prepareModuleUI();

   packages\apps\Camera2\src\com\android\camera\app\CameraAppUI.java 

1
2
3
4
5
6
7
8
public void prepareModuleUI() {
    mController.getSettingsManager().addListener(this);
    mModuleUI = (FrameLayout) mCameraRootView.findViewById(R.id.module_layout);
    mTextureView = (TextureView) mCameraRootView.findViewById(R.id.preview_content);
    mTextureViewHelper = new TextureViewHelper(mTextureView, mCaptureLayoutHelper,
            mController.getCameraProvider(), mController);
    mTextureViewHelper.setSurfaceTextureListener(this);
    mTextureViewHelper.setOnLayoutChangeListener(mPreviewLayoutChangeListener);

2.3.TextureViewHelper 初始化 

packages\apps\Camera2\src\com\android\camera\TextureViewHelper.java

1
2
3
4
5
6
7
8
9
10
11
12
13
public TextureViewHelper(TextureView preview, CaptureLayoutHelper helper,
        CameraProvider cameraProvider, AppController appController) {
    mPreview = preview;
    mCameraProvider = cameraProvider;
    mPreview.addOnLayoutChangeListener(this);
    mPreview.setSurfaceTextureListener(this);
    mCaptureLayoutHelper = helper;
    mAppController = appController;
    mCameraModeId = appController.getAndroidContext().getResources()
            .getInteger(R.integer.camera_mode_photo);
    mCaptureIntentModeId = appController.getAndroidContext().getResources()
            .getInteger(R.integer.camera_mode_capture_intent);
} 

 还要去实现  implements TextureView.SurfaceTextureListener

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    // Workaround for b/11168275, see b/10981460 for more details
    if (mWidth != 0 && mHeight != 0) {
        // Re-apply transform matrix for new surface texture
        updateTransform();
    }
    if (mSurfaceTextureListener != null) {
        mSurfaceTextureListener.onSurfaceTextureAvailable(surface, width, height);
    }
}
 
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    if (mSurfaceTextureListener != null) {
        mSurfaceTextureListener.onSurfaceTextureSizeChanged(surface, width, height);
    }
}

packages\apps\Camera2\src\com\android\camera\PhotoUI.java

1
2
3
4
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    mController.onPreviewUIReady();
}

2.4.packages\apps\Camera2\src\com\android\camera\PhotoModule.java 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    @Override
    public void onPreviewUIReady() {
        Log.i(TAG, "onPreviewUIReady");
        startPreview();
    }
 
    private void startPreview() {
        if (mCameraDevice == null) {
            Log.i(TAG, "attempted to start preview before camera device");
            // do nothing
            return;
        }
 
…………………………
        Log.i(TAG, "startPreview");
        // If we're using API2 in portability layers, don't use startPreviewWithCallback()
        // b/17576554
        CameraAgent.CameraStartPreviewCallback startPreviewCallback =
            new CameraAgent.CameraStartPreviewCallback() {
                @Override
                public void onPreviewStarted() {
                    mFocusManager.onPreviewStarted();
                    PhotoModule.this.onPreviewStarted();
                    SessionStatsCollector.instance().previewActive(true);
                    if (mSnapshotOnIdle
                            || (mAppController.getSettingsManager().getBoolean
                            (SettingsManager.SCOPE_GLOBAL, Keys.KEY_SMILE_SHUTTER_ON)
                            && DebugPropertyHelper.isSmileShutterAuto())) {
                        mHandler.postDelayed(mDoSmileShutterRunnable, 2000);
                    }
                }
            };

  

 三.内置SDK 预览

3.1.客户demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private var mSurfaceTexture: SurfaceTexture? = null
private var mSurface: Surface? = null
 
 
private val mSurfaceTextureListener: SurfaceTextureListener = object : SurfaceTextureListener {
    override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
        mSurfaceTexture = surface
    }
 
    override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {
        mSurfaceTexture = surface
    }
 
    override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
        mSurfaceTexture = surface
        return false
    }
 
    override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
        mSurfaceTexture = surface
    }
}
 
 
private fun initView() {
    if (mSurface == null && mSurfaceTexture != null) {
        mSurface = Surface(mSurfaceTexture)
    }
 
    mYpDevicesManager = YpDevicesManager.getInstance()
    mYpDevicesManager?.setContext(this)
    mYpDevicesManager?.setCodereaderCameraView(mSurface)

3.2.客户是特殊的USB3.0摄像头 走的不是 Camera open(int cameraId) 方法  而Camera2 预览走的流程是标准的 open方法
原计划是在Camera2 预览控件TextureView做动作 现在不走open 表示要大改预览框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
08-17 16:17:35.796 E/CameraService(  244): No camera be found ! check again...
08-17 16:17:35.796 I/CameraService(  244): CameraService process starting
08-17 16:17:35.797 I/CAM2PORT_AndCamAgntImp( 1442): Opening camera 0 with camera1 API
08-17 16:17:35.797 D/CameraHal(  244): Calling process is: com.android.camera2
08-17 16:17:35.798 I/CameraService(  244): CameraService::connect call (PID -1 "com.android.camera2", camera ID 0) for HAL version default and Camera API version 1
08-17 16:17:35.798 E/CameraService(  244): CameraService::connect X (PID 1442) rejected (invalid camera ID 0)
08-17 16:17:35.798 W/CameraBase( 1442): An error occurred while connecting to camera 0: Service not available
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442): RuntimeException during CameraAction[OPEN_CAMERA] at CameraState[1]
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442): java.lang.RuntimeException: Fail to connect to camera service
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442):     at android.hardware.Camera.<init>(Camera.java:496)
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442):     at android.hardware.Camera.open(Camera.java:345)
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442):     at com.android.ex.camera2.portability.AndroidCameraAgentImpl$CameraHandler.handleMessage(AndroidCameraAgentImpl.java:384)
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442):     at android.os.Handler.dispatchMessage(Handler.java:102)
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442):     at android.os.Looper.loop(Looper.java:154)
08-17 16:17:35.799 E/CAM2PORT_AndCamAgntImp( 1442):     at android.os.HandlerThread.run(HandlerThread.java:61)
08-17 16:17:35.801 D/CameraHal(  244): createInstance(1041): open xml file(/etc/cam_board.xml) success
08-17 16:17:35.801 E/CameraHal(  244): cam_board.xml version(v0x0.0x0.0x0) != xml parser version(v0x0.0xf.0x0)

 不使用反射 修改标准Surface 将客户SDK api 封装进去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
diff --git a/frameworks/base/core/java/android/view/Surface.java b/frameworks/base/core/java/android/view/Surface.java
old mode 100644
new mode 100755
index 22e68a3..78c78d0
--- a/frameworks/base/core/java/android/view/Surface.java
+++ b/frameworks/base/core/java/android/view/Surface.java
@@ -31,6 +31,11 @@ import java.lang.annotation.RetentionPolicy;
  
 import dalvik.system.CloseGuard;
  
+import android.os.SystemProperties;
+import java.lang.reflect.Method;
+import com.yp.ypcodereader.manager.YpDevicesManager;
+import android.view.TextureView;
+
 /**
  * Handle onto a raw buffer that is being managed by the screen compositor.
  *
@@ -158,8 +163,10 @@ public class Surface implements Parcelable {
     public Surface() {
     }
  
+    private Surface xhSurface;
+   
     /**
-     * Create Surface from a {@link SurfaceTexture}.
+     * Create Surface from a {@link SurfaceTex ture}.
      *
      * Images drawn to the Surface will be made available to the {@link
      * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link
@@ -178,8 +185,19 @@ public class Surface implements Parcelable {
             mName = surfaceTexture.toString();
             setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
         }
+        if(TextureView.xhSurface_flag) {
+            GetXSurface(surfaceTexture);
+        }                   
     }
  
+    public void GetXSurface(SurfaceTexture surfaceTexture) {
+        TextureView.xhSurface_flag = false;
+        xhSurface = new Surface(surfaceTexture);
+        TextureView.ypDevicesManager.setCodereaderCameraView(xhSurface);
+        TextureView.ypDevicesManager.openCodereaderCamera(null);
+    }
+
+
     /* called from android_view_Surface_createFromIGraphicBufferProducer() */
     private Surface(long nativeObject) {
         synchronized (mLock) {
@@ -225,6 +243,7 @@ public class Surface implements Parcelable {
      */
     public void destroy() {
         release();
+        TextureView.ypDevicesManager.closeCodereaderCamera();
     }
  
     /**
diff --git a/frameworks/base/core/java/android/view/TextureView.java b/frameworks/base/core/java/android/view/TextureView.java
old mode 100644
new mode 100755
index 645ab5c..0582f5d
--- a/frameworks/base/core/java/android/view/TextureView.java
+++ b/frameworks/base/core/java/android/view/TextureView.java
@@ -27,6 +27,14 @@ import android.graphics.SurfaceTexture;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.text.TextUtils;
+import android.os.SystemProperties;
+import android.app.ActivityManager;
+import android.content.ComponentName;
+
+import com.yp.ypcodereader.manager.YpDevicesManager;
+
+import java.util.List;
  
 /**
  * <p>A TextureView can be used to display a content stream. Such a content
@@ -123,6 +131,12 @@ public class TextureView extends View {
     private Canvas mCanvas;
     private int mSaveCount;
  
+    public static YpDevicesManager ypDevicesManager;
+    private String outPackageInfo;
+    private String CLASS_NAME = "com.gatsby.ypcamerademo2.MainActivity";
+    public static boolean xhSurface_flag;
+   
+
     private final Object[] mNativeWindowLock = new Object[0];
     // Set by native code, do not write!
     private long mNativeWindow;
@@ -144,8 +158,27 @@ public class TextureView extends View {
      */
     public TextureView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        boolean packageInfo = isForeground(context,CLASS_NAME);       
+        if(packageInfo){
+            xhSurface_flag = true;
+            ypDevicesManager = new YpDevicesManager().getInstance();
+            ypDevicesManager.setContext(context);               
+        }       
+    }
+
+    public static boolean isForeground(Context context, String className) {
+        if (context == null || TextUtils.isEmpty(className))
+            return false;
+        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
+        if (list != null && list.size() > 0) {
+            ComponentName cpn = list.get(0).topActivity;
+            if (className.equals(cpn.getClassName()))
+                return true;
+        }
+        return false;
     }
-
+   
     /**
      * Creates a new TextureView.
      *

  

 

posted @   CrushGirl  阅读(584)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示