Tracking Camera Access and User Interactions
    • 7 Minutes to read
    • Dark
      Light

    Tracking Camera Access and User Interactions

    • Dark
      Light

    Article summary

    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?