Dev Tip: Returning Plug-in Control to Main Camera App


#1

I used the Camera API to extend the video recording time of the RICOH THETA. During development, I ran into a problem stopping the plug-in and returning control to the main camera app. This is a critical step in making the plug-in accessible on the THETA Plug-in Store. I’ll explain how I solved the problem and enabled the plug-in to open the camera from the plug-in, then close it to return control to the camera. The GitHub repo for the completed project is here.

I used the theta-plugin-camera-api-sample as a starting point.

Original Plug-in Lifecycle with Problem

These are the original steps that occurred after the plug-in was activated.

Step 1: Send a request to close the camera of the main application

notificationCameraClose()

Step 2: Open camera on the plug-in side

File: CameraFragment.java
Method: surfaceCreated()

Step 3: Close plug-in

When the mode button is pressed for a long time (when the plug-in ends)

Step 4: Send request to open the camera of the main application

notificationCameraOpen()

Step 5: Terminate the application

finishAndRemoveTask()

in

notificationSuccess()

Close the open camera on the plug-in side within the application termination processing

File: CameraFragment.java
Method: surfaceCreated()

Problem

Upon receiving the request to open the camera in step 4, the main body application tries to open the camera. Since the camera is still open on the plug-in side at this point, the camera cannot be opened and an error occurs.

Solution

After the close process of the plug-in side camera is completed, a request to open the camera of the main application is sent.

PluginActivity.java

Processing of notificationCameraOpen() in close() processing is executed at the end of activity.

We move notificationCameraOpen() from close() to onDestroy(), which is the standard method in the Android Activity lifecycle.

Source Code Snippet

Delete notificationCameraOpen() part of close() method.

 / **
    * End processing
    * /
   public void close () {
// if (isCamera) {
// notificationCameraOpen ();
//}
       notificationSuccess ();
   }

// Add onDestroy and add notificationCameraOpen () in it
   @Override
   protected void onDestroy () {
       if (isCamera) {
           notificationCameraOpen ();
       }
       super.onDestroy ();
   }

Explanation of Notification Using Broadcast Intent

notificationCameraOpen and notificationCameraClose are in the same PluginActivity.java file. You can see that it is using Intent with ACTION_MAIN_CAMERA_OPEN.

public void notificationCameraOpen() {
    isCamera = false;
    sendBroadcast(new Intent(ACTION_MAIN_CAMERA_OPEN));
}

public void notificationCameraClose() {
    isCamera = true;
    sendBroadcast(new Intent(ACTION_MAIN_CAMERA_CLOSE));
}

Overview of Activity Lifecycle and when onDestroy() is called

As I included notificationCameraOpen in onDestroy(), I wanted to understand whereonDestroy() fits into the Android Activity Lifecycle.

Success Notification

I’m calling notificationSuccess() in close()

/**
 * Notifying Completion of Plug-in when the plug-in ends normally
 */
public void notificationSuccess() {
    Intent intent = new Intent(ACTION_FINISH_PLUGIN);
    intent.putExtra(PACKAGE_NAME, getPackageName());
    intent.putExtra(EXIT_STATUS, ExitStatus.SUCCESS.toString());

Benefits of Using the Camera API

Although many plug-ins use the Web API to take video and pictures, I used the Camera API to gain more control over the length of the video. With the Camera API, I was also able to change the video compression CODEC from H.264 to HEVC, resulting in a significantly smaller file size.