Android SDK Setup
This short guide will walk through the basics of the Camera Kit Android SDK. We recommend reading this entire page as you follow along to add a simple Camera Kit integration to your app!
Camera Kit Android for Beginners
If you are new to Android development or feel that this documentation goes at a faster pace than you are comfortable with, check out our beginner tutorial.
Check out our Sample Apps
The Android directory in the Camera Kit SDK download includes several sample apps that demonstrate different approaches to integrating Camera Kit SDK into your android app.
- camerakit-sample-basic — contains the bare minimum way to integrate Camera Kit.
- camerakit-sample-full — contains a fully functioning camera capture with lenses and preview flow.
- camerakit-sample-custom-video — demonstrates how to setup a custom video/audio encoding and audio source implementation.
- camerakit-sample-custom-input — demonstrates how to setup a custom input to the Camera Kit's processing pipeline.
- camerakit-sample-simple — demonstrates how to setup a simple, Camera Kit powered, camera capture flow via the standalone, batteries-included
CameraActivity
. - camerakit-sample-dynamic-app — demonstrates how to dynamically load CameraKit SDK as a dynamic feature module (DFM) as well as a standalone apk.
Minimum Device Requirements
- Recent Android Studio (4.0+), download latest at: https://developer.android.com/studio.
- Gradle 6.0+ and Android Gradle Plugin 4.2.2+.
- Android 5.0 device or emulator, with a minimum SDK API level of 21 and OpenGL ES 3.0+, is required.
Prerequisites
Snap Developer set up
You'll need a Snap Developer account, and you'll need to request access to Camera Kit SDK. You can find more info on that here.
You may also want to familiarize yourself with how to access and manage AR content (i.e. Lenses). You read about that here.
Android Studio
Pleaes be sure to be using the latest version of Android Studio. This guide assumes you have it installed, and are familar with the Kotlin progamming langugae.
Adding the SDK
The current version of the CameraKit SDK is available on the public Maven Central repository, make sure you have the following in your app's root build.gradle
file:
allprojects {
repositories {
mavenCentral()
}
}
Include Dependencies
All Camera Kit artifacts are published under a single version. See the CHANGELOG
in the SDK download for a summary of changes in each release.
You should add the implementation dependencies necessary for your specific project. Refer to the sample apps' gradle files for specific examples.
For starters we will add the main camerakit
and support-camera
in the module level gradle file like this (replace $cameraKitVersion
with the latest SDK version in your maven directory).
implementation
implementation "com.snap.camerakit:camerakit:$cameraKitVersion"
implementation "com.snap.camerakit:support-camerax:$cameraKitVersion"
Get your API Token
To gain access to the Camera Kit service you must include your App API Token in your app configuration.
Your API Token can be found in the Snap Kit Portal and is used to provide authorized access to Camera Kit remote services.
API Token
is different for Production and Staging Environment. A watermark will be applied to the camera view when using the Staging API token.
The easiest way to include this, is to define a <meta-data>
tag in AndroidManifest.xml
with a Camera Kit application ID value under <application>
tag:
<application ...>
<meta-data android:name="com.snap.camerakit.api.token" android:value="${cameraKitApiToken}" />
</application>
Set Compile Options
Camera Kit is built targeting Java8 bytecode. This requires enabling Java8 compatibility (desugar) support via the Android Gradle Plugin (AGP) compileOptions
.
For more information, see "build configuration" in build.gradle
in the camerakit-sample-full
sample app.
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Implementiation
There are 3 main ways to implement Camera Kit in your Android app, depending the amount of customization you require.
-
Full ReferenceUI - Using the
CameraAcitvity
, You can launch an activity that provides live preview screen, Lenses carousel, shutter button, controls for inclusive camera, portrait mode, etc. This option has limited custimization options for UI and functionality. -
ReferenceUI With Configurable Session - Using the
CameraLayout
This approach is more customizable compared to that of the CameraActivity approach discussed above. This approach offers a way to customize each Camera Kit Session by registering for callbacks, it is also possible to extend this class and override the protected fields and methods if different behavior is desired. -
Use your own UI - With this approach you will bring your own custom layout and attach that to Camera Kit Session. You can either bring your own Camera implementation and pass the source to the Session object or use the CameraXImageProcessorSource from support-camerax library. This is the apporach we will be taking below.
For code snippets on how to intergrate with Reference UI check out this guide.
Check if Device is Supported
Before initializing CameraKit, it's essential to check if the device meets the minimum requirements for AR functionality. Use the supported()
method to determine whether the device supports the necessary hardware and software features.
import com.snap.camerakit.supported;
if (!supported(this)) {
// Handle the case where the device is not supported
Log.e("CameraKit", "Device is not supported");
}
This code checks if the current device supports CameraKit's AR features. If the device is not supported, you can handle it gracefully, such as by showing an error message to the user.
Initializing an Input Camera Source
We will start of by initialzing the CameraXImageProcessorSource. This class is provided by the camera kit support library to help you integrate CameraX (the Android camera API) with the Camera Kit AR system. This allows the SDK to process camera frames from the CameraX camera source and feed them into the Snapchat Camera Kit's AR pipeline, enabling real-time image processing, allowing us to apply lenses.
import com.snap.camerakit.support.camerax.CameraXImageProcessorSource
class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var imageProcessorSource = CameraXImageProcessorSource(
context = this, lifecycleOwner = this
)
}
}
Request Camera Permission
Since we're using our own UI, we need to request the necessary permission to access the device's camera.
First, make sure to declare the camera permission in your app's AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
Since the app requires access to the device's camera, we must request permission from the user. This is done in two stages: first, registering the permission request launcher, and then checking the permission status at runtime.
1. Register the Permission Request Launcher
You first need to register a launcher for the permission request. This launcher is responsible for handling the result of the permission request (whether the user grants or denies the permission).
private val requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
imageProcessorSource.startPreview(true) // Start preview if permission is granted
} else {
// Handle the case where the user denies the permission
}
}
This code registers a permission request launcher that listens for the user's response. If the permission is granted, the camera preview is started. If the permission is denied, you can handle the denial (e.g. show a message).
2. Check Permission at Runtime
Next, you need to check whether the app already has permission to use the camera. If permission is granted, you can immediately start the camera preview. If not, you need to request permission at runtime.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
imageProcessorSource.startPreview(true) // Start preview if permission is already granted
} else {
requestPermissionLauncher.launch(Manifest.permission.CAMERA) // Request permission at runtime
}
Here, ContextCompat.checkSelfPermission()
checks if the camera permission is already granted. If it is, the camera preview starts. If not, the requestPermissionLauncher is triggered to request permission from the user.
Setup your XML layout
In your layout xml file, add a ViewStub
, The Provided ViewStub
will inflate view hierarchy of Session
which includes rendering camera preview with lenses.
Add ViewStub
to xml like this:
<ViewStub
android:id="@+id/camera_kit_stub"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Initializing Camera Kit Session
To render a lens we must create a Camera Kit Session. Each session represents a rendering pipeline — it connects an input media source (e.g the CameraXImageProcessorSource) to Camera Kit's AR engine, applies a Lens, and renders the output to the ViewStub layout. If no ViewStub
is provided then Session
does not attempt to render any views while the output of camera preview can be attached to using ImageProcessor.connectOutput
. If you cannot provide ViewStub
and connect output manually then it will not be possible for lenses to receive user’s touch input.
var cameraKitSession = Session(context = this) {
imageProcessorSource(imageProcessorSource)
attachTo(findViewById(R.id.camera_kit_stub))
}
Applying AR Lens
In the Camera Kit SDK -- just like in the Snapchat app itself -- each individual AR experience is called a Lens. Lenses are created using Lens Studio. You can find more information about acquiring Lenses here.
You can find Lenses and Lens Groups in the Lens Scheduler. This is where you can manage your Lenses and Lens Groups and where you can find Lens IDs and Lens Group IDs. You can read more about managing Lenses in Lens Scheduler here.
Before applying a Lens to a session, you must load metadata about that Lens. Lenses can be loaded either one at a time, or entire Lens Groups can be loaded at once. You'll need a Lens ID and its Lens Group ID to complete this step.
cameraKitSession.apply {
lenses.repository.observe(
LensesComponent.Repository.QueryCriteria.ById(LENS_ID, LENS_GROUP_ID)
) { result ->
result.whenHasFirst { requestedLens ->
lenses.processor.apply(requestedLens)
}
}
}
Removing the Lens
You can also remove the currently-applied Lens:
cameraKitSession.lenses.processor.clear()
Handle Activity Lifecycle
The Session
instance is typically shared within a single Android application, service or activity lifecycle scope as Session
is costly in terms of memory and cpu resources it requires to operate. Once done with a Session
, It is essential to dispose it using Session#close
method which releases all the acquired resources in Camera Kit safe manner.
override fun onDestroy() {
cameraKitSession.close()
super.onDestroy()
}
Putting it all together
Using the examples above, here's a complete example of the minimal Camera Kit Android SDK integration:
class CameraViewActivity : AppCompatActivity(R.layout.activity_main) {
private lateinit var cameraKitSession: Session
private lateinit var imageProcessorSource: CameraXImageProcessorSource
companion object {
const val LENS_GROUP_ID = "REPLACE-THIS-WITH-YOUR-OWN-APP-SPECIFIC-VALUE"
const val LENS_ID = "REPLACE-THIS-WITH-YOUR-OWN-APP-SPECIFIC-VALUE"
}
// Initialize a permission request launcher
private val requestPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
startPreview()
} else {
// handle permission denied
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (!supported(this)) {
// Camera Kit not Supported on this device
return
}
imageProcessorSource = CameraXImageProcessorSource(
context = this, lifecycleOwner = this
)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
startPreview()
} else {
requestPermissionLauncher.launch(Manifest.permission.CAMERA)
}
cameraKitSession = Session(context = this) {
imageProcessorSource(imageProcessorSource)
attachTo(findViewById(R.id.camera_kit_stub))
}.apply {
lenses.repository.observe(
LensesComponent.Repository.QueryCriteria.ById(LENS_ID, LENS_GROUP_ID)
) { result ->
result.whenHasFirst { requestedLens ->
lenses.processor.apply(requestedLens)
}
}
}
}
private fun startPreview() {
imageProcessorSource.startPreview(false)
}
override fun onDestroy() {
cameraKitSession.close()
super.onDestroy()
}
Troubleshooting
The following is a list of common issues and suggestions on how to troubleshoot them when integrating Camera Kit into your own app.
Camera preview is black
- Check that your device is supported by Camera Kit using
supported()
method. The minimum OpenGLES version that Camera Kit supports is 3.0. - Check that a camera based
Source<ImageProcessor>
such asCameraXImageProcessorSource
is provided to theSession.Builder
. If you cannot provide an implementation ofSource<ImageProcessor>
then make sure to connect aSurfaceTexture
based input to the currentSession.processor
. - If no
ViewStub
is provided to theSession.Builder
then Camera Kit does not attempt to render any views such as lenses carousel as well as camera preview. To see camera preview without any other Camera Kit views, aTextureView
,SurfaceTexture
orSurface
based output must be connected to the currentSession.processor
. - If a non-null
ViewStub
is provided to theSession.Builder
check (using Layout Inspector) that the layout dimensions are more than 0 when theViewStub
gets inflated. The Camera Kit's root view that gets inflated from the providedViewStub
inherits layout parameters set on theViewStub
, check thatmatch_parent
or other parameters are applicable to your layout. - Compare versions of dependencies of your app to the Camera Kit sample apps. If dependency versions differ, for example the
camerakit-sample-full
usesandroidx.constraintlayout:constraintlayout:1.1.3
while your app usesandroidx.constraintlayout:constraintlayout:2.0.0
, it is possible that code ported from Camera Kit sample to your app may not work as expected.
Nothing works as expected
- Attach debugger to your app, enable Java exception breakpoints and build a
Session
while checking that there are no unexpected exceptions with stacktraces related to Camera Kit. - Attach debugger to your app, pause all threads and export their state into a text file - check that there are no deadlocked threads related to Camera Kit.
- Check Camera Kit FAQ page.
- Need extra support? Check our support page