- Table of Contents
- Example Project
- CubiCapture Library Module
- Updating to CubiCapture 3.2.4
- Release Notes
- Glossary
- Implementation
- UI Settings
- Torch (Flashlight) Support
- About Warning Priorities
- Status Codes
- Archived Update Guides
- Archived Release Notes
This project provides an example implementation and use of the CubiCapture library module. From this project you can get the basic idea of how to implement the scanning and scan playback with CubiCapture to your app.
For your app the next step would be to upload the scan to your server and use CubiCasa Conversion API.
CubiCapture library module provides a scanning Fragment which can be used to scan a floor plan
with an Android device. The scanning Fragment saves scan files into a zip file, which your app can
upload to the CubiCasa back-end for processing. CubiCapture also provides a scan playback Fragment
which can be used to review the scan and to see any warnings that were shown during the scan, as well
as any room labels that were added.
- Update your app to use the CubiCapture 3.2.4 library module
- Update the app level
build.gradledependencies (see Implementation) - Consider validating scan data before uploading the scan. See Validating the Scan Data for details
Note! If you've previously implemented version 3.2.2 you've probably done the next steps already:
- Update the implementations of
CubiEventListenerandTrueNorthto use their new package location:cubi.casa.cubicapture.utils.* - See the changes to the UI, including new scan guides/warnings, the new
"Lower the device" warning, and the new setting to configure the capture photo button position
(
isCapturePhotoButtonOnRight: Boolean). Refer to UI settings if you want to customize the colors, drawables, dimensions, or strings, and update your resource values accordingly - See Release Notes for new, changed, or removed methods and status codes
Note! If you've previously implemented version 3.1.1 you've probably done the next steps already:
- If you used speech recognition, the
RECORD_AUDIOandINTERNETpermissions, andandroid.speech.RecognitionServicecan be removed from theAndroidManifest.xml - Update your scanning
Activityto use portrait orientation. Addandroid:screenOrientation="portrait"to theactivitytag of the scanningActivityin theAndroidManifest.xml, and addrequestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAITto theonCreate()method of the scanningActivity - See the changes to the UI, including new scan guides/warnings, the new vertical tilt warning, and the end scan confirmation dialog. Refer to UI settings if you want to customize the colors, drawables, dimensions, or strings, and update your resource values accordingly.
- Remove
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)andCubiCapture.registerCallback(activity: Activity)as these are now handled by the CubiCapture SDK - Check if you want to enable the photo capturing option
- See Release Notes for CubiCapture methods that have been changed to properties, renamed variables, removed views, methods, and properties, and new, changed, and removed status codes. Update your code accordingly
For older update guides, see Archived Update Guides
3.2.4:
- Added
ScanDataValidatorfor validating scan data (see Validating the Scan Data) - Various bug fixes and improvements
- Updated dependencies (see Implementation)
3.2.2:
- Revised UI and warnings (see UI settings)
- Added Torch (Flashlight) Support
- Added a "Lower the device" warning
- Added a new setting for configuring the capture photo button position
(
isCapturePhotoButtonOnRight: Boolean) - The previously available
getAvailableStorageMinutes(File)method has been removed and replaced with:estimatePreScanStorageMinutes(File)for pre-scan storage estimationestimateRemainingStorageMinutes()for estimating storage during a scan
- The previously available
zipScan(File)method has been removed and replaced with the newScanZipper.zip(...)method. See Manual Zipping for details - New status codes:
- Replaced status code 56 with a new status code: 56, "Failed to write config file"
- Changes to the descriptions of status codes: 6, 7, 15, 19, 51, 54, 56, 90, 91, 93, 103, and 106
- Removed status codes: 12, 50, 55, 57, 58, 60, 61, 62, and 64
- Performance improvements
- Various fixes and improvements
- Updated CubiCapture's
targetSdkVersionto API level35 - Updated dependencies (see Implementation)
3.1.3:
- Performance improvements
- Updated CubiCapture's
targetSdkVersionto API level34 - Updated dependencies (see Implementation below)
3.1.1:
- Scanning orientation is now portrait
- Added photo capturing option
- New UI, scan guides and end scan confirmation dialog
- Added vertical tilt warning
- Added camera permission handling
- Dropped speech recognition and depth capturing
- Aborting scan if the device is in the wrong orientation for too long
- Improved drift detection: Scan now aborts if device position shows unnatural "sliding" behavior, while "jumps" do not cause the scan to abort
- CubiCapture now adds flags to keep the screen on
- Removed
registerCallback(activity: Activity). Callback is now registered automatically setTimerEnabled(enabled: Boolean)is nowtimerEnabled: Boolean,setBackButtonEnabled(enabled: Boolean)is nowbackButtonEnabled: Boolean,setRecordButtonEnabled(enabled: Boolean)is nowrecordButtonEnabled: Boolean,setWarningSound(resId: Int)is nowtrackingWarningSoundResId: Int,setAutoZippingEnabled(enabled: Boolean)is nowautoZippingEnabled: Boolean, andCubiEventListenermethodgetPropertyType(): PropertyTypeis nowpropertyType: PropertyType- Removed reminder views, hint labels,
matchHintLabelWidth: Boolean,requestLocationServices: Boolean,TrueNorth.ENABLED_AND_REQUEST,setNewView(), andsetOrderInfo() scanFolderNameandallScansFolderrenamed asscanDirectoryNameandallScansDirectory, respectively- Updated dependencies (see Implementation below). Removed
com.facebook.shimmer:shimmerdependency - New status codes 14, "The device was in the wrong orientation for too long.", 116, "Device position jumped in an unnatural manner.", and CAMERA permission related codes 120-124
- Changes to status codes 0, 13, 16, 17, 18, 21, and 23
- Removed status codes 20, 22, 31-49, 59, 95-98, and 103
For older release notes, see Archived Release Notes
| Term | Description |
|---|---|
| Scan | The process of capturing the surroundings in indoor space using the phone's camera. |
| ARCore | Google's Augmented Reality library that is used in CubiCapture library for scanning. |
| Tracking | The process of aligning the device to it's surroundings properly. We use ARCore to track where the phone is relative to the world around it. |
| Sideways walk | An error which occurs during a scan when the user walks sideways. Walking sideways makes it hard to track the position of the device and can affect the quality of the scan. |
This implementation was made with Android Studio Narwhal Feature Drop | 2025.1.2 Patch 1 using Android Gradle Plugin version 8.12.1.
Start by downloading the Android library module.
Add the CubiCapture library module to your project:
- Place the
cubicapture-release-3.2.4.aarfile to your project'sapp/libs/folder. - In Android Studio navigate to:
File->Project Structure->Dependencies->app-> In theDeclared Dependenciestab, click+and selectJAR/AAR Dependency. - In the
JAR/AAR Dependencydialog, enter the path aslibs/cubicapture-release-3.2.4.aarand selectimplementationas configuration. -> PressOK,ApplyandOK. - Check your app's
build.gradlefile to confirm a that in contains the following declaration:implementation files('libs/cubicapture-release-3.2.4.aar').
Add the following lines to the app level build.gradle inside the dependencies branch:
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation files('libs/cubicapture-release-3.2.4.aar')
implementation 'com.google.ar:core:1.50.0'
implementation 'com.google.code.gson:gson:2.13.1'
implementation 'com.jaredrummler:android-device-names:2.1.1'
// Implement the following if 'CubiCapture.trueNorth' is set to 'ENABLED':
implementation 'com.google.android.gms:play-services-location:21.3.0'
// Implement the following if using 'ScanPlayback':
implementation 'androidx.recyclerview:recyclerview:1.4.0'
implementation 'androidx.media3:media3-exoplayer:1.8.0'Add CubiCapture fragment to your projects scanning layout .xml file:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/cubiFragment"
android:name="cubi.casa.cubicapture.CubiCapture"
android:layout_width="match_parent"
android:layout_height="match_parent" />To allow your scanning Activity to consume more RAM, to lock screen orientation to portrait
and to prevent multiple onCreate() calls add the following code to your AndroidManifest file
inside your scanning Activity's activity tag. Example:
<activity
android:name=".ExampleActivity"
android:largeHeap="true"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize" />Declare a lateinit variable for CubiCapture in your scanning Activity:
private lateinit var cubiCapture: CubiCaptureInitialize the CubiCapture fragment in onCreate():
cubiCapture = supportFragmentManager.findFragmentById(R.id.cubiFragment) as CubiCaptureImplement CubiEventListener interface in your scanning Activity. Example:
class ExampleActivity : AppCompatActivity(), CubiEventListenerAdd the following method to receive status updates from CubiEventListener:
override fun onStatus(code: Int, description: String) { }Add the following method to receive the scan directory and the zip file as File from
CubiEventListener:
override fun onFile(code: Int, file: File) { }Where code 1 is the scan directory and code 2 is the scan zip file.
Set the directory where all scan directories will be stored. Example:
cubiCapture.allScansDirectory = getExternalFilesDir(null) ?: filesDirSet the scan output directory name. Example:
cubiCapture.scanDirectoryName = UUID.randomUUID().toString()Set the property type. Example:
val selectedPropertyType: PropertyType = // ...
cubiCapture.propertyType = selectedPropertyTypePossible values for the PropertyType are SINGLE_UNIT_RESIDENTIAL, TOWNHOUSE, APARTMENT, and OTHER.
Add your app's version information to the scan data (optional). Example:
cubiCapture.appVersion = BuildConfig.VERSION_NAME // e.g. String "1.2.3"
cubiCapture.appBuild = BuildConfig.VERSION_CODE // e.g. Int 25Override the Activity#onWindowFocusChanged(hasFocus: Boolean) method to call
CubiCapture#onWindowFocusChanged(hasFocus: Boolean, activity: Activity) to allow CubiCapture
to handle its internal processes accordingly based on the window focus change:
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
cubiCapture.onWindowFocusChanged(hasFocus, this)
}You should also prevent Navigation bar back presses during saving. Example:
// Handle back press: Move to background if saving; otherwise, finish activity.
onBackPressedDispatcher.addOnClickListener(this) {
// The saving variable is set to true when onStatus() receives code 2.
if (saving) {
moveTaskToBack(true)
} else {
finish()
}
}You should check that the device has ARCore installed and that it's up-to-date before starting the scanning activity.
Scanning requires the CAMERA permission to be granted. The permission is already declared in the
library's manifest. Upon start, CubiCapture checks whether the permission is granted and shows a
missing permission view if it is not.
If you want to declare your app as "AR Required", add the following entry to your
AndroidManifest.xml file inside the application tag. This ensures that
the app is only visible to devices that support ARCore:
<!-- "AR Required" app, requires "Google Play Services for AR" (ARCore) to be installed -->
<meta-data android:name="com.google.ar.core" android:value="required" />To avoid memory leaks, always remember to call finish() when your activity is done and should be closed.
You should call finish() when you receive status code 5 or 19.
True north detection can be used to enable the CubiCapture to capture the heading relative to the "true north" to the scan. This information can then be used to add the information the floor plan (e.g. compass). In order to the true north data to be collected, the Location Services must be turned on and the location permission must be granted. No position data is collected by the CubiCapture.
True north detection trueNorth has the following two settings:
| Name | Description |
|---|---|
TrueNorth.DISABLED |
True north detection disabled |
TrueNorth.ENABLED |
True north detection enabled |
Example, where we enable the true north detection:
cubiCapture.trueNorth = TrueNorth.ENABLEDtrueNorth is set to TrueNorth.ENABLED by default.
If you are going to use true north detection you need to declare the ACCESS_COARSE_LOCATION and
ACCESS_FINE_LOCATION permissions in your app's manifest file, and request the ACCESS_FINE_LOCATION
permission before the scan. You also need to implement the Google Play services' location library
by adding it to the app level build.gradle dependencies (see the build.gradle implementation
in the start of Implementation above).
CubiCapture provides two functions to estimate the scan duration that can be stored on the
device based on the available storage space. These functions help understand storage availability
either before starting a scan or during an ongoing scan.
The estimatePreScanStorageMinutes(File) method estimates the maximum scan duration (in minutes)
that can be stored on the device before starting a scan.
This method is useful for warning the user if storage space is insufficient before initiating the scanning process.
Example:
val allScansDirectory = getExternalFilesDir(null) ?: filesDir
val estimatedMinutes: Int = CubiCapture.estimatePreScanStorageMinutes(allScansDirectory)
if (estimatedMinutes <= 60) {
showLowStorageWarning(estimatedMinutes)
}The estimateRemainingStorageMinutes() method estimates the remaining scan duration (in minutes)
during an ongoing scan. Ensure that allScansDirectory is initialized before using this method.
Example:
val remainingMinutes: Int = cubiCapture.estimateRemainingStorageMinutes()Note: Calling estimateRemainingStorageMinutes() without initializing the allScansDirectory
will throw an IllegalStateException.
Scan playback is a Fragment which can be used to review the scan and to see any warnings that were
shown during the scan, as well as any room labels that were added.
The Fragment has a media control panel that can be used to play/pause, jump between scan events
and video frames one by one. All the scan events can be found in the Events list, which can be used
to easily jump between the events. The active events are displayed in the area above the Events
list. The video playback speed can be changed from the top bar which appears when the video is in
paused state.
To implement the ScanPlayback, first add the required dependencies (see Implementation).
Add ScanPlayback fragment to your projects scan playback's XML layout file:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/scanPlayback"
android:name="cubi.casa.cubicapture.ScanPlayback"
android:layout_width="match_parent"
android:layout_height="match_parent" />Declare a lateinit variable for ScanPlayback in your scan playback Activity:
private lateinit var scanPlayback: ScanPlaybackInitialize the ScanPlayback lateinit variable in onCreate():
scanPlayback = supportFragmentManager.findFragmentById(R.id.scanPlayback) as ScanPlaybackImplement ScanPlaybackListener interface to your scan playback Activity - Example:
class ViewScanActivity : AppCompatActivity(), ScanPlaybackListenerAdd the following function to receive updates when the playing state changes (playing/paused):
override fun onIsPlayingChanged(isPlaying: Boolean) { }Set the scan folder of the scan you want to playback with setScanFolder(scanFolder: File) in onCreate().
This function will return true if the scan folder has a video file, otherwise false. Example:
scanPlayback.setScanFolder(scanFolder)Set on View.OnClickListener for the top bar's back button. Example:
scanPlayback.setOnBackButtonClickListener {
finish()
}Starting with release 3.1.1, the CubiCapture SDK now includes the option to enable users to take photos during scanning. These photos are included in the scan directory and the scan zip file.
Enable or disable photo capturing (disabled by default):
cubiCapture.photoCapturingEnabled = trueSafe mode can be used to disable the ARCore's Depth API to prevent any native ARCore crashes caused by any possible bugs in ARCore's Depth API. We recommend implementing a Safe mode setting to your app. The setting should only be visible to users with a Depth API supported device, and user should enable the Safe mode if they are experiencing stability issues while scanning. Enabling the Safe mode will disable the Depth API and Too close -warning.
To check if the device is Depth API supported, check the value of depthApiSupported: Boolean after
receiving code 1 from onStatus(code: Int, description: String). Save this value to, for example,
SharedPreferences. And then use the saved value to determine if the Safe mode setting should be
visible to the user or not.
Then enable or disable the Safe mode based on the user's selection. Example:
val settings = getSharedPreferences("settings", 0)
cubiCapture.safeMode = settings.getBoolean("safeMode", false)safeMode: Boolean is set to false by default. Value is ignored on devices which do not support
Depth API, because the Depth API and Too close -warning is disabled on those devices by default.
Warning sound is played when the ARCore's TrackingState is not TRACKING.
To change the tracking warning sound call:
cubiCapture.trackingWarningSoundResId = R.raw.new_warning_soundCubiCapture provides flexibility for zipping scan files, allowing either automatic or manual zipping based on your application's needs.
Automatic zipping is enabled by default, meaning scan files are automatically compressed after the scan completes. You can disable this behavior if you prefer to handle zipping manually:
cubiCapture.autoZippingEnabled = falseIf automatic zipping is disabled, you can manually compress scan files using the ScanZipper.zip
method. This should be called only after all scan files are successfully saved.
The manual zip method expects the scan directory to contain the following files:
arkitData.json, config.json and video.mp4.
If any of these required files are missing, the zipping operation will fail, triggering the error
callback with a MissingRequiredFilesException.
Example Usage:
val zipUUID = UUID.randomUUID().toString()
val zipFile = File(scanDirectory, "$zipUUID.zip")
ScanZipper.zip(
scanDirectory = scanDirectory,
zipFile = zipFile,
onSuccess = { createdZipFile ->
// Handle success: The zip file has been created successfully.
},
onError = { exception ->
// Handle error: Missing required files or zipping failure.
}
)The zip method performs the operation in a background coroutine to avoid blocking the main thread.
Both the success and error callbacks are executed on the main thread, ensuring UI safety.
For the zip method to succeed, the scan directory must contain all required files.
Optional files will be included in the zip if present.
Here’s an example directory structure where zipping will succeed:
.
└── AllScansDirectory
├── ExampleScanDirectory
│ ├── arkitData.json
│ ├── config.json
│ ├── video.mp4
│ ├── feedback.json
│ ├── scanLog.json
│ ├── UUID*.jpg <- 0 or more snapshot files
│ └── photo_capturer.json
Note: The UUID*.jpg and photo_capturer.json files will only be present if photos were taken
during the scan.
Before uploading a scan, it's a good practice to validate that all required data is present and
consistent. The ScanDataValidator utility offers a straightforward way to verify the integrity
of the scan files in a given directory.
The validator checks for several conditions:
- The scan directory exists.
- All required files (
arkitData.json,config.json,video.mp4) are present. - The JSON files are not empty.
- The frame counts between the video and AR data are consistent.
The validation is performed synchronously and returns a ScanDataValidationResult.
val result = ScanDataValidator.validateScanData(scanDirectory)
when (result) {
is ScanDataValidationResult.Valid -> {
// Validation successful.
}
is ScanDataValidationResult.Invalid -> {
// Handle the validation error.
// Example debug log:
Log.e("ScanValidation", "Validation failed: ${result.errorType} - ${result.message}")
}
}The validateScanData method returns a ScanDataValidationResult object,
which can be one of two types:
ScanDataValidationResult.Valid: Returned when the scan data passes all integrity checks.ScanDataValidationResult.Invalid: Returned when the scan data is found to be invalid. This object contains two properties:errorType: An enum specifying the kind of problem found.message: A string describing the specific error.
When validation fails, the Invalid result will contain one of the following ErrorType values:
| ErrorType | Description |
|---|---|
DIRECTORY_NOT_FOUND |
The specified scanDirectory does not exist. |
FILES_MISSING |
One or more required files (arkitData.json, config.json, video.mp4) are missing from the directory. |
FILE_EMPTY |
The arkitData.json or config.json file was found but is empty. |
VIDEO_FRAME_EXTRACTION_FAILED |
The validator was unable to extract the frame count from the video.mp4 file. |
AR_FRAME_EXTRACTION_FAILED |
The validator was unable to extract the frame count from the arkitData.json file. |
FRAME_COUNT_INCONSISTENCY |
The number of frames in the video and AR data files are inconsistent. |
UNKNOWN_ERROR |
An unexpected exception occurred during the validation process. |
Position of the capture photo button. By default, it’s on the right:
cubiCapture.isCapturePhotoButtonOnRight = falseWhether to initialize and display the scan timer. Initialized and visible by default:
cubiCapture.timerEnabled = falseWhether to display the CubiCapture's close button. Visible by default:
cubiCapture.closeButtonEnabled = falseEnable or disable the record button. Enabled by default:
cubiCapture.recordButtonEnabled = falseEnable or disable low storage warnings. Enabled by default:
cubiCapture.storageWarningsEnabled = falseTo customize the colors or alphas of the default CubiCapture graphics, you need to redefine the
default colors in your application's colors.xml file.
Below is the list of all default colors and alphas defined in the CubiCapture library:
<!-- Scan related texts colors -->
<color name="cc_scan_text_color">#FDFDFD</color>
<color name="cc_guide_title_text_color">#E6F0FA</color>
<color name="cc_guide_info_text_color">#E6F0FA</color>
<color name="cc_processing_text_color">#FDFDFD</color>
<color name="cc_photo_count_non_zero_text_color">#0C2F46</color>
<!-- Scan close button background color. Only visible when fullscreen guide is shown -->
<color name="cc_scan_button_close_background_color">#131619</color>
<!-- Scan timer background colors -->
<color name="cc_scan_timer_background_color">#B62138</color>
<color name="cc_scan_timer_idle_background_color">#FDFDFD</color>
<!-- Record button colors -->
<color name="cc_record_button_primary_color">#FDFDFD</color>
<color name="cc_record_button_recording_fill_color">#B62138</color>
<!-- Photo capture button background color -->
<color name="cc_button_capture_photo_background_color">#FDFDFD</color>
<!-- Scan guide colors -->
<color name="cc_guide_warning_solid_color">#E0131619</color>
<color name="cc_guide_warning_stroke_color">#ECA80D</color>
<color name="cc_guide_info_solid_color">#E0131619</color>
<color name="cc_guide_info_stroke_color">#5DB2A7</color>
<!-- Colors for the scan guide warning corners -->
<color name="cc_guide_warning_corners_solid_color">#FE566F</color>
<color name="cc_guide_warning_corners_stroke_color">#FDFDFD</color>
<!-- Scan overlay colors -->
<!-- Note: Default gradient colors transition from lower opacity to higher opacity -->
<color name="cc_overlay_default_stroke_color">#5DB2A7</color>
<color name="cc_overlay_warning_stroke_color">#ECA80D</color>
<color name="cc_overlay_start_scanning_solid_color">#66131619</color>
<color name="cc_overlay_warning_solid_color">#665E1B2B</color>
<color name="cc_overlay_warning_gradient_start_color">#00E6F0FA</color>
<color name="cc_overlay_warning_gradient_center_color">#7AB62138</color>
<color name="cc_overlay_warning_gradient_end_color">#A3611225</color>
<!-- Request permission button background and text color -->
<color name="cc_permission_request_button_background_color">#FDFDFD</color>
<color name="cc_permission_request_button_text_color">#131619</color>
<!-- Scan dialog background and button colors -->
<color name="cc_dialog_background_color">#0C2F46</color>
<color name="cc_dialog_button_positive_text_color">#FDFDFD</color>
<color name="cc_dialog_button_negative_text_color">#FDFDFD</color>
<color name="cc_dialog_button_positive_gradient_start_color">#1D4357</color>
<color name="cc_dialog_button_positive_gradient_end_color">#008674</color>
<color name="cc_dialog_button_negative_stroke_color">#FDFDFD</color>
<!-- Processing view progress bar color -->
<color name="cc_processing_progress_bar_color">#FDFDFD</color>
<!-- Scan playback text color for events and playback speed spinner -->
<color name="ccPlaybackMainTextColor">#FDFDFD</color>
<!-- Scan playback text color for "Events", "Frame" and "Time" texts -->
<color name="ccPlaybackControllerTextColor">#569789</color>
<!-- Scan playback main background color -->
<color name="ccPlaybackBackgroundColor">#071d29</color>
<!-- Scan playback top bar background color -->
<color name="ccPlaybackTopBarBackgroundColor">#80071d29</color>
<!-- Scan playback events container background color -->
<color name="ccEventsContainerBackgroundColor">#80071d29</color>
<!-- Scan playback controller background color -->
<color name="ccPlaybackControllerBackgroundColor">#163241</color>
<!-- Scan playback controller button tint -->
<color name="ccPlaybackControllerButtonTint">#569789</color>
<!-- Scan playback event colors -->
<color name="ccPlaybackWarningColor">#B85E1B2B</color>
<color name="ccPlaybackSpaceLabelColor">#B8569789</color>
<!-- Scan playback timeline colors -->
<color name="ccTimelineBackgroundColor">#3A3A3A</color>
<color name="ccTimelineWarningColor">#B85E1B2B</color>
<color name="ccTimelineSpaceLabelColor">#B8569789</color>
<color name="ccTimelineThumbColor">#FDFDFD</color>
<!-- Scan playback scrollbar color -->
<color name="ccPlaybackScrollbarColor">#FDFDFD</color>For example, if you want to change the color and alpha of the scan timer's background,
you can define the new colors in your application's colors.xml file like this:
<!-- Scan timer background colors -->
<color name="cc_scan_timer_background_color">#FFFF0000</color>
<color name="cc_scan_timer_idle_background_color">#FFFFFFFF</color>The colors can be defined using either the #RRGGBB color notation or the #AARRGGBB notation,
which includes a hexadecimal alpha value.
To customize CubiCapture's default layout sizes, margins, and text sizes, you need to override the
library's default dimensions by defining them in your application's dimens.xml file.
This file should be located in the values directory.
For different screen sizes (e.g., tablets), you can define specific dimensions by creating a
dimens.xml file in the corresponding resource directory, such as values-sw600dp for tablets
with a screen width of at least 600dp.
Below is the list of all default dimensions defined in the CubiCapture library for phones and tablets:
Phones (values/dimens.xml):
<!--
Scan close button size, background radius and background margin
Note:
- Scan close button is constrained to vertically center the scan timer
- Scan close button's background margin is applied to the original background drawable item
-->
<dimen name="cc_scan_button_close_size">24dp</dimen>
<dimen name="cc_scan_button_close_background_radius">10dp</dimen>
<dimen name="cc_scan_button_close_background_margin">12dp</dimen>
<!-- Scan timer margin top, width and background radius -->
<dimen name="cc_scan_timer_width">96dp</dimen>
<dimen name="cc_scan_timer_height">24dp</dimen>
<dimen name="cc_scan_timer_background_radius">36dp</dimen>
<!-- Scan guide margins, paddings, and max width -->
<dimen name="cc_guide_margin">16dp</dimen>
<dimen name="cc_guide_text_contents_padding">16dp</dimen>
<dimen name="cc_guide_info_text_margin_top">4dp</dimen>
<dimen name="cc_guide_max_width">560dp</dimen>
<!-- Scan guide text sizes -->
<dimen name="cc_guide_title_text_size">20dp</dimen>
<dimen name="cc_guide_info_text_size">14dp</dimen>
<!-- Scan overlay stroke width -->
<dimen name="cc_overlay_stroke_width">2dp</dimen>
<!-- Scan guide icon height (using scale type center inside) -->
<dimen name="cc_guide_icon_height">160dp</dimen>
<!-- Scan guide background radius and stroke width -->
<dimen name="cc_guide_background_radius">8dp</dimen>
<dimen name="cc_guide_background_stroke_width">2dp</dimen>
<!-- Scan fullscreen guide padding -->
<dimen name="cc_guide_fullscreen_padding">32dp</dimen>
<!-- Scan fullscreen guide icon height -->
<dimen name="cc_guide_fullscreen_icon_height">72dp</dimen>
<!-- Scan fullscreen guide text margins -->
<dimen name="cc_guide_fullscreen_title_text_margin_top">32dp</dimen>
<dimen name="cc_guide_fullscreen_info_text_margin_top">16dp</dimen>
<!-- Scan controls container paddings and item margin (gap between items) -->
<dimen name="cc_scan_controls_container_padding_top">16dp</dimen>
<dimen name="cc_scan_controls_container_padding_bottom">24dp</dimen>
<dimen name="cc_scan_controls_item_margin">56dp</dimen>
<!-- Scan header container paddings -->
<dimen name="cc_scan_header_container_padding_horizontal">16dp</dimen>
<dimen name="cc_scan_header_container_padding_vertical">24dp</dimen>
<!-- Record button size -->
<dimen name="cc_button_record_size">64dp</dimen>
<!-- Photo capture button size, stroke width, and icon size-->
<dimen name="cc_button_capture_photo_button_size">56dp</dimen>
<dimen name="cc_button_capture_photo_button_stroke_width">2dp</dimen>
<dimen name="cc_button_capture_photo_icon_size">32dp</dimen>
<!-- Photo thumbnail size -->
<dimen name="cc_photo_thumbnail_size">56dp</dimen>
<!-- Photo count background (non-zero) and text size-->
<dimen name="cc_photo_count_non_zero_text_background_size">24dp</dimen>
<dimen name="cc_photo_count_text_size">12dp</dimen>
<!-- Request permission button radius, padding horizontal and margin top -->
<dimen name="cc_permission_request_button_radius">100dp</dimen>
<dimen name="cc_permission_request_button_padding_horizontal">32dp</dimen>
<dimen name="cc_permission_request_button_margin_top">32dp</dimen>
<!-- Scan dialog dimensions -->
<dimen name="cc_dialog_padding">32dp</dimen>
<dimen name="cc_dialog_margin">16dp</dimen>
<dimen name="cc_dialog_info_text_margin_top">16dp</dimen>
<dimen name="cc_dialog_button_positive_margin_top">24dp</dimen>
<dimen name="cc_dialog_button_negative_margin_top">16dp</dimen>
<dimen name="cc_dialog_background_radius">16dp</dimen>
<dimen name="cc_dialog_button_radius">100dp</dimen>
<dimen name="cc_dialog_button_negative_stroke_width">1dp</dimen>
<!-- Processing view progress bar size scale -->
<dimen name="cc_progress_bar_size_scale">1.6</dimen>
<!-- Processing view processing text margin -->
<dimen name="cc_processing_text_margin">16dp</dimen>
<!-- Scan timer text size -->
<dimen name="cc_text_size_scan_timer">14dp</dimen>
<!-- Heading 1 text size -->
<dimen name="cc_text_size_heading_1">20dp</dimen>
<!-- Heading 2 text size -->
<dimen name="cc_text_size_heading_2">16dp</dimen>
<!-- Body 1 text size -->
<dimen name="cc_text_size_body_1">16dp</dimen>
<!-- Body 2 text size -->
<dimen name="cc_text_size_body_2">14dp</dimen>
<!-- Scan playback controller button width percent -->
<dimen name="cc_controller_button_width_percent">0.10</dimen>
<!-- Scan playback small text size (Used for all texts except active events) -->
<dimen name="cc_playback_text_size_small">14dp</dimen>
<!-- Scan playback big text size (Used for active events) -->
<dimen name="cc_playback_text_size_big">20dp</dimen>Tablets (values-sw600dp/dimens.xml):
<!-- Scan close button size-->
<dimen name="cc_scan_button_close_size">32dp</dimen>
<!-- Scan timer margin top, width and background radius -->
<dimen name="cc_scan_timer_width">136dp</dimen>
<dimen name="cc_scan_timer_height">44dp</dimen>
<dimen name="cc_scan_timer_background_radius">36dp</dimen>
<!-- Scan guide text sizes -->
<dimen name="cc_guide_title_text_size">20dp</dimen>
<dimen name="cc_guide_info_text_size">20dp</dimen>
<!-- Scan guide icon height (using scale type center inside) -->
<dimen name="cc_guide_icon_height">210dp</dimen>
<!-- Scan controls container paddings -->
<dimen name="cc_scan_controls_container_padding_top">32dp</dimen>
<dimen name="cc_scan_controls_container_padding_bottom">32dp</dimen>
<!-- Scan header container paddings -->
<dimen name="cc_scan_header_container_padding_horizontal">16dp</dimen>
<dimen name="cc_scan_header_container_padding_vertical">24dp</dimen>
<!-- Record button size -->
<dimen name="cc_button_record_size">88dp</dimen>
<!-- Photo capture button and icon size-->
<dimen name="cc_button_capture_photo_button_size">72dp</dimen>
<dimen name="cc_button_capture_photo_icon_size">32dp</dimen>
<!-- Photo thumbnail size -->
<dimen name="cc_photo_thumbnail_size">72dp</dimen>
<!-- Photo count background (non-zero) and text size-->
<dimen name="cc_photo_count_non_zero_text_background_size">32dp</dimen>
<dimen name="cc_photo_count_text_size">20dp</dimen>
<!-- Scan timer text size -->
<dimen name="cc_text_size_scan_timer">20dp</dimen>For example, if you want to change the size of the record button, you can define the new size in
your application's dimens.xml file like this:
<!-- Record button size -->
<dimen name="cc_button_record_size">72dp</dimen>For tablets, you can define a different size in values-sw600dp/dimens.xml:
<!-- Record button size -->
<dimen name="cc_button_record_size">96dp</dimen>To change CubiCapture's default texts, you need to override the library's default strings by
redefining them in your application's strings.xml file.
Below is the list of all default texts defined in the CubiCapture library:
<!-- Displayed when the ARCore is initializing -->
<string name="cc_tracking_initializing_title">Setting up…</string>
<string name="cc_tracking_initializing_info">Move your device so we can begin tracking your position</string>
<!-- Displayed when ready to start scanning -->
<string name="cc_start_scanning_title">Press Record</string>
<string name="cc_start_scanning_info">Start moving to scan</string>
<!-- Displayed if tracking is lost due to excessive motion -->
<string name="cc_tracking_excessive_motion_title">Slow down</string>
<string name="cc_tracking_excessive_motion_info">You are moving too fast, move slower</string>
<!-- Displayed if tracking is lost due to insufficient visual features -->
<string name="cc_tracking_insufficient_features_title">Lack of visual features</string>
<string name="cc_tracking_insufficient_features_info">Point the camera at distinctive features</string>
<!-- Displayed if tracking is lost due to poor lighting conditions -->
<string name="cc_tracking_insufficient_lighting_title">Turn the lights on</string>
<string name="cc_tracking_insufficient_lighting_info">It is too dark here</string>
<!-- Displayed if the user is walking sideways -->
<string name="cc_guide_sideways_left_title">Turn left</string>
<string name="cc_guide_sideways_right_title">Turn right</string>
<string name="cc_guide_sideways_left_info">Point the camera in your walking direction</string>
<string name="cc_guide_sideways_right_info">Point the camera in your walking direction</string>
<!-- Displayed title and info text for the rotate warning -->
<string name="cc_guide_rotate_title">Rotate your device</string>
<string name="cc_guide_rotate_info">Please scan in portrait orientation</string>
<!-- Displayed if the device is tilted forward too much -->
<string name="cc_guide_raise_device_title">Raise your device</string>
<string name="cc_guide_raise_device_info">You\'re pointing too much at the floor</string>
<!-- Displayed if the device is tilted up too much -->
<string name="cc_guide_lower_device_title">Lower your device</string>
<string name="cc_guide_lower_device_info">You\'re pointing too much at the ceiling</string>
<!-- Displayed if the user is rotating/turning too fast -->
<string name="cc_guide_fast_rotation_title">Turn slowly</string>
<string name="cc_guide_fast_rotation_info">Avoid fast turns for best scanning results</string>
<!-- Displayed if the user is scanning too close to objects -->
<string name="cc_guide_too_close_title">You\'re too close</string>
<string name="cc_guide_too_close_info">Keep more distance from the objects you\'re scanning</string>
<!-- Displayed if the device's storage space is running low -->
<string name="cc_guide_low_storage_title">Low storage</string>
<!-- Note! Always include the %1$d in the info string! -->
<string name="cc_guide_low_storage_info">Only %1$d minutes of scanning time left</string>
<!-- Displayed if the device experiences thermal throttling -->
<string name="cc_guide_throttling_title">Device getting hot</string>
<string name="cc_guide_throttling_info">You can continue scanning, but move slowly</string>
<!-- Displayed if camera permission is not granted -->
<string name="cc_permission_camera_title">No camera access</string>
<string name="cc_permission_camera_info">Cannot scan without camera permission. Please allow access to the camera</string>
<!-- Displayed if permission is not granted -->
<string name="cc_permission_request_button_text">Turn on</string>
<!-- Displayed if record button is pressed to finish scan -->
<string name="cc_dialog_finish_scan_title">Finish scan?</string>
<string name="cc_dialog_finish_scan_info">Are you sure you want to finish this scan?</string>
<!-- Displayed if close button is pressed to cancel scan -->
<string name="cc_dialog_cancel_scan_title">Cancel scan?</string>
<string name="cc_dialog_cancel_scan_info">Are you sure you want to cancel this scan?</string>
<!-- Displayed positive and negative button texts for scan dialogs -->
<string name="cc_dialog_button_positive_text">Yes</string>
<string name="cc_dialog_button_negative_text">No</string>
<!-- Displayed in the processing view after recording is finished -->
<string name="cc_processing_text">Processing scan.\nPlease do not exit the application.</string>
<!-- Scan playback speed spinner text. Always include the %1$s in the string!-->
<string name="cc_playback_speed_text">Playback speed: %1$s</string>
<!-- Scan playback speed spinner text for normal speed -->
<string name="cc_playback_normal_speed_text">Normal</string>
<!-- Scan playback events header text -->
<string name="cc_playback_events_header_text">Events</string>
<!-- Scan playback frame text. Always include the %1$s in the string!-->
<string name="cc_playback_frame_text">Frame: %1$s</string>
<!-- Scan playback time text. Always include the %1$s in the string!-->
<string name="cc_playback_time_text">Time: %1$s</string>
<!-- Scan playback active event texts -->
<string name="cc_playback_excessive_motion">Moving too fast</string>
<string name="cc_playback_insufficient">Insufficient lighting or features</string>
<string name="cc_playback_sideways">Walking sideways</string>
<string name="cc_playback_floor">Scanning floor</string>
<string name="cc_playback_ceiling">Scanning ceiling</string>
<string name="cc_playback_horizontal">Scanning horizontally</string>
<string name="cc_playback_wrong_orientation">Wrong device orientation</string>
<string name="cc_playback_fast_rotation">Turning too fast</string>
<string name="cc_playback_too_close">Too close</string>To change CubiCapture's default drawables, you need to override them by redefining the drawables
in your application's drawables.xml file. This file should be located in the values directory.
Below is the list of all default drawables defined in the CubiCapture library:
<!--
Scan close button icon and background.
Note: Background is only visible when fullscreen guide is shown
-->
<drawable name="cc_scan_button_close_icon">@drawable/cc_icon_close</drawable>
<drawable name="cc_scan_button_close_background">@drawable/cc_close_button_background</drawable>
<!-- Scan timer background -->
<drawable name="cc_scan_timer_background">@drawable/cc_timer_background</drawable>
<drawable name="cc_scan_timer_idle_background">@drawable/cc_timer_idle_background</drawable>
<!-- Photo count non-zero text background -->
<drawable name="cc_photo_count_non_zero_text_background">@drawable/cc_photo_count_text_background</drawable>
<!-- Record button -->
<drawable name="cc_not_recording">@drawable/cc_drawable_not_recording</drawable>
<drawable name="cc_recording">@drawable/cc_drawable_recording</drawable>
<!-- Photo capture button -->
<drawable name="cc_button_capture_photo_icon">@drawable/cc_icon_camera</drawable>
<drawable name="cc_button_capture_photo_background">@drawable/cc_button_capture_photo_background_circle</drawable>
<!-- Displayed when ready to start scanning -->
<drawable name="cc_guide_start_scanning_icon">@drawable/cc_icon_start_scanning</drawable>
<!-- Displayed if tracking is lost due to excessive motion -->
<drawable name="cc_tracking_excessive_motion_icon">@drawable/cc_icon_excessive_motion</drawable>
<!-- Displayed if tracking is lost due to insufficient visual features -->
<drawable name="cc_tracking_insufficient_features_icon">@drawable/cc_icon_insufficient_features</drawable>
<!-- Displayed if tracking is lost due to poor lighting conditions -->
<drawable name="cc_tracking_insufficient_lighting_icon">@drawable/cc_icon_insufficient_lighting</drawable>
<!-- Displayed if the user is walking sideways -->
<drawable name="cc_guide_sideways_left_icon">@drawable/cc_icon_turn_left</drawable>
<drawable name="cc_guide_sideways_right_icon">@drawable/cc_icon_turn_right</drawable>
<!-- Displayed icon for the rotate warning -->
<drawable name="cc_guide_rotate_device_icon">@drawable/cc_icon_rotate_device</drawable>
<!-- Displayed if the device is tilted forward too much -->
<drawable name="cc_guide_raise_device_icon">@drawable/cc_icon_raise_device</drawable>
<!-- Displayed if the device is tilted up too much -->
<drawable name="cc_guide_lower_device_icon">@drawable/cc_icon_lower_device</drawable>
<!-- Displayed if the user is rotating/turning too fast -->
<drawable name="cc_guide_fast_rotation_icon">@drawable/cc_icon_fast_rotation</drawable>
<!-- Displayed if the user is scanning too close to objects -->
<drawable name="cc_guide_too_close_icon">@drawable/cc_icon_too_close</drawable>
<!-- Displayed if camera permission is not granted -->
<drawable name="cc_permission_camera_icon">@drawable/cc_icon_camera</drawable>
<!-- Scan overlays -->
<drawable name="cc_overlay_default">@drawable/cc_overlay_default_drawable</drawable>
<drawable name="cc_overlay_start_scanning">@drawable/cc_overlay_start_scanning_drawable</drawable>
<drawable name="cc_overlay_warning_solid">@drawable/cc_overlay_warning_solid_drawable</drawable>
<drawable name="cc_overlay_warning_gradient">@drawable/cc_overlay_warning_gradient_drawable</drawable>
<!--
Scan guide warning corners:
- You can either change the entire main drawable (`cc_guide_warning_corners`),
or modify the individual corner drawables, which are assembled to form
the complete, default drawable.
-->
<drawable name="cc_guide_warning_corners">@drawable/cc_warning_corners</drawable>
<drawable name="cc_guide_warning_corner_top_left">@drawable/cc_warning_corner_top_left</drawable>
<drawable name="cc_guide_warning_corner_top_right">@drawable/cc_warning_corner_top_right</drawable>
<!-- Warning and info guide backgrounds -->
<drawable name="cc_guide_warning_background">@drawable/cc_warning_background</drawable>
<drawable name="cc_guide_info_background">@drawable/cc_info_background</drawable>
<!-- Fullscreen warning guide background, which is just a color by default -->
<drawable name="cc_guide_fullscreen_warning_background">#B85E1B2B</drawable>
<!-- Permission request button background -->
<drawable name="cc_permission_request_button_background">@drawable/cc_request_permission_button_background</drawable>
<!-- Scan dialog background and button backgrounds -->
<drawable name="cc_dialog_background">@drawable/cc_scan_dialog_background</drawable>
<drawable name="cc_dialog_button_positive_background">@drawable/cc_dialog_positive_button_background</drawable>
<drawable name="cc_dialog_button_negative_background">@drawable/cc_dialog_negative_button_background</drawable>
<!-- Scan view background color, which is just a color by default -->
<drawable name="cc_scan_background">#0C2F46</drawable>
<!-- Processing screen background, which is just a color by default -->
<drawable name="cc_processing_background">#0C2F46</drawable>
<!-- Scan playback timeline thumb -->
<drawable name="cc_timeline_thumb">@drawable/cc_drawable_timeline_thumb</drawable>
<!-- Scan playback back arrow -->
<drawable name="cc_playback_back_arrow">@drawable/cc_icon_arrow_left</drawable>For example, if you want to change the default record button drawable graphics to your own
drawables, you can redefine the drawables in your application's drawables.xml file like this:
<!-- Record button -->
<drawable name="cc_not_recording">@drawable/not_recording_new</drawable>
<drawable name="cc_recording">@drawable/recording_new</drawable>CubiCapture supports automatic torch (flashlight) activation on devices that support the Depth API and torch. If the surrounding lighting is too dark during a scan, CubiCapture will automatically activate the torch to improve the scan's lighting conditions.
During a scan, CubiCapture displays warnings to the user if it detects any issues with the scanning style or tracking. These warnings are categorized into different priority levels. Higher-priority warnings will override and hide any lower-priority warnings, ensuring only the most critical warning is shown at a given time.
| Priority Level | Warnings |
|---|---|
| 1 | Not tracking* |
| 2 | Rotate device |
| 3 | Sideways walking, Fast rotation, Too close |
| 4 | Device is tilted forward/up too much |
| 5 | Low storage, Device is hot |
*The Not tracking warning is displayed when ARCore's TrackingState is not TRACKING,
meaning the position of the device cannot be determined.
In this case, CubiCapture will display a tracking warning (e.g., insufficient visual features
warning) to help reestablish device tracking as quickly as possible.
Received when the device is turned to the correct (portrait) orientation.
Received when the scan is started by pressing the record button.
Received when the user has ended the scan and the scan has enough data. The saving of the scan files begins after this.
Received when the user has ended the scan and the scan does not have enough data. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received when the scan files are successfully saved without any errors. If automatic zipping is enabled, zipping will start after this.
Received when CubiCapture is finished, and the scanning Activity should be finished.
This code is always received after a scan. To determine whether the scan was successful,
you need to handle the preceding codes (e.g., codes 4 and 7).
For example:
- On a successful scan, you'll first receive code 4 (indicating successful saving of scan data), followed by code 7 (indicating successful zipping of scan files, if 'autoZipping' is enabled).
- On an unsuccessful scan, code 4 will be skipped and an error code (e.g., code 3: "Finished recording - Not enough data") will be received instead.
Received when the scan files are successfully saved without any errors.
The description will contain a path to the scan directory.
To receive the scan directory as a File use the CubiEventListener's
onFile(code: Int, file: File) method where the code 1 receives the scan directory.
Received when the automatic zipping of the scan files is completed successfully.
The description will contain a path to the zip file.
To receive the zip file as a File use the CubiEventListener's
onFile(code: Int, file: File) method where code 2 receives the zip file.
Received when ARCore motion tracking is lost due to poor lighting conditions.
Received when ARCore motion tracking is lost due to excessive motion.
Received when ARCore motion tracking is lost due to insufficient visual features.
Received when ARCore is tracking again.
Received if the position of the device is "sliding" in an unnatural manner. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received if the device was in the wrong orientation for too long. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received when the scan is not successful. Any scan files are deleted (code 15), and CubiCapture will be finished after this (code 5).
Received when the record button is pressed, but recording cannot be started because the device is not in the correct orientation.
Received when the device is in the wrong orientation.
Received when a warning sound is played, and ARCore motion tracking is lost (codes 8, 9, and 10).
Only received if ARCore was tracking before the tracking was lost to avoid playing the error sound
multiple times in a row.
(The ARCore TrackingFailureReason might change (between codes 8, 9, and 10) during a short period of time).
Received when the CubiCapture's close button press is confirmed via dialog. You should call
Activity.finish().
Received when the pitch of the camera has been too low for a certain amount of time.
Received when the pitch of the camera has been too high for a certain amount of time.
Received when the pitch of the camera is optimal again.
Received when ARCore's TrackingState is PAUSED, meaning the position of the device cannot be
determined.
Received when the user is walking sideways to the left while the camera is pointing forward.
Received when the user is walking sideways to the right while the camera is pointing forward.
Received when the user is not walking sideways anymore.
Received if ARCore is unable to start tracking during the first five seconds. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received if the automatic zipping fails.
Received if there's an exception on the OpenGL thread.
Received if camera video preview surface fails to be initialized.
Received if the writing of the arkitData.json file fails.
The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received if the writing of the config.json file fails.
The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received if the frame processing fails.
Received if ARCore has been unable to return correct values for the device's position for a certain amount of time. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received if the device has Location Services turned off on start. Only received if true north
detection is enabled and ACCESS_FINE_LOCATION permission is granted.
68, "Not able to get true north because Location Services were still off once recording was started."
Received if the device had Location Services turned off once recording was started.
Only received if true north detection is enabled and ACCESS_FINE_LOCATION permission is granted.
69, "Sensor is reporting true north data with low or unreliable accuracy. Not saving these true north values."
Received if the sensor is reporting true north data with low or unreliable accuracy. These values cannot be trusted, so true north detection is not saving these values. Only received if true north detection is enabled and running.
Received if the thermal state changes to nominal.
Received if the thermal state changes to light.
Received if the thermal state changes to moderate.
Received if the thermal state changes to severe.
Received if the thermal state changes to critical.
Received if the thermal state changes to emergency.
Received if the thermal state changes to shutdown.
Received once on start when the fragment's activity has been created and in certain intervals during a scan
while recording. minutes: Int is an estimation in minutes of the maximum scan length the device can store.
Received if the device runs out of storage space while scanning. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received if the user is scanning too close to objects.
Received when the user turns around too fast while scanning.
Received when the user is not scanning too close to objects anymore.
Received when the user is not turning around too fast anymore.
Received if the writing of the scanLog.json file fails.
Received if the writing of the feedback.json file fails.
Received if there's no gyroscope sensor available. CubiCapture will not be able to detect fast movements.
Received if the depth data processing fails.
Received if the rotation vector sensor is not supported on device. True North data will be acquired using the accelerometer and magnetometer instead.
Received if the ARCore session is initializing normally.
Received if the ARCore session is initialized and ARCore's TrackingState is TRACKING.
This is only received when the recording has not been started.
While recording, status code 11 is received instead.
Received when trying to start recording while the ARCore session is still in the initialization process.
Received when any required variables have not been initialized at the start.
The list of uninitialized variables will be included in the description.
The required variables are: scanDirectoryName, allScansDirectory, and propertyType.
Received if an internal error occurred while creating the ARCore session. You will receive code 5 after this.
Received if the device is not compatible with ARCore. If encountered after completing the installation check, this usually indicates that ARCore has been side-loaded onto an incompatible device. You will receive code 5 after this.
Received if the thermal state is critical or higher on startup. You will receive code 5 after this.
Received if the writing of the photo_capturer.json file fails.
Received if the position of the device "jumps" in an unnatural manner. Note that this does NOT abort the scan.
Received when the CAMERA permission is not granted.
Received when the camera permission view's permission request button is pressed, launching the application settings.
Received when the camera permission view's permission request button is pressed, prompting the CAMERA permission through the Android OS permission dialog.
Received when the CAMERA permission is granted through the Android OS permission dialog. Note that this is not received if the permission is granted through the application settings.
Received when the CAMERA permission is denied through the Android OS permission dialog. Note that this is not received if the permission is denied through the application settings.
Received when an error occurs during the video encoding process.
Received when the video encoder fails to initialize properly. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Received when encoding times out due to a mismatch between the number of frames queued and the number of frames successfully encoded. The scan files will be deleted (code 15), and CubiCapture will be finished after this (code 5).
Note! If you've previously implemented version 2.10.1 you've probably done the next steps already:
- Replace the
CubiCaptureandScanPlayback<fragment>tags with the<androidx.fragment.app.FragmentContainerView>tags - Handle the new status code 107, "Device is too hot to start scanning." to show user an error message after the aborted scan
Note! If you've previously implemented version 2.9.0 you've probably done the next steps already:
- Update your
minSdkVersionto API level29or higher - Rename
getFile(code: Int, file: File)andgetStatus(code: Int, description: String)methods as asonFile(code: Int, file: File)andonStatus(code: Int, description: String), respectively - If you want to disable the low storage warnings, see the new
storageWarningsEnabledbelow General UI settings - Check if you want to handle the new status code 103, "Not initialized"
Note! If you've previously implemented version 2.8.0 you've probably done the next steps already:
- Check the new
safeModevariable, and if you want to implement a Safe mode setting to your app - Handle the new status code 79, "Device ran out of storage space" to show user an error message after the scan
Note! If you've previously implemented version 2.6.0 you've probably done the next steps already:
- If you want to implement the new scan playback
Fragmentto your application, see Scan playback and new resources for customization
Note! If you've previously implemented version 2.5.2 you've probably done the next steps already:
- Change your
CubiCapture.CubiEventListenerinterface implementation toCubiEventListener - Check if you want to handle the new status codes: 70-76, 90 and 94
- In previous library module documentation there was a typo where status code
88was written as86. If you handle code86, change it to88. This code is received when the user is not scanning too close to objects anymore and the too close warning is hidden.
Note! If you've previously implemented version 2.5.1 you've probably done the next steps already:
- See Archived Release Notes if you want to customize CubiCapture's text sizes, or the size of the processing progress bar
Note! If you've previously implemented version 2.5.0 you've probably done the next steps already:
- Customization of the CubiCapture has changed. See Archived Release Notes for information about deprecations and how the CubiCapture is customized now
- Check if you want to handle the new status codes: 85, 88 and 93
Note! If you've previously implemented version 2.4.0 you've probably done the next steps already:
- Remove deprecated
feedbackGatheringEnabled: Booleanif you used it - Check if you want to handle the new status codes (codes 87, 89, 92, 105 and 106)
Note! If you've previously implemented version 2.3.1 you've probably done the next steps already:
- Set
allScansDirectory: Filewhich replacedallScansFolderName: String(see Implementation) - If you want to get an estimation in minutes of the maximum scan length the device can store, see Archived Release Notes for more information
- Check if you want to handle the new status codes (codes 78, 91 and 100-102)
Note! If you've previously implemented version 2.3.0 you've probably done the next steps already:
- See how to enable/disable the true north detection (see Implementation)
- Check if you want to handle the new status codes 67-69
Note! If you've previously implemented version 2.2.2 you've probably done the next steps already:
- If you want to set the enabled status of the record button
Viewsee Archived Release Notes for more information
Note! If you've previously implemented version 2.2.1 you've probably done the next steps already:
- Check if you want to handle the new status codes 65 and 66
- See if you want to add information about your app's version to be written to the scan data
(see variables
appVersionandappBuildfrom Implementation)
Note! If you've previously implemented version 2.2.0 you've probably done the next steps already:
- Remove calls to CubiCapture lifecycle functions
resume(),pause(),stop()anddestroy()
2.10.1:
CubiCaptureandScanPlaybackFragmentsnow support the<androidx.fragment.app.FragmentContainerView>tag instead of the<fragment>tag- Scan is now aborted if the thermal state is critical or higher on startup
- New status code 107, "Device is too hot to start scanning."
- Scan data is no longer affected by enabled code shrinking
2.9.0:
- Setting the property type is now required. Added a new
CubiEventListenermethodgetPropertyType(): PropertyTypewhich must be used to set thePropertyType propertyType: PropertyTypevariable is now deprecatedgetFile(code: Int, file: File)andgetStatus(code: Int, description: String)methods renamed asonFile(code: Int, file: File)andonStatus(code: Int, description: String), respectively- Added new
storageWarningsEnabledvariable for enabling/disabling low storage warnings. See General UI settings for more information - Added new customization options for processing screen text color and progress bar color.
See
ccProcessingTextColorandccProgressBarColorunder Colors and alphas - New status code 103, "Not initialized"
- CubiCapture's
minSdkVersionandtargetSdkVersionhave been updated to API levels29and33, respectively - Updated dependencies (see Implementation)
2.8.0:
- Re-enabled Too close -warning for Depth API supported devices
- Added new
safeModevariable for enabling/disabling Depth API. See Safe mode for more information - Aborting scan when device runs out of storage space
- New status code 79, "Device ran out of storage space"
- Margins of the scan back button now match the margins of the scan timer
- Updated dependencies (see Implementation below)
2.7.0:
- Ceiling warning adjustments
- Updated dependencies (see Implementation)
2.6.3:
- Property type can now be added to the scan data with the new variable
propertyType: PropertyType - Patch to prevent majority of the native ARCore crashes. Too close -warning is disabled for the time being and will be enabled again once Google has fixed the issue
- Updated dependencies (see Implementation)
- Various bug fixes
2.6.1:
- Bug fix: Fixed record button not being vertically centered when speech recognition was disabled
2.6.0:
- New scan playback
Fragmentavailable, which can be used to review the scan and to see any warnings that were shown during the scan, as well as any room labels that were added. See Scan playback for more information - Reminder view for microphone and location permission for more information
- New customization resources for scan playback and reminder view
- Resource names
open_settings_text,cc_location_background,cc_location_reminder_text_sizeandlocation_services_reminder_textrenamed ascc_open_location_settings_text,cc_reminder_background,cc_reminder_text_sizeandcc_location_services_reminder_text - Default processing background
cc_processing_backgroundis now a color (previously a PNG format image) - CubiCapture's
targetSdkVersionhas been updated to API level 31 - New status codes: 95-98. Changes to the status codes 37 and 38
- Updated dependencies and added new dependencies for the scan playback (see Implementation)
- Various bug fixes and optimizations
2.5.2:
- Thermal state monitoring. Changes in thermal state can be listened by using status codes 70-76
- Scan log (extra information about the scanning session, included in the zip)
- Changes to the click area of the CubiCapture's back button to prevent accidental clicks
CubiCapture.CubiEventListenerinterface implementation is nowCubiEventListener- New status codes: 70-76, 90 and 94
- Improvements to scan data
2.5.1:
- New variable
matchHintLabelWidth: Booleanto set hint label widths to match the wider one or to wrap label text. This istrueby default. For more information, see UI Settings - New customization resources in
dimens.xmlfor CubiCapture text sizes, hint label width and processing progress bar size. See Dimensions - Various bug fixes
2.5.0:
- Too close warning. A warning which will trigger if the user is scanning too close to objects. This warning is currently only available on devices which support Depth API
- End scan confirmation slider. In order to end the scan, user now has to slide the record button from right to left to the end of the slider. This feature was added to prevent the scan from being accidentally ended
- Location Services reminder and a new variable
requestLocationServices: Boolean. Settings this totruewill show the Location Services reminder -view if Location Services are turned off. This isfalseby default (see Implementation). - Changes to the customization of the CubiCapture
- Most of the customization is now done in the following resource files:
colors.xml,dimens.xml,drawables.xmlandstrings.xml - Deprecated public scan warning
ImageViews, error and speech recognition textCharSequences and image resource idInts. All of these are now customizable via the resource files listed above - Scan warnings and guides are now combination of
drawableicons,stringresources anddrawablebackgrounds instead of beingImageViews. This allows better customization and the warnings can be localizable to any language - String resource names
recordHintString,speakHintStringandlowStorageStringrenamed ascc_record_hint_text,cc_speech_hint_textandcc_low_storage_textin the filestrings.xml - Default string values reviewed
- For more information about the customization changes, see UI Settings
- Most of the customization is now done in the following resource files:
- New status codes: 37, 38, 85, 88 and 93. Changes to the
description: Stringof the code 24 - CubiCapture's
targetSdkVersionhas been updated to API level 30. Specifying atargetSdkVersionin your project'sbuild.gradleorAndroidManifest.xmlwill override the CubiCapture's value - CubiCapture no longer use the
WRITE_EXTERNAL_STORAGEpermission or request therequestLegacyExternalStorageattribute - Default scan warning background is now more translucent
- Various bug fixes
- Updated dependencies and new dependency
com.facebook.shimmer:shimmer:0.5.0for the end scan confirmation slider (see Implementation)
2.4.0:
- Fast rotation warning. A warning which will trigger if the user turns around too fast while
scanning. This is a customizable
ViewfastMovementWarning: ImageView - Deprecated
feedbackGatheringEnabled: Booleanoption - New status codes (codes 39, 87, 89, 92, 105 and 106)
- UI improvements
- Various bug fixes
- Updated ARCore version to 1.25.0
2.3.1:
- Replaced
allScansFolderName: StringwithallScansFolder: File?(see Implementation) - AR Session initializing indication text. This text can be customized by changing the value of
initializingErrorText: CharSequence - Low storage warning. Low storage warning text can be changed by redefining the string in your applications
strings.xmlfile (see UI Settings) - New function
getAvailableStorageMinutes(File)which returns an estimation in minutes of the maximum scan length the device can store (see Implementation) - New variable
feedbackGatheringEnabled: Booleanto toggle the feedback data gathering, this istrueby default - Various bug fixes and optimizations
- New status codes (codes 78, 91 and 100-102)
- Changes to the description message of the error code 45. It now contains the error code of the SpeechRecognizer
- Updated ARCore version to 1.24.0
2.3.0:
- Horizontal scanning warning. This is a customizable
ViewhorizontalWarning: ImageView - True north detection (see Implementation)
- New status codes (codes 31-36 and 67-69)
- Dropped values from the
arkitData.json(scan data file). Saving of the scan files is now faster - Changes to the device orientation detection (landscape, portrait etc)
- Memory optimization
- Fixes to scaling of depth camera intrinsics
2.2.2:
- Hint label texts can be changed by redefining the strings in your applications
strings.xmlfile (see UI Settings) - New variables
speechNoResultsTextandreadyForSpeechTextto change speech recognition's pop-up texts (type:CharSequence, default values:"No results"and"Say the room name") - New function
recordButtonEnabled(Boolean)to set the enabled status of the record buttonView - Updated ARCore version to 1.23.0
2.2.1:
- Possibility to add information about your app's version with new variables
appVersionandappBuild. These will be written to the scan data - New status codes (codes 65 and 66)
- Various bug fixes
2.2.0:
- Depth capturing support for the following devices;
Galaxy S20 Ultra 5G,Galaxy S20+ 5GandGalaxy S10 5G - Speech recognition for room labels
- Optimized frame-rate handling (more stable capturing frame-rate)
- New status codes (codes 40-49 and 59-64)
- Updated dependencies
- CubiCapture lifecycle functions
resume(),pause(),stop()anddestroy()have been removed, those are now handled by CubiCapture. Note thatonWindowFocusChanged()function is still required - Views
buttonRecordandbuttonRecordHintare now private and part of the speech recognition UI. Customizing these Views now works differently, for example, thesetNewView()function for those Views will no longer work - Speech recognition UI can be modified by using the
colors.xmlanddimens.xmlfiles. See UI Settings to see how to customize the graphics, size of the views and layout margins - New image resource variables
hintLabelBackgroundandnotRecordingImage - Record button hint label
buttonRecordHintis now TextView - Default record button drawables have a new look and are now vector drawables for higher quality (previously a PNG format image)
- Default status border drawables
trackingStatusBordersandfailureStatusBordersnow as vector drawables for higher quality (previously a PNG format image) - Fixed
sidewaysWarningstatus codes (codes 25 and 26) not being sent when image resource changes betweenturnLeftImageandturnRightImagewhensidewaysWarningis already set to visible - Fixed video encoder crashes