将单独的类实现为Activity

时间:2017-06-24 19:14:25

标签: java android android-camera2

问题 在清理我的代码时,我想将我的Android摄像头方法移动到一个单独的类,符合我认为的最佳实践。经过一整天的搜索,我仍然在努力弄清楚如何做到这一点。主要问题是实现方法的差异以及从相机API到相机2 API的转变导致在线找到我无法复制的解决方案。请注意,我是Java的初学者,因此,这可能是一个非常新的错误,由于网络上的各种信息,我无法解决这个错误。

当前代码 我的主要问题是,startCamera()中的SurfaceTexture texture = surfaceView.getSurfaceTexture();表示Cannot resolve method 'getSurfaceTexture()',而previewBuilder.addTarget(texture);抱怨addTarget (android.view.surface) in Builder cannot be applied to (android.graphics.SurfaceTexture)

public class CameraView extends TextureView implements TextureView.SurfaceTextureListener{

    private Size previewsize;
    private CameraDevice cameraDevice;
    private CaptureRequest.Builder previewBuilder;
    private CameraCaptureSession previewSession;
    private final Context context;
    public SurfaceView surfaceView;
    public TextureView textureView;

    public CameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
        // Once the surface is created, simply open a handle to the camera hardware.
        openCamera();
    }

    public void onSurfaceTextureUpdated(SurfaceTexture texture) {
    }

    public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int     width, int height) {

        try {
            //cameraDevice.setPreviewDisplay(holder);

            //cameraDevice.startPreview();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
        // stopPreview();
        cameraDevice.close();
        return true;
    }

    public void openCamera()
    {
        CameraManager manager = (CameraManager) context.getSystemService (Context.CAMERA_SERVICE);
        try
        {
            String cameraId = manager.getCameraIdList()[0];
            CameraCharacteristics     characteristics=manager.getCameraCharacteristics(cameraId);
            StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
            previewsize = map.getOutputSizes(SurfaceTexture.class)[0];
            try {
                manager.openCamera(cameraId, stateCallback, null);
            } catch (SecurityException e){
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice camera) {
            cameraDevice = camera;
            startCamera();
        }
        @Override
        public void onClosed(CameraDevice camera) {
            // nothing
        }
        @Override
        public void onDisconnected(CameraDevice camera) {
        }
        @Override
        public void onError(CameraDevice camera, int error) {
        }
    };

    void startCamera()
    {
        if (cameraDevice == null || previewsize==null)
        {
            return;
        }

        SurfaceTexture texture = surfaceView.getSurfaceTexture();
texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());

        Surface surface = new Surface(texture);
        try
        {
            // add all the standard stuff to the previewBuilder
            previewBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        } catch (Exception e) {}
        previewBuilder.addTarget(texture);
        try
        {
            cameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(CameraCaptureSession session) {
                previewSession = session;
                getChangedPreview();
            }
            @Override
            public void onConfigureFailed(CameraCaptureSession session{
            }
        },null);
        } catch (Exception e) {}
    }

    void getChangedPreview()
    {
        previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);

        HandlerThread thread = new HandlerThread("changed Preview");
        thread.start();
        Handler handler = new Handler(thread.getLooper());
        try
        {
            previewSession.setRepeatingRequest(previewBuilder.build(), null, handler);
        }catch (Exception e){}
    }
}

目标 为了保持我的代码清洁和易懂,我想限制MainActivity类在视图之间切换,而不是在那里有大量的方法。我想通过将以下对象从INVISIBLE切换到VISIBLE来激活我的应用中的相机视图。其他建议表示赞赏。

cameraView = (CameraView) findViewById(R.id.camera);
然后

MainActivity.java看起来像:

public class MainActivity extends AppCompatActivity {

    private TextView mTextMessage;
    private CameraView cameraView;
    private MainSurfaceView mGLView;
    private TextureView textureView;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    mTextMessage.setText(R.string.title_home);
                    return true;
                case R.id.navigation_dashboard:
                    mTextMessage.setText(R.string.title_dashboard);
                    return true;
                case R.id.navigation_notifications:
                    mTextMessage.setText(R.string.title_notifications);
                    return true;
            }
            return false;
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextMessage = (TextView) findViewById(R.id.message);
        cameraView = (CameraView) findViewById(R.id.camera);
        mGLView = (MainSurfaceView) findViewById(R.id.glSurfaceView);
        BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

    }
}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

startCamera()中的

SurfaceTexture texture = surfaceView.getSurfaceTexture();表示Cannot resolve method 'getSurfaceTexture()'

您调用surfaceView的方法getSurfaceTexture。 surfaceView是一个SurfaceView。我们来看看文档: https://developer.android.com/reference/android/view/SurfaceView.html 显然,SurfaceView没有名为" getSurfaceTexture()"的方法。但是,在Google上搜索" getSurfaceTexture()Android"向我们展示了该方法属于TextureView类。您的类CameraView有一个名为" textureView"的字段,因此(我不知道您想要实现什么)可以根据需要调用该字段上的方法。另外你的类CameraView本身就是一个TextureView(你想要吗),所以如果你想在类本身上调用它,你也可以调用getSurfaceTexture()

previewBuilder.addTarget(texture);抱怨addTarget (android.view.surface) in Builder cannot be applied to (android.graphics.SurfaceTexture). 让我们再看看文档:{​​{3}} 显然,CaptureRequest.builder(previewBuilder的类型)有一个名为addTarget的方法,但该方法只接受Surface!你正在传递一个纹理。您可能希望将texture更改为surface