CameraKit v0.13.3

Thu Dec 06 2018

With the latest beta version, v1.0.0-beta3.10 migrating to AndroidX and receiving dependency updates, we thought it fitting to add the same to v0.13.3.

Here’s what’s new in CameraKit v0.13.3.


Just like I wrote in our release for v1.0.0-beta3.10, AndroidX will continue updates for Android’s support library. This will help CameraKit stay fully functional on older devices.

Video Duration Limits

Video duration limit added to the video recorder to stop recording video after a set amount of time. Thanks to @lucianoiam in Github for the contribution.

Dependency Updates

v0.13.3 matches the updates to Gradle and Kotlin we made in beta3.10.

Check out all of our changes on the Pull Request.

As always, we love to hear from the community. Find us on Github or send a message on Spectrum!

Thank you for being a part of CameraKit!

CameraKit v0.13.3 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Our New CameraKit Documentation Site

Thu Nov 29 2018

We always are working to find ways to make CameraKit more accessible and simple to use, and in the past few months, this has represented a big focus for us. We are advocates of open source in every way; not only for its ability to create great communities but also foster faster, easier, and more accessible developer environment for previously untouched problems.

As one of our first steps in making CameraKit more usable, we are happy to share our entirely new documentation site, housed within the CameraKit website:

CameraKit helps you add reliable camera to your app quickly. Our open source camera platform provides consistent capture results, service that scales, and endless camera possibilities.

It is important that our new docs accomplish a few key things, for us and for our community…

  • Housed in the same domain as our primary web presence; we weren’t fans of using and wanted to have easy reach in how users access and utilize the CameraKit documentation.
  • Multiple version support for past, current, and future CameraKit releases; ability to quickly comprehend the differences, implementation changes, and available API calls of older and newer versions.
  • Gooood-lookin’; we love our brand and are enjoying growing it, so the docs need to match the same style and simplicity associated with the rest of the CameraKit brand.

Our goal is to continue to grow the community around CameraKit. It is a priority for us and updating our documentation is just one of many steps we have planned (and most importantly are actively working on) in making that goal realized.

We have more enhancements already in the pipeline for the documentation site, but we welcome any feedback on or via our contact form

Our New CameraKit Documentation Site was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

CameraKit v1.0.0-beta3.10

Wed Nov 28 2018

The CameraKit team is hard at work creating a stable 1.0.0 release of CameraKit-Android! In the mean time, we will push smaller updates to address issues and feature requests we’ve received from the community.

Here’s what’s new in beta3.10.


AndroidX is Android’s new support library. Like the support library it replaces, AndroidX brings backwards compatibility across Android releases. AndroidX will allow CameraKit to stay up to date with the latest support improvements.

Clear Listeners

We added methods to remove the common listeners CameraKit supports including Preview, Camera, and Error listeners.

Dependency Updates

Beta3.10 also brings CameraKit dependencies up to date like Gradle and Kotlin.

You can see all the changes for yourself on the Pull Request.

We’re always looking for your feedback! If there is a feature you want to see, or a bug you’ve encountered create a ticket on GitHub. Or if you’d rather reach out to the developers directly, send us a message on Spectrum.

Thank you for being a part of CameraKit!

CameraKit v1.0.0-beta3.10 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Building a NestJS API — A Peek Through My Search History

Wed Nov 07 2018

Building a NestJS API — A Peek Through My Search History

Recently, I was tasked with creating our API. I chose NestJS to experiment with since its tagline:

A progressive Node.js framework for building efficient, reliable and scalable server-side applications.

really jived with me. I was excited to tackle this problem and thought with my JavaScript background — learning a new library while also learning TypeScript couldn’t be that hard, could it? Well, 500+ searches and a pretty good API foundation later, NestJS has lived up to the excitement. This article takes you through my development hurdles and successes.

A selection of my searches will be displayed in the format: search🔎 as well as quick answers to some. Additionally, on the search itself, I’ve linked to specific articles or posts that solved those queries.

API requirements

  • Typescript, TypeORM, GraphQL Support
  • Basic Splash Page that shows ‘API Operational’ with CameraKit Logo/etc
  • User scheme to support sign-in, sign-up, portal access, and user settings

Doing Research

It starts with the nestjs🔎 search. One that I had used seven more times over the course of development, most assuredly to get to the main NestJS site — a great source of documentation and best practices. I quickly realized I needed to take a step back to see what NestJS does. nestjs explanation🔎landed me this great article from Auth0. The next search nestjs vs nextjs🔎 seems a bit out of place, but to make things a bit more confusing, the main CameraKit website began transitioning to NextJS for server-side rendered React; which, of course, has nothing in common with NestJS besides very similar pronunciation.

Constructing the Scaffold

I soon gained a bit of confidence as I started branching off to the beginning steps of making an API— nestjs user authentication🔎 which led me down the path of using nestjs passport🔎, and then getting a bit more serious with the keyword-shotgun approach scaffold nestjs typescript typeorm graphql🔎 — a surprisingly helpful search which pointed me towards this GitHub Repository. I will implement some of the ideas here, just to have them not work later, though, after an update changes the interfaces. I then realized I should include Linting; tslint airbnb rules🔎, tslint config json extend🔎, and tsconfig.json🔎 helped set up TsLint with my preferred Airbnb Config. This was not any harder than installing and adding a line in tslint.json.

Adding a Database

Apollo support was next on my todo list:

- scaffold tests typescript typeorm grapql
- apollo server express
nestjs grapql scaffold

Though I ran into what I thought was a problem with a package version Module has no exported member ‘graphiqlexpress’🔎. I solved this by adding @types/grpahql. Only after some confusion: Removing carrots from dependencies🔎, What are carrots in package.json🔎.

After adding TypeORM (with the help of the docs), and deciding to use PostgreSQL as the database, I was ready to start writing some code.

add typeorm to nestjs
- best db to use with typeorm
- what database to use with typeorm
- typeorm and mongodb
- set up postgresql server on windows

Making the Index Page

I like starting with a splash page for the API to have a quick and dirty way to confirm requests are being served. This involved getting the file system

nestjs index example
- import path

- favicon

Including the favicon

- favicon

- favicon include in site
- Nestjs fastify “favicon”

As well as getting the image and font right

Roboto text
- font shorthand
- vertically align text in div
“CameraKit API Operational” on the index page

“nest can’t resolve dependencies of the”🔎

This search, and similar phrases, came up multiple times while developing with NestJS. An error might look something like:

[ExceptionHandler] Nest can't resolve dependencies of the UserController (UserService, ?). Please make sure that the argument at index [1] is available in the current context.

and I did not know where to look at first. I thought there was something I didn’t know about nestjs interface🔎 or typescript interface🔎, but there were some helpful clues. First, I looked inside the user.controller, and realized that (UserService, ?) points towards its constructor:

You can see NestJS knows about the UserService, and even though I believed I imported the SubscriptionService

nestjs imports exports providers🔎 showed me it both needs to be exported from subscription.module

As well as imported from the user.module

Using Different Development Environments

Because I develop on a Windows computer and Mac laptop, programs and services outside of the great NPM need to be installed: install postgres mac🔎, debugged: invalid active developer path🔎 and set up: create role postgresql🔎 postgresql mac service cli🔎 default postgres password🔎 create user postgres🔎. After getting back up to speed on the Mac side I begin implementing user registration and login. nest authentication login api🔎 and nestjs authentication🔎 kept pointing me towards nestjs/passport as well as the authentication technique in the NestJS docs. I eventually went with their “best practice”, and decided to follow the JWT approach.

- jwt passport persistent sessions
- express session
- nestjs passport session
- passport session
- passport jwt session
debugging nestjs
- auto attach vs option

Out of those searches, I realized I did not want to use express session as well as learning how to debug from here. For Visual Studio Code users turn on Auto Attach:

Visual Studio Code settings — search for “auto attach” and flip it on

and create nodemon.jsonwhich runs with nodemon.

Adding custom Configuration and Security

A few searches later,

- what passport strategy to use for logins local vs jwt
what’s the point of jwt
- saving jwt in local storage
- nestjs middleware cookie session login authentication
- passport extend strategy
- nestjs guard passport
use guards nestjs

I had the API hooked up to the web client in what I thought was a working state. I realized later that the nice comments in the example GitHub repository would need to be followed and implemented. After some worrying: authentication with jwt secure🔎 jwt brute force🔎 generate good jwt secret🔎 I needed a place to store my newly generated secret . I turned to dotenv🔎 to handle configuration files, and of course had to search how to name something starting with a dot in finder🔎. I started off with using purely environment variables and accessing them within the code from process.env.ENVIRONMENT_VARIABLE, but soon after nestjs configuration documentation🔎, I found my way back to the NestJS documentation which suggests using joi npm🔎 for validation. I followed the advanced configuration and made a global module nestjs global modules🔎. To round out my “security audit” I read and implemented nestjs force ssl🔎 for production

After quite a few searches

- express-sslify nestjs
- ssl “nestjs”
- nestjs redirect https
- res.redirect is not a function express-sslify

- 301 moved permanently from disk cache
- redirected you too many times https express

began to add CSRF protection csurf🔎 until I decided it was unnecessary at this time.

Deploying to Heroku

The next step was deployment to Heroku. Of course it did not work on the first try. I fixed bcrypt failing heroku🔎 by installing a new version, same with ts-node not found🔎, and an error that stumped me for a while — web process failed to bind to $PORT within 60 seconds of launch wait longer🔎. I originally thought I might need more time, but I actually needed to dynamically set the port according to the environment variable that Heroku assigns. When that still did not fix the problem app.listen string or number🔎 nestjs heroku port🔎 nestjs heroku deploy🔎 showed me the host was required to be set to

I was then back to errors that I had seen before! This time concerning the environment variables. I was confused how the variables worked on Heroku, and realized after a bit of searching:

heroku dotenv
- push file to heroku
- put dotenv file in Heroku
“Dotenv” “heroku”
- dotenv parse current process env variables
- “Get all” environment variables dotenv

dotenv does not work with Heroku because the .envfile should never be committed. This is for good reason since your secrets would not be secret. Therefore, I solved the problem by either using the file (if found) or checking for environment variables that are already set and then validating them.

- get keys from object into different object specific
- get variables out of process.env
- assign specific object properties to new object
reduce mdn

With that done, more errors came up that looked like a typescript compilation problem, but with weird errors like cannot find global type ‘Boolean’.

‘AsyncIterator’. Do you need to change your target library?
- cannot find global type ‘Boolean’.
- cannot find name ‘Blob’
invalid module name in augmentation. Module ‘graphql/type/definition’
- unexpected token { import
tsc not converting imports

Almost everyone pointed towards fixes through tsconfig.json, yet suggestions to change the lib to X would remove Y error, but add Z error. I ended up with a tsconfig.jsonthat worked, but unfortunately I could not tell you why.

Still, TypeORM was throwing errors, and it was at this time I realized the TypeORM entities

no repository for “contact” was found
- typeorm entities
looks like this entity is not registered in current “default” connection

were correctly found during development in the /src directory, but since production moves the files to the/dist directory, the entities were not correctly found. I changed where TypeORM looks for the entity files by changing src/**/*.entity.tsto dist/**/*.entity.js.


To great relief, the server successfully deployed and started serving requests. I have since gone on to add more functionality as well as run into more problems, but that’s development! Thanks for reading, and if you’re interested: a full list of my searches!

CameraKit helps implement reliable Android camera into your mobile app easily. Open-source, performant, and optimized for tackling the complex Camera APIs on Android.

Building a NestJS API — A Peek Through My Search History was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

BlurKit Release v1.1.0

Thu Nov 01 2018

*chanting* BlurKit BlurKit BlurKit!

Here’s the skinny on the latest release.

Removed Kotlin

In the previous release we added Kotlin to our library, but we’ve since changed philosophy. Kotlin introduces a large dependency. Requiring our users to include such a dependency in their application is a lot to ask. Going forward we are going to stick to Java as our Android language of choice.

Transparency Control

Up until now there was no reliable way to adjust the transparency of the blur applied through BlurKit. We’ve added an XML attribute and Java call to set the alpha value of the blur.

  • XML: blk_alpha
  • Java: setAlpha(float alpha)

There’s a smattering of other minor changes you can see for yourself on the Pull Request.

If you found a bug or have a request for a feature, create an issue on GitHub. Or if you’d rather reach out to the developers directly send us a message on Spectrum.

Thanks for using BlurKit!

BlurKit Release v1.1.0 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Publishing Android Library to Bintray with Gradle + Buddy.Works

Thu Nov 01 2018

If you’re developing an Android Library you will most likely come to the point where you’ll want to distribute your package. There are several ways to accomplish that; in this article I’ll show you my favorite set of tools and methods. We’ll use Gradle to create the package and Bintray to host and distribute.

The last part of this system is automating the build process with a continuous integration tool like Buddy.Works. In Buddy you can setup your build environment to run Gradle commands on every push to your repository.

The tools covered in this article were implemented in the BlurKit project, you can find the code in this repository: It might be helpful to see a complete example as you’re working on your own project!


Image result for gradle

If you’ve even just got a taste for Android development you should be familiar with Gradle. Gradle is a powerful builds system that builds library files from Java source code.

In its default Android setup, Gradle builds your project into an APK to run on an android device. However if you’re creating a library you need to create .pom and .aar files to publish to Bintray.

Let’s Get To It.

First we’ll create a new file called deploy.gradle that we will call from the project build.gradle. The end goal from the deployment is to build, then publish to Bintray. Let’s first define our build task.

Before building a new project we need to clean the previous deployment. Do that with the following function.

task cleanForDeployment {
doLast {
logger.lifecycle('BlurKit: Deployment: Cleaning...')
logger.lifecycle('Deleting: ' + project.buildDir)
delete project.buildDir

The build files are contained at the path project.buildDir. Deleting that folder will effectively clean the previous build.

Now, build our new package.

task buildForDeployment {
logger.lifecycle('BlurKit: Deployment: Building...')
finalizedBy assemble

doFirst {
android.variantFilter { variant ->
if ( == 'debug') {

The buildForDeployment task depends on cleanForDeployment and finalized by a gradle command called assemble. In the buildForDeployment command do a quick check of the buildType to determine if we are running in debug mode.

The last thing Gradle has to do is deploy the package to Bintray; let’s take a quick detour to Bintray.

The Land of Bintray.

JFrog Bintray is a cloud platform that gives you full control over how you publish, store, promote, and distribute software.

The proper name is JFrog Bintray but for this article I’ll simply refer to the service as Bintray. Like the quote from their documentation says, Bintray is a service to host and distribute software. Bintray has become the standard for most Android projects due to its reliability and ease of use.

If you don’t have an account, navigate to and create one now.

Bintray is organized with the following hierarchy. Account -> Repository -> Package -> Version.

Once you’ve created an account, add a new repository. If you are not using JCenter (we’ll touch on that in a bit) the name will show up when the user is implementing your package, so pick a name that reflects the project. For this example I’ll use “other”. Then select type as maven, and click create.

From the repository page add a new package. This package will be the name of the public facing library that users will include in their projects. I’ve used “blurkit-android”.

Now we’ll go back to Gradle code.

Gradle Town

Welcome back to Gradle. Add the following code to the top of the deploy.gradle file.

apply plugin: 'com.jfrog.bintray'
bintray {
user = getBintrayUser()
key = getBintrayKey()
configurations = ['archives']
pkg {
repo = 'other'
name = 'blurkit-android'
userOrg = 'camerakit'
vcsUrl = ''
licenses = ['MIT']

version {
name = project.version
released = new Date()

Here we create a bintray object and configure it with our Bintray account information we just set up. The repo, name and userOrg come from Bintray. vcsUrl, and licenses are not required but reference your version control url and the license associated with it. version is the version that the user will include in the implementation of your library.

For example with a package name of “blurkit-android” and a version of ‘1.0.0’ the line to include the library from Android would be:

implementation ‘io.alterac.blurkit:blurkit:1.0.0’

I’ve setup project.version from my build.gradle file which we will cover in the next section.

The two parameters I haven’t mentioned, user and key are private variables and should not be included directly in the code. Let’s create two functions to get the user and key parameters from environment variables or a configuration file.

def getBintrayUser() {
if (System.getenv('BINTRAY_USER')) {
return System.getenv('BINTRAY_USER')
} else if (rootProject.file('').exists()) {
Properties properties = new Properties()
return properties.getProperty('bintray.user')
} else {
logger.lifecycle("Warning: Could not find BINTRAY_USER in environment or")

def getBintrayKey() {
if (System.getenv('BINTRAY_KEY')) {
return System.getenv('BINTRAY_KEY')
} else if (rootProject.file('').exists()) {
Properties properties = new Properties()
return properties.getProperty('bintray.key')
} else {
logger.lifecycle("Warning: Could not find BINTRAY_KEY in environment or")

The above block first checks the system environment variables for BINTRAY_USER and BINTRAY_KEY. If they do not exist it then checks the file as a backup. You can store the variable wherever is convenient. I chose to use environment variables.

Now our Bintray object is setup with the information from our online Bintray account but it’s not yet doing anything useful. Let’s add a deploy command to deploy this package to Bintray.

task deployRelease {
logger.lifecycle('BlurKit - Starting Release Deployment')

dependsOn cleanForDeployment
dependsOn buildForDeployment
finalizedBy bintrayUpload

doLast {

logger.lifecycle('Deploying version ' + bintrayUpload.getVersionName() + ' in ' + bintrayUpload.getRepoName())

This deployRelease command builds on what we created in buildRelease and is finished by the gradle command bintrayUpload. Before the deployment command runs, we have to set the versionName, userOrg, and repoName again.

Integrating With The Rest Of Your Gradle Scripts.

The last Gradle step is integrating deploy.gradle with the rest of our gradle scripts. Two files need modification.

First the top level build.gradle.

buildscript {
 dependencies {
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.1'

allprojects { project ->
group = 'io.alterac.blurkit'
version = '1.0.0'

repositories {

The additions are:

  1. Bintray dependency.
  2. allprojects line — Here we define the version number that is referenced by Bintray for deployment

Next we’ll head to the project level build.gradle where we’ll make a few more additions.

plugins {
id '' version '1.5'
install {
repositories.mavenInstaller {
pom.project {
artifactId 'blurkit'
packaging 'aar'

apply from : 'deploy.gradle'
  1. The android-maven dependency.
  2. install block where the groupId, artifactId and packaging are defined. We’ll package with .aar for use in Android projects.
  3. apply from : 'deploy.gradle' to link the deploy.gradle file.

To run the command we just created type ./gradlew deployRelease in the top level directory of the project.

Finishing Up

Then navigate to your package on Bintray’s website and you should see a notification that a new version has been published. Confirm that version and Bintray will finalize the upload. You should see something like this.

The default way that your Library is included in an Android project is with the line shown in the bottom left of the package page.

compile ‘io.alterac.blurkit:blurkit:1.0.0’

When using default Bintray you need to add a repositories section with the name of the repository your package is hosted in the build.gradle of the Android project.

repositories {
maven {
url ""
dependencies {
implementation 'io.alterac.blurkit:blurkit:1.0.0'

On the bottom right of the package page there is an option to link to JCenter. JCenter is included in Android projects by default and doesn’t require you do add the specific url of your repository.

Icing On The Cake

This setup is fast and reliable but doesn’t solve our problem of automation. There are plenty of automation tools out there but my preferred method is Buddy.Works.

Buddy.Works is a platform to create deployment pipelines for your projects of any type, from Android to Web development. You can configure all kinds of different commands and environments to test and deploy.

Visit and create an account. You can get started with Google, GitHub or Bitbucket.

Create a new project, allow Buddy access to your Github profile and select the GitHub repository from your account. This repository is the one Buddy.Works will watch for changes on.

Next smash the “Add a new pipeline” button, give it a name and select the trigger mode and branch you want to work from. I have mine set to On Push to the master branch.

From here you’ll see a list of possible actions you can add to your pipeline.

There are a lot of possible actions in different categories. You can publish to Google Play, tell the pipeline to wait for approval, zip files and run commands from all types of languages and frameworks.

For this tutorial we’ll keep it simple and just create a Gradle command.

Gradle in Buddy.Works

Select the Gradle action and you’ll be taken to a terminal window with some more options above it. In the command window we’ll add our deployment task.

./gradlew deployRelease

./gradlew is the gradle wrapper command and installs missing gradle dependencies rather than depending on gradle itself. Any other command, gradle or otherwise can be added here.

If you run the pipeline in its current state (go ahead and try it now) it won’t work. You’ll most likely get an error about Java sdk/ndk locations not found. Good news for you, I’ve already set up a development environment on Docker for Android projects. The image is located here on DockerHub: but you can add it to by clicking on the environment tab and adding the docker image of “emersoncloud/android-ndk-28”

Lastly we need to add the Bintray user and key environment variables for the gradle script. Do that in the variables tab.

Save the pipeline and you’ll be ready to rumble! You can now push a change to your repository and watch it run through the pipeline.

Our pipeline is very simple with just a single action. You can add additional actions below the Gradle action or have them run on failure in the “Actions Run On Failure” section.


While this article covers our automation of BlurKit, we plan to integrate a similar automated system for the CameraKit project with support for beta and snapshot releases as well. We are huge advocates of automated devOps so expect many more posts about our other automated systems and future systems coming soon!

You can check out the project where we implement these Gradle scripts here:

Thanks for reading and I hope you were able to follow along and publish your project successfully. If you have any questions drop a comment here on Medium and I’ll be sure to respond.

Publishing Android Library to Bintray with Gradle + Buddy.Works was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Revitalizing BlurKit

Thu Oct 11 2018

What Is BlurKit?

BlurKit is an easy to use and performant utility to render real-time blur effects in Android. BlurKit was created by the same team that brought you CameraKit. CameraKit is still our main focus but because of the usage of BlurKit we felt the need to bring some updates to the utility.

The project was started late 2016 and has gained quite a lot of traction. By mid 2017 we crossed 2000 stars on GitHub, a testament to the need for BlurKit. The previous methods to retrieve and blur a source bitmap took on average 50ms. The same procedure with BlurKit takes 1/15th the time or just 3ms. The speed of BlurKit creates a seamless experience and allows blurring where not previously possible.

GitHub Star Count

Where We Are Going

Today BlurKit gets some new life. It’s been almost 18 months since the last commit, updates are long overdue! In this commit we’ve added unit and integration tests, moved the first class to Kotlin and updated the README with the latest documentation.

We are putting more focus back into the BlurKit project. In the coming months new features will be added and bugs will be squashed.

Our aim is to always be closely integrated with the community; we want your feedback! If you encounter a bug or have an idea for a new feature, open an issue on GitHub and we’ll address it as quickly as possible.

We’ve recently started a channel where you can ask specific questions and contact the developers directly.

Thanks for your support and we hope you’re as excited as us by the future of BlurKit!

BlurKit is a sister project of CameraKit ( Created by Alterac Inc.

Revitalizing BlurKit was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

Getting Started With CameraKit v1.0.0-beta1

Sat Aug 25 2018

CameraKit is a simple to use wrapper for Googles Camera1 and Camera2 APIs. In this tutorial you’ll learn how to get started using CameraKit in your Android application. The code for this project is on GitHub, and you can read more about CameraKit on our website.

Part 1 — Get Camera Output

The first step to using CameraKit is to add a couple lines to your app level build.gradle file.

repositories {
maven { url ''}
dependencies {
implementation 'com.camerakit:camerakit:1.0.0-beta1'

That’s it! With those two lines CameraKit is ready to rumble.

In order to see the a preview of the camera on your screen we’ll add a CameraKitView to the activity_main.xml .

<?xml version="1.0" encoding="utf-8"?>
< xmlns:android=""


There are plenty of settings to explore in the CameraKitView, however just to get started we’ll set camera_facing="back" and leave it at that.

Now head over to your to initialize the CameraKitView. The two functions required to start the View are onResume() and onPause() . We also need to request permissions from the user to access the device’s camera.

import com.camerakit.CameraKitView;
public class MainActivity extends AppCompatActivity {

private CameraKitView cameraKitView;

protected void onCreate(Bundle savedInstanceState) {
cameraKitView = findViewById(;

protected void onResume() {

protected void onPause() {

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
cameraKitView.onRequestPermissionsResult(requestCode, permissions, grantResults);

This will place the camera output front and center in our application. Run it on your device and you should see something like this:

That’s all it takes to simply access the camera output! If you want to go off on your own from here, it was nice talking with you. Otherwise keep that dial locked and we’ll use CameraKit to capture and save an image!

Part 2 — Capturing an Image

First things first, let’s put a button on the activity_main.xml . There are plenty of different ways to create a button; here’s one example.


Now back to the! Initialize the button:

import com.camerakit.CameraKitView;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {

private CameraKitView cameraKitView;
private Button photoButton;

protected void onCreate(Bundle savedInstanceState) {
cameraKitView = findViewById(;

photoButton = findViewById(;

Here comes the exciting part, the photoOnClickListener ! This listener is of type View.onClickListener and we only need to Override one function: onClick. Inside the onClick() function we then call cameraKitView.captureImage() and override CameraKit’s onImage function.

This is where the magic happens. onImage() takes two parameters, a CameraKitView object and an image in the form of a byte array. This is the final image and can be manipulated however you would like.

In the code below, I create a new File and FileOutputStream and write the file to a particular filename, “photo.jpg”.

private View.OnClickListener photoOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
cameraKitView.captureImage(new CameraKitView.ImageCallback() {
public void onImage(CameraKitView cameraKitView, final byte[] photo) {
File savedPhoto = new File(Environment.getExternalStorageDirectory(), "photo.jpg");
try {
FileOutputStream outputStream = new FileOutputStream(savedPhoto.getPath());
} catch ( e) {
Log.e("CKDemo", "Exception in photo callback");

Now you should be able to run this application on your device and capture an image. The image will be in the device folder and named “photo.jpg”

Final Thoughts

Thanks for following along to this very quick crash course to CameraKit. Hopefully you found it easier and more intuitive than wrestling with Google’s APIs.

In the coming weeks we will officially be launching CameraKit v1.0.0 with many stability and performance improvements over the previous v0.13. The official release will also bring about a new set of documentation.

If you have any questions don’t hesitate to reach out on GitHub or leave us a comment here on Medium.

Getting Started With CameraKit v1.0.0-beta1 was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

CameraKit and Kotlin

Tue Jul 10 2018

Here at CameraKit we are always trying to keep up to date with modern Android development tools. In upcoming releases, we will be transitioning our codebase from Java into Kotlin. I’ll discuss Kotlin and how it can help take CameraKit to the next level.

A Bit About Kotlin

Kotlin is a programming language created by JetBrains in 2011, the makers of Android Studio. Kotlin aims to bring the convenience of modern language features to Android with clean, concise style. The standard library is small with little runtime overhead and relies heavily on compile-time inlining to increase performance.

In addition to being a great language to read and write, it’s very easy to migrate from Java to Kotlin. Kotlin fully supports interoperability with native code. That means that all the libraries you are familiar with in Java will work just the same in Kotlin. Interfacing with existing Java code does not require any special treatment like adapters.

Kotlin also has strong support from its creator JetBrains and Google, who made Kotlin an official language of Android. Kotlin is an easy transition from existing Java code and will likely be around for many years to come.

There’s lots great articles and resources for Kotlin, here are a few of my favorites: Kotlin Reference, Why you should totally switch to Kotlin, Why Kotlin is my next programming language.

Kotlin in CameraKit

Earlier this year, Android KTX was announced, a set of Kotlin extensions specifically for Android development. It continues on the same ideas that make Kotlin such a great language to begin with, clear concise code resulting in a simpler to understand project. Google and JetBrains are adding more coverage of the Android Framework all the time. With CameraKit, we aim to create our own extensions that will make the native camera APIs easier to use.

The first aspect of CameraKit that we’ve rewritten in Kotlin is the CameraSurfaceView and its rendering components such as the CameraSurfaceRenderer and TextureProgram. As you’ll see in the code snippets below, the Kotlin code is easy to read and digest. Kotlin is also still very performant as it compiles to Java bytecode to run on the JVM.

Here’s some sample code from our latest commit:

class CameraSurfaceView : GLSurfaceView {

internal val renderer: CameraSurfaceRenderer

constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)

init {

renderer = CameraSurfaceRenderer(context)

keepScreenOn = true

fun setShader(shader: Int) {
renderer.shader = shader

The class is defined in a similar fashion to Java followed by the new inheritance syntax, which makes a lot of sense when you see how variables are defined.

Another huge benefit to Kotlin is its null safety. Kotlin distinguishes between non-null types and nullable types. Take a look at the following snippet.

private var surfaceTexture: SurfaceTexture? = null

The question mark signifies that the variable can be made null and in this case, is set right to null. Now when accessing this variable you must do one of two things.

if (surfaceTexture != null) {
return surfaceTexture!!
surfaceTexture?.run {...}

One must first check if the value of the object is null or use a safe call like in the second example which will evaluate to null instead of throwing a null pointer exception.

Feel free to dig into our code over on the GitHub page.


For so many reasons discussed above, migrating to Kotlin is an easy choice for us at CameraKit. Kotlin allows for digestable and concise code, JetBrains has created great editing tools and migration from Java won’t make you want to pull your hair out.

With Android KTX we will be able to add amazing features to CameraKit in the coming months. Stay tuned for more updates focused around integrating Kotlin into our platform!

CameraKit and Kotlin was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more

3K Stars On GitHub — Thank You!

Fri Jun 15 2018

This week, almost a year and a half after starting development on CameraKit, we passed 3,000 stars on GitHub. This is a very special achievement for us, and we wanted to take this opportunity to say Thank You. Thank you to our growing community, to our sponsors Expensify and Buddy.Works, and to our 23 contributors: you made all of this possible.

What’s next?

We are gearing up to launch the official release of v1.0.0 very soon. This release includes video and a new core ‘engine’ which we will detail in a future post. Then the sky’s the limit! We will continue to adding core functionality to picture and video, followed by support for add-ons/extensions. These extensions will allow the CameraKit library to remain small and tidy with the ability to add more complex components.

Want to join the community?

Drop us an issue on GitHub or make your own change and submit a pull request. We’d love to get your feedback on how to improve CameraKit for everyone!

It’s been an incredible adventure so far, and we’re excited for the road ahead.

3K Stars On GitHub — Thank You! was originally published in CameraKit on Medium, where people are continuing the conversation by highlighting and responding to this story.

Show more