Improve Android autocapture
Autocapture is the CSQ SDK solution for automatically capturing user interactions in Android apps built with the native Android View framework.
For Autocapture to work, make sure you’ve:
-
Added the Android View Autocapture Plugin to instrument your app code with direct calls into the CSQ SDK:
build.gradle.kts plugins {// ...id("io.heap.gradle") version "1.1.0"}build.gradle plugins {// ...id 'io.heap.gradle' version '1.1.0'} -
Enabled
enableViewAutocapture
in the SDK Product Analytics configuration:CSQ.configureProductAnalytics(context = this,envId = "YOUR_ENVIRONMENT_ID",options = ProductAnalyticsOptions(enableViewAutocapture = true))CSQ.configureProductAnalytics(this,"YOUR_ENVIRONMENT_ID",new ProductAnalyticsOptions.Builder().enableViewAutocapture(true).build());
Autocapture calls collect information about the interaction, create an event, and send it to Product Analytics without any additional code necessary.
When instrumenting your code, the CSQ SDK attempts to piggyback on specific listeners and callback methods that provide the basis for an interaction. In other cases, the CSQ SDK attempts to attach its own listeners to views to listen for interactions. This means that, in some cases, if a listener isn’t attached to a view, then the interaction cannot be captured automatically.
For example, consider this form layout (layout properties omitted for brevity):
<LinearLayout> <EditText android:id="@+id/edit_first_name" /> <EditText android:id="@+id/edit_last_name" /> <CheckBox android:id="@+id/checkbox_accept_terms" /> <Button android:id="@+id/button_submit" /></LinearLayout>
In code, we might hook up this layout like so:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
// Attach a listener to the button. findViewById<Button>(R.id.button_submit).setOnClickListener { // Handle submit and perform form validation. } }}
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
// Attach a listener to the button. findViewById(R.id.button_submit).setOnClickListener(view -> { // Handle submit and perform form validation. }); }}
In the above example, the CSQ SDK is able to autocapture all clicks on the submit button by instrumenting the OnClickListener
attached to the button. However, any changes made in the edit fields aren’t captured and changes to the check box state are also not captured. The reason being, those views don’t have a listener attached to them, so there’s nowhere for the CSQ SDK to piggyback on the interaction.
If you want to capture interactions for a view, and aren’t seeing them automatically captured by Product Analytics, in most cases you can just add a listener.
Below is a table of the types of interactions that we capture, the view types that support those interactions, and any listeners that must be set to the view in order for the CSQ SDK to capture an interaction. You can use this table of views and listeners to enhance your data capture experience.
Interaction | Supported Types | Required Listener |
---|---|---|
View Click | All subclasses of View . | View.OnClickListener must be set to the target view. |
In-Text Link Click | TextView and its subclasses. | In-text link must be generated using a ClickableSpan that overrides the onClick method. |
Dialog Button Click | All dialog types that implement DialogInterface (e.g. AlertDialog ). | DialogInterface.OnClickListener must be set to the target dialog button. |
Dialog List Item Click | Platform native and AndroidX implementations of AlertDialog . | Must attach a DialogInterface.OnClickListener to the target dialog’s list using AlertDialog.Builder.setItems() . |
List Item Click | All subclasses of AdapterView . | AdapterView.OnItemClickListener must be set to the target list. |
Spinner Item Selected | All subclasses of AdapterView , but works best with Spinner and its subclasses. | AdapterView.OnItemSelectedListener must be set to the target view. |
Toggle Control Value Changed | All subclasses of CompoundButton (e.g. ToggleButton , CheckBox , Switch ) except RadioButton . | CompoundButton.OnCheckedChangeListener must be set to the target view. |
Radio Group Value Changed | RadioGroup and its subclasses. | RadioGroup.OnCheckedChangeListener must be set to the target view. |
Text Input Value Changed | EditText and its subclasses. | TextWatcher must be set to the input field using TextView.addTextChangedListener() . |
Date Value Changed | DatePickerDialog | DatePickerDialog.OnDateSetListener must be set to the target dialog. |
Time Value Changed | TimePickerDialog | TimePickerDialog.OnTimeSetListener must be set to the target dialog. |
SeekBar Value Changed | SeekBar | SeekBar.OnSeekBarChangeListener must be set to the target view. |
Slider Value Changed | Material component library implementations of Slider and RangeSlider . | No required listeners needed for value change capture. Heap will attach its own listener. |
It’s important to note that Product Analytics will make a best effort attempt to differentiate between user driven interactions and programmatic interactions. For instance, if the user clicks on a CheckBox
to change its value and there’s a listener attached, the CSQ SDK will capture that interaction. However, if you change the checked value of a CheckBox
using the setChecked
method in code, the CSQ SDK will attempt to ignore that interaction as it isn’t indicative of user behavior, even though it might be the side effect of another user interaction. This is true of all interaction events that are designated as a “Changed” event in the above table.