Some notes after further testing:
- Use 0 as the minimum zoom level, not 5 as I stated above. The top-most zoom levels cost next to no storage space and generate really quickly. Using 0 also means that the imagery is always visible when zooming and panning at extreme values.
- Use 19 as max zoom level. The default zoom of ODK Collect's map seems to be 19 (cf. https://github.com/getodk/collect/blob/master/collect_app/src/main/java/org/odk/collect/android/geo/MapProvider.java#L91), so if your offline map renders nicely at that level, the storage and processing cost of adding level 20 is up to you.
- The QGIS plugin "Zoom Level" is useful to calculate the zoom level at a given scale. The relationship between those depends on latitude.
- The MBTiles do not exactly follow the render cut-off scale. E.g., even if I configure the maximum zoom ESRI World Imagery's scale dependent visibility to go to a maximum of 1:1100 (this varies between 1000 and 1200 across Western Australia, YMMV), it should cut out before I see the grey placeholders saying "Map data not yet available" hiding the OpenStreetMap vectors. However, I can see the grey placeholder tiles for the entire zoom level 19 (roughly a scale of 1:1100 down to 1:500 at my latitudes of -20 degrees).
- To get a nice cut-over of raster aerial imagery to vector basemaps you might need to find a scale dependent visibility maximum for the raster that's just at zoom level X.001 or Y.999 or so. Let us know here if there's a formula.
- Getting the offline maps just right requires a lot of testing and verifying. Make sure you send your folks out with sufficient imagery in extent and zoom level.