Putting a separate class into action

Problem While cleaning up my code, I want to move my android camera methods into a separate class, according to what I think is best practice. After searching all day, I am still trying to figure out how to do this. The main problem is that differences in implementation methods and the move from the Camera API to the Camera2 API result in found online solutions that I cannot reproduce. Please note that I am fairly new to Java and as such this is probably a very newbie bug that I cannot solve due to the variety of information on the internet.

Current Code My main problem is what SurfaceTexture texture = surfaceView.getSurfaceTexture();

in startCamera () says Cannot resolve method 'getSurfaceTexture()'

and what it previewBuilder.addTarget(texture);

complains about 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){}
    }
}

      

Purpose To keep my code clean and understandable, I would like to restrict the MainActivity class to switch between views instead of having a ton of methods there. I would like to activate my camera view in my application by switching the next object from INVISIBLE

to VISIBLE

. Other suggestions are welcome.

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

      

MainActivity.java

will look like this:

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);

    }
}

      

Your help is appreciated!

+3


source to share


1 answer


SurfaceTexture texture = surfaceView.getSurfaceTexture();

in startCamera () says Cannot resolve method 'getSurfaceTexture()'

You are calling the getSurfaceTexture method of surfaceView. surfaceView - SurfaceView. Let's take a look at the documentation: https://developer.android.com/reference/android/view/SurfaceView.html Apparently the SurfaceView doesn't have a method called "getSurfaceTexture ()". However, a Google search for "getSurfaceTexture () Android" shows us that the method belongs to the TextureView class. Your CameraView class has a field called "textureView" so (I don't know exactly what you want to achieve) can call a method on that field if you want. Also, your CameraView class is the TextureView itself (you need that), so you can also just call getSurfaceTexture()

if you want to call it in the class itself.



previewBuilder.addTarget(texture);

complains about addTarget (android.view.surface) in Builder cannot be applied to (android.graphics.SurfaceTexture).

Let's look at the documentation again: https://developer.android.com/reference/android/hardware/camera2/CaptureRequest.Builder.html Apparently CaptureRequest.builder (previewBuilder type) has a method called addTarget

, but this method only accepts the surface! You are passing in a texture. You probably want to change texture

tosurface

0


source







All Articles