'CameraX keeps crashing when saving picture in service with attempt to involve null method

I have all a service that take a picture using Camerax independent of activity. I am trying to see if it is possible. And looks like the code keeps crashing at the saving output file part. I have all the permissions done. And if possible, can camerax capture videos in foreground service?

java.lang.RuntimeException: Unable to start service com.example.medialistenercopy.PlayerService@6b908e8 with Intent { cmp=com.example.medialistenercopy/.PlayerService }: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.camera.core.ImageCapture.takePicture(androidx.camera.core.ImageCapture$OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture$OnImageSavedCallback)' on a null object reference
        at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3849)
        at android.app.ActivityThread.access$1600(ActivityThread.java:208)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1728)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:205)
        at android.app.ActivityThread.main(ActivityThread.java:6991)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:884)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.camera.core.ImageCapture.takePicture(androidx.camera.core.ImageCapture$OutputFileOptions, java.util.concurrent.Executor, androidx.camera.core.ImageCapture$OnImageSavedCallback)' on a null object reference
     

The service loads fine until the line below.

   ``` ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(path).build(); ```

This is where things fail

public class PlayerService extends LifecycleService {
    //camera stuff
    ImageCapture imageCapture = null;
    Executor executor;
    private final ServiceLifecycleDispatcher mDispatcher = new ServiceLifecycleDispatcher(this);
    Camera camera;
    private File videoDir;
    private File path;
    @Override
    public void onCreate() {
        mDispatcher.onServicePreSuperOnCreate();
        super.onCreate();
    }
    // camera stuff
    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    //public void onCreate() {
    public int onStartCommand(Intent intent, int flags, int startId) {
      
        super.onStartCommand(intent, flags, startId);
       
 
        createNotificationChannel();
        Intent intent1 = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent1, 0);
        Notification notification = new NotificationCompat.Builder(this, "ChannelID1")
                .setContentTitle("Big App")
                .setContentText("Application Ongoing")
                .setSmallIcon(R.mipmap.ic_icon_round)
                .setContentIntent(pendingIntent).build();
        startForeground(1, notification)
        start_Camera(); /**/THIS IS WHERE THE FUNCTION IS CALLED** 
 
        return START_STICKY;
    }
    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel(
                    "ChannelID1", "Foreground Notification",
                    NotificationManager.IMPORTANCE_DEFAULT);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(notificationChannel);
        }
    }
    //camera stuff
    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mDispatcher.getLifecycle();
    }
    public void start_Camera()   {
        ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
                ProcessCameraProvider.getInstance(this);
        cameraProviderFuture.addListener(() -> {
            try {

  executor = Executors.newSingleThreadExecutor();
                // Camera provider is now guaranteed to be available
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                // Choose the camera by requiring a lens facing
                CameraSelector cameraSelector = new CameraSelector.Builder()
                        .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
                        .build();
                ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                        //.setTargetResolution(new Size(width,height))
                        .setBackgroundExecutor(executor)
                        .setBackpressureStrategy(ImageAnalysis.STRATEGY_BLOCK_PRODUCER)
                        .setImageQueueDepth(5)
                        .build();
                imageAnalysis.setAnalyzer(executor, image -> {
                    int rotationDegrees = image.getImageInfo().getRotationDegrees();
                    image.close();
                });
                imageCapture = new ImageCapture.Builder()
                        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                        .build();
             
                cameraProvider.unbindAll();
                cameraProvider.bindToLifecycle(this, cameraSelector, imageAnalysis, imageCapture);
            } catch (InterruptedException | ExecutionException e) {
                // Currently no exceptions thrown. cameraProviderFuture.get()
                // shouldn't block since the listener is being called, so no need to
                // handle InterruptedException.
            }
        }, ContextCompat.getMainExecutor(this));
        // file folder
        Date currentTime = Calendar.getInstance().getTime();
        currentTime.toString();
        videoDir = new File(Environment.getExternalStorageDirectory() + "/DCIM/Camera/");
        if (!videoDir.exists()) {
            videoDir.mkdir();
        }
        String fileName = currentTime + ".jpg";
        path = new File(videoDir, fileName);
        //file folder
        
        ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(path).build();
        
//EVERYTHING FAILS below 
        imageCapture.takePicture(outputFileOptions, executor, new ImageCapture.OnImageSavedCallback () {
            @Override
            public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        // success log 
                    }
                });
            }
            @Override
            public void onError(@NonNull ImageCaptureException error) {
                error.printStackTrace();
            }
        });
 
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        super.onBind(intent);
        mDispatcher.onServicePreSuperOnBind();
        return null;
    }
    @Override
    public void onDestroy() {
        stopForeground(true);
        stopSelf();
        mDispatcher.onServicePreSuperOnDestroy();  //camera stuff
        super.onDestroy();
       
    }
 
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source