Improving Android autocapture
The Android View Autocapture SDK is Heap's solution for automatically capturing user interactions in Android apps built with the native Android View framework. This autocapture experience is accomplished using the Heap Gradle Plugin to instrument your app's code with direct calls into Heap's SDK. Those calls collect information about the interaction, create an event, and send it to Heap without any additional code necessary.
When instrumenting your code, Heap attempts to piggyback on specific listeners and callback methods that provide the basis for an interaction. In other cases, Heap 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 simple 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 simple 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, Heap 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 Heap to piggyback on the interaction.
If you want to capture interactions for a view, and aren't seeing them automatically captured by Heap, 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 Heap 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.OnClickListenermust be set to the target view. | 
| In-Text Link Click | TextViewand its subclasses. | In-text link must be generated using a ClickableSpanthat overrides theonClickmethod. | 
| Dialog Button Click | All dialog types that implement DialogInterface(e.g.AlertDialog). | DialogInterface.OnClickListenermust be set to the target dialog button. | 
| Dialog List Item Click | Platform native and AndroidX implementations of AlertDialog. | Must attach a DialogInterface.OnClickListenerto the target dialog's list usingAlertDialog.Builder.setItems(). | 
| List Item Click | All subclasses of AdapterView. | AdapterView.OnItemClickListenermust be set to the target list. | 
| Spinner Item Selected | All subclasses of AdapterView, but works best withSpinnerand its subclasses. | AdapterView.OnItemSelectedListenermust be set to the target view. | 
| Toggle Control Value Changed | All subclasses of CompoundButton(e.g.ToggleButton,CheckBox,Switch) exceptRadioButton. | CompoundButton.OnCheckedChangeListenermust be set to the target view. | 
| Radio Group Value Changed | RadioGroupand its subclasses. | RadioGroup.OnCheckedChangeListenermust be set to the target view. | 
| Text Input Value Changed | EditTextand its subclasses. | TextWatchermust be set to the input field usingTextView.addTextChangedListener(). | 
| Date Value Changed | DatePickerDialog | DatePickerDialog.OnDateSetListenermust be set to the target dialog. | 
| Time Value Changed | TimePickerDialog | TimePickerDialog.OnTimeSetListenermust be set to the target dialog. | 
| SeekBar Value Changed | SeekBar | SeekBar.OnSeekBarChangeListenermust e set to the target view. | 
| Slider Value Changed | Material component library implementations of SliderandRangeSlider. | No required listeners needed for value change capture. Heap will attach its own listener. | 
It's important to note that Heap 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, Heap will capture that interaction. However, if you change the checked value of a CheckBox using the setChecked method in code, Heap 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.
Updated over 2 years ago