Static Class in Kotlin

Earlier this week I need to create a static class in Kotlin. If you are coming from Java like myself, the syntax is slightly different, but still easy. Here’s the code

class Constants { 
  companion object {
    val constantKey = "KeyValue"    
    fun getConstant() : String { return "KeyValueFromFun" }
  } 
}

You can then use the class like this:

Constants.constantKey
Constants.getConstant()

Recording Video on Android with CameraKit

In my projects, I have to do video recorinding often. It’s trendy of course. Lately, I have been using a library called CameraKit which adds some nice features on to the general implementation. This library is pretty good, although updates are slightly sparatic and the docs are out of date. In this tutorial, I’ll show you how to get started recording video with this library.

Side note, I usually like to use libraries and contribute to them rather than implementing myself to support open source :D.

Installing and Setting up

The first step is to install the library via gradle. Go to your Module:app gradle file and add the following to your dependencies:

compile 'com.wonderkiln:camerakit:0.13.1'

Sync cradle, then add a new activity. For this example we will use an Activity called RecordActivity. To create a new Activitiy to go File -> New -> Activity -> Blank Activity. This will create a new activity as well as a activity_record.xml file.

One last thing, we will need to add the storage permission to your AndroidManifest.xml (video and mic will be asked at runtime)

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Add the CameraView

Insided the activity_record.xml file, let’s add the following view

<com.wonderkiln.camerakit.CameraView xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/camera"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:ckCropOutput="false"
    app:ckDoubleTapToToggleFacing="true"
    app:ckFacing="back"
    app:ckFlash="off"
    app:ckFocus="tapWithMarker"
    app:ckJpegQuality="100"
    app:ckMethod="standard"
    app:ckPinchToZoom="true"
    app:ckVideoQuality="highest"
    app:ckZoom="2.0" />

This is the basic CameraView from the  CameraKit library. There are several options here, but most are just default. You can get a full list here: http://docs.camerakit.website/#/?id=extra-attributes

Let’s also add a button that we can use to start an stop the camera.

<Button
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="recordButton"
    android:text="Record"
    />

Setting up the Code

Now that we have our UI, let’s wire that up. Open up the RecordActivity.java and add the following private variables.

private CameraView cameraView;
private boolean isRecording = false;

These will hold our CameraView and the current recording state. Let’s now create a function (to keep logic isolated) that will initialized our camera. Call it setUpCameraView​. Inside the function, let’s grab the CameraView and add the CameraKitEventListener which will allow us to listen to the CameraView events.

cameraView = (CameraView) findViewById(R.id.camera);
cameraView.addCameraKitListener(new CameraKitEventListener() {
  @Override
  public void onEvent(CameraKitEvent cameraKitEvent) {
  }

  @Override
  public void onError(CameraKitError cameraKitError) {
  }

  @Override
  public void onImage(CameraKitImage cameraKitImage) {
  }

  @Override
  public void onVideo(CameraKitVideo cameraKitVideo) {
    // The File parameter is an MP4 file.
    Log.d("testing-tag", String.valueOf(cameraKitVideo.getVideoFile()));
  }
});

There are a few events here that can be helpful to hook into and notify your users, but the main function we are concerned with is onVideo. I also added a log function to print the path to the video file. You can use this file in your app of course 😀

Finally, let’s wire up the button to record.

Button buttonView = (Button) findViewById(R.id.captureButton);
buttonView.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    if (isRecording) {
      cameraView.stopVideo();
      isRecording = false;
      return;
    }

    cameraView.captureVideo();
    isRecording = true;
  }
});

Here we simply start the video capture when the user clicks and set the status to isRecording. We of course reverse that when the user clicks again.

Adding Lifecycle

One last thing we have to do when working with the camera is to be sure to unlock and destroy our media listener. Most of that is hidden by CameraKit so we just need to add the following to your activity life cycle events.

@Override
public void onResume() {
  super.onResume();
  cameraView.start();
}

@Override
protected void onPause() {
  cameraView.stop();
  super.onPause();
}

The Final Result

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.wonderkiln.camerakit.CameraKitError;
import com.wonderkiln.camerakit.CameraKitEvent;
import com.wonderkiln.camerakit.CameraKitEventListener;
import com.wonderkiln.camerakit.CameraKitImage;
import com.wonderkiln.camerakit.CameraKitVideo;
import com.wonderkiln.camerakit.CameraView;

public class RecordActivity extends AppCompatActivity {

  private CameraView cameraView;
  private boolean isRecording = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_record);

    setUpCameraView();
  }

  @Override
  public void onResume() {
    super.onResume();
    cameraView.start();
  }

  @Override
  protected void onPause() {
    cameraView.stop();
    super.onPause();
  }

  private void setUpCameraView() {
    cameraView = (CameraView) findViewById(R.id.camera);
    cameraView.addCameraKitListener(new CameraKitEventListener() {
      @Override
      public void onEvent(CameraKitEvent cameraKitEvent) {
      }

      @Override
      public void onError(CameraKitError cameraKitError) {
      }

      @Override
      public void onImage(CameraKitImage cameraKitImage) {
      }

      @Override
      public void onVideo(CameraKitVideo cameraKitVideo) {
        // The File parameter is an MP4 file.
        Log.d("testing-tag", String.valueOf(cameraKitVideo.getVideoFile()));
      }
    });

    Button buttonView = (Button) findViewById(R.id.captureButton);
    buttonView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        if (isRecording) {
          cameraView.stopVideo();
          isRecording = false;
          return;
        }

        cameraView.captureVideo();
        isRecording = true;
      }
    });
  }
}

And that’s it! I hope this gets you started recording video on Android. Feel free to leave any questions or comment below.