Tracking Camera Access and User Interactions
- 7 Minutes to read
- Print
- DarkLight
Tracking Camera Access and User Interactions
- 7 Minutes to read
- Print
- DarkLight
Article summary
Did you find this summary helpful?
Thank you for your feedback
You can use the Android SDK to track user interactions with the camera in your app. The following examples are based on Android’s CameraX library, but tracking is also possible with other implementations with minor adjustments.
Out-of-the-box tracking includes:
Changing flash settings
Switching between front and back cameras
Taking pictures
Accessing the most recent picture
For any additional functionality, further implementation work may be required to enable tracking.
Please note
Ensure event parameters are configured correctly in your account to capture the necessary data.
//Access Camera:
view.findViewById<Button>(R.id.button).setOnClickListener {
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(
MainFragmentDirections.actionMainFragmentToPermissionsFragment()
)
//Tracking event is sent
Webtrekk.getInstance().trackCustomEvent("access camera")
}
//Take/Save image:
/** Define callback that will be triggered after a photo has been taken and saved to disk */
private val imageSavedListener = object : ImageCapture.OnImageSavedCallback {
override fun onError(imageCaptureError: Int, message: String, cause: Throwable?) {
Log.e(TAG, "Photo capture failed: $message", cause)
}
override fun onImageSaved(photoFile: File) {
Log.d(TAG, "Photo capture succeeded: ${photoFile.absolutePath}")
// We can only change the foreground Drawable using API level 23+ API
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Update the gallery thumbnail with latest picture taken
setGalleryThumbnail(photoFile)
}
// Implicit broadcasts will be ignored for devices running API
// level >= 24, so if you only target 24+ you can remove this statement
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
requireActivity().sendBroadcast(
Intent(android.hardware.Camera.ACTION_NEW_PICTURE, Uri.fromFile(photoFile))
)
}
// If the folder selected is an external media directory, this is unnecessary
// but otherwise other apps will not be able to access our images unless we
// scan them using [MediaScannerConnection]
val mimeType = MimeTypeMap.getSingleton()
.getMimeTypeFromExtension(photoFile.extension)
MediaScannerConnection.scanFile(
context, arrayOf(photoFile.absolutePath), arrayOf(mimeType), null)
//If there is no error, tracking event for taking/saving image is sent
val params: LinkedHashMap<String, String> = LinkedHashMap()
params.put("ck6", "take picture")
Webtrekk.getInstance().trackCustomEvent("click.camera.button", params)
}
}
//Change flash settings:
/** Global variable to keep state of flash mode, default value set to off */
private var flashMode = ImageCapture.FLASH_MODE_OFF
/** Listener for button used to change flash mode */
controls.findViewById<ImageButton>(R.id.flash_mode_button).setOnClickListener {
val flashResource: Int
flashMode = if (flashMode == ImageCapture.FLASH_MODE_OFF){
flashResource = R.drawable.ic_flash_auto_white_24dp;
ImageCapture.FLASH_MODE_AUTO
}
else if (flashMode == ImageCapture.FLASH_MODE_AUTO){
flashResource = R.drawable.ic_flash_on_white_24dp;
ImageCapture.FLASH_MODE_ON
}
else {
flashResource = R.drawable.ic_flash_off_white_24dp;
ImageCapture.FLASH_MODE_OFF
}
val flashButtonImage = container.findViewById<ImageButton>(R.id.flash_mode_button)
// Run the operations in the view's thread
flashButtonImage.post {
// Load thumbnail into circular button using Glide
Glide.with(flashButtonImage)
.load(flashResource)
.apply(RequestOptions.circleCropTransform())
.into(flashButtonImage)
}
//Bind use cases
bindCameraUseCases()
//Tracking event is sent
val params: LinkedHashMap<String, String> = LinkedHashMap()
params.put("ck6", "change flash setting")
Webtrekk.getInstance().trackCustomEvent("click.camera.button", params)
}
//Change lens facing to front or back:
/** Global variable to keep state of chosen camera, default values set to back camera */
private var lensFacing = CameraSelector.LENS_FACING_BACK
/** Listener for button used to switch cameras */
controls.findViewById<ImageButton>(R.id.camera_switch_button).setOnClickListener {
lensFacing = if (CameraSelector.LENS_FACING_FRONT == lensFacing) {
CameraSelector.LENS_FACING_BACK
} else {
CameraSelector.LENS_FACING_FRONT
}
//Bind use cases
bindCameraUseCases()
//Tracking event is sent
val params: LinkedHashMap<String, String> = LinkedHashMap()
params.put("ck6", "change camera")
Webtrekk.getInstance().trackCustomEvent("click.camera.button", params)
}
//Access Camera:
view.findViewById(R.id.button).setOnClickListener(v -> {
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigate(
MainFragmentDirections.actionMainFragmentToPermissionsFragment());
//Tracking event is sent
Webtrekk.getInstance().trackCustomEvent("access camera", Collections.emptyMap());
});
//Take/Save image:
/** Define callback that will be triggered after a photo has been taken and saved to disk */
private ImageCapture.OnImageSavedCallback imageSavedListener = new ImageCapture.OnImageSavedCallback() {
@Override
public void onError(int imageCaptureError, @NonNull String message, @Nullable Throwable cause) {
Log.e(TAG, "Photo capture failed: " + message, cause);
}
@Override
public void onImageSaved(@NonNull File file) {
String msg = "Pic captured at " + file.getAbsolutePath();
Log.d(TAG, "Photo capture succeeded: " + msg);
// We can only change the foreground Drawable using API level 23+ API
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Update the gallery thumbnail with latest picture taken
setGalleryThumbnail(true);
}
//If there is no error, tracking event for taking/saving image is sent
Map<String, String> params = new LinkedHashMap<>();
params.put("ck6", "take picture");
Webtrekk.getInstance().trackCustomEvent("click.camera.button", params);
}
};
//Change flash settings:
/** Global variable to keep state of flash mode, default value set to off */
private int flashMode = FlashMode.OFF;
/** Listener for button used to change flash mode */
view.findViewById(R.id.flash).setOnClickListener(v -> {
if (flashMode == FlashMode.ON) {
flashMode = FlashMode.OFF;
flashResource = R.drawable.ic_flash_off_white_24dp;
} else if (flashMode == FlashMode.OFF) {
flashMode = FlashMode.AUTO;
flashResource = R.drawable.ic_flash_auto_white_24dp;
} else if (flashMode == FlashMode.AUTO) {
flashMode = FlashMode.ON;
flashResource = R.drawable.ic_flash_on_white_24dp;
}
Glide.with(flashButton)
.load(flashResource)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.apply(RequestOptions.circleCropTransform())
.into(flashButton);
bindPreview(cameraProvider);
//Tracking event is sent
Map<String, String> params = new LinkedHashMap<>();
params.put("ck6", "change flash setting");
Webtrekk.getInstance().trackCustomEvent("click.camera.button", params);
});
//Change lens facing to front or back:
/** Global variable to keep state of chosen camera, default values set to back camera */
private int lensFacing = LensFacing.BACK;
/** Listener for button used to switch cameras */
view.findViewById(R.id.camera_switch_button).setOnClickListener(v -> {
if (lensFacing == LensFacing.BACK)
lensFacing = LensFacing.FRONT;
else
lensFacing = LensFacing.BACK;
bindPreview(cameraProvider);
//Tracking event is sent
Map<String, String> params = new LinkedHashMap<>();
params.put("ck6", "change camera");
Webtrekk.getInstance().trackCustomEvent("click.camera.button", params);
});
Was this article helpful?