Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to create LifecycleCamera with destroyed lifecycle

I'm trying to make floating cameraview for my screen recorder application.

FloatingViewService.java

public class FloatingViewService extends LifecycleService implements CameraXConfig.Provider, LifecycleOwner {
    private View mFloatingView;
    private WindowManager mWindowManager;
    PreviewView previewView;
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;

    public FloatingViewService() {
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        super.onBind(intent);
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);
        final WindowManager.LayoutParams params;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);

        } else {
            params = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_PHONE,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                    PixelFormat.TRANSLUCENT);

        }
        params.width = 400;
        params.height = 300;
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mFloatingView, params);


        mFloatingView.findViewById(R.id.previewFrame).setOnTouchListener(new View.OnTouchListener() {
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;

                    case MotionEvent.ACTION_UP:
                        return true;

                    case MotionEvent.ACTION_MOVE:
                        //this code is helping the widget to move around the screen with fingers
                        params.x = initialX + (int) (event.getRawX() - initialTouchX);
                        params.y = initialY + (int) (event.getRawY() - initialTouchY);
                        mWindowManager.updateViewLayout(mFloatingView, params);
                        return true;
                }
                return false;
            }
        });

        cameraFun(mFloatingView);


    }

    public void cameraFun(View mFloatingView) {
        previewView = mFloatingView.findViewById(R.id.previewFrame);
        cameraProviderFuture = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
            }
        }, ContextCompat.getMainExecutor(this));
    }

    void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
        Preview preview = new Preview.Builder()
                .build();

        CameraSelector cameraSelector = new CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
                .build();
        preview.setSurfaceProvider(previewView.createSurfaceProvider());
        OrientationEventListener orientationEventListener = new OrientationEventListener(this) {
            @Override
            public void onOrientationChanged(int orientation) {
                int rotation;
                int orientationcheck = getResources().getConfiguration().orientation;

                if (orientationcheck == Configuration.ORIENTATION_PORTRAIT) {
                    if (orientation >= 45 && orientation < 135) {
                        rotation = 360;
                    } else if (orientation >= 135 && orientation < 225) {
                        rotation = 180;
                    } else if (orientation >= 225 && orientation < 315) {
                        rotation = 360;
                    } else {
                        rotation = 0;
                    }
                    Log.i("orientation", String.valueOf(orientation) + "= ORIENTATION_PORTRAIT" + orientationcheck);

                } else {
                    if (orientation >= 45 && orientation < 135) {
                        rotation = 90;
                    } else if (orientation >= 135 && orientation < 225) {
                        rotation = 180;
                    } else if (orientation >= 225 && orientation < 315) {
                        rotation = 270;
                    } else {
                        rotation = 0;
                    }
                    Log.i("orientation", String.valueOf(orientation) + "= ORIENTATION_Land" + orientationcheck);
                }
                Log.i("orientation", String.valueOf(orientation) + "= " + orientationcheck);

                previewView.setRotation(rotation);
            }
        };
        orientationEventListener.enable();
        cameraProvider.bindToLifecycle(this, cameraSelector, preview);
    }

    @NonNull
    @Override
    public CameraXConfig getCameraXConfig() {
        return Camera2Config.defaultConfig();
    }

    public void onDestroy() {
        super.onDestroy();
        mWindowManager.removeView(mFloatingView);
    }
}

layout_floating_widget.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.camera.view.PreviewView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/previewFrame"
    android:layout_width="300dp"
    android:layout_height="250dp"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:layout_alignParentEnd="true"
    android:layout_alignParentBottom="true"
    android:layout_gravity="center" />

BackgroundService.java Check below code how I call FloatingViewService.java

public class BackgroundService extends Service {
    Boolean onoff = true;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onCreate() {
        super.onCreate();
        new FloatingViewService();
        if (onoff) {
            onoff = false;
            startService(new Intent(this, FloatingViewService.class));
        } else {
            onoff = true;
            stopService(new Intent(this, FloatingViewService.class));
        }
    }
}

ERROR:

 java.lang.IllegalArgumentException: Trying to create LifecycleCamera with destroyed lifecycle.
        at androidx.camera.lifecycle.LifecycleCameraRepository.createLifecycleCamera(LifecycleCameraRepository.java:103)
        at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:414)
        at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java:275)
        at com.rdbrain.FloatingViewService.bindPreview(FloatingViewService.java:196)
        at com.rdbrain.FloatingViewService.lambda$cameraFun$0$FloatingViewService(FloatingViewService.java:138)
        at com.rdbrain.-$$Lambda$FloatingViewService$qkM-fNI79D-TvnilmrNFZjQYwlI.run(Unknown Source:2)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6626)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)

Note : This code is working as separate module but when I connect to screen recorder it not working, I have setup all necessary permission and service in manifests.xml

like image 978
Krunal Dholiya Avatar asked Aug 06 '20 03:08

Krunal Dholiya


1 Answers

Use viewLifecycleOwner instead of this in cameraProvider.bindToLifecycle(this, cameraSelector, preview);

like image 127
AndroidSam27 Avatar answered Sep 20 '22 08:09

AndroidSam27