Collect will need to stop using /sdcard/odk for files

Google recently introduced stricter target API level requirements for applications published to the Play Store. ODK Collect currently targets Android 9 but as soon as Android 11 is released, it will need to target Android 10. This will likely be in fall 2020.

This has two major implications: Collect will no longer be able to use files in /sdcard/odk/ and it will no longer be able to read device-unique identifiers such as the International Mobile Equipment Identity which is used as deviceId (sent with every form submission and form list request). Because these may have impact across the ecosystem, I'll start a thread for each change describing a proposed approach and soliciting feedback. See Collect will need to stop using IMEI as deviceID and making simSerial and subscriberID available for the thread on deviceId.

The /sdcard/odk/ folder that has always been used by Collect to store blank forms, submissions and corresponding databases in a public folder on the device that any application can access. For security purposes, Android will no longer allow folders shared between applications. Collect will instead need to use a folder that only it can see and write to ("scoped storage").

As far as I know, these are the implications:

  • When ODK Collect is uninstalled or downgraded, all files including unsent submissions will be deleted
  • If users want to manually push files from a computer to their device, they will need to use a path like /sdcard/Android/data/org.odk.collect.android
  • It will no longer be possible for other applications to directly read or modify ODK Collect files (e.g. generate or modify submissions, read form definitions)
  • It will be impossible to use ODK Collect versions prior to the ones with this storage change on Android 11+ devices

@Grzesiek2010, @seadowg and I have spent quite a bit of time exploring our options and would like to propose the following course of action:

  • Let users know that these changes are coming with a community announcement
  • In the upcoming v1.26 release, have new installs use the dedicated Collect directory. This means that these users will not need to undergo any kind of data migration.
  • Either in v1.26 or in the following release, put a notice on the Collect landing screen that files need to be moved and let the enumerator make the change by tapping a button when it is appropriate for them (e.g. when all pending submissions have been sent). We are proposing to let users explicitly trigger the data migration because it could take a while depending on storage speed, whether sent submissions were deleted and whether media files were captured. Having it be user-triggered will also make it easier to recover from any errors that may happen during the migration.
  • In the summer release (before August 2020 and the requirement to target Android 11), on devices where the files haven't already been moved, force the move on first load of this version. After the change to scoped storage is made, it will be impossible for Collect to migrate files out of /sdcard/odk so users who upgrade after will not have blank or filled forms available. They should be able to manually move the files using adb, however.

Please provide any feedback you may have on this approach. Are there implications we may not have considered? Do you have alternate suggestions on how we make this change as seamless as possible for users?

OpenMapKit is one application that I know reads contents from /sdcard/odk and will need to change (@danbjoseph). The Skunkworks Crow project for sharing form definitions and filled forms between devices will need to make a similar modification for itself. I'm not sure what the best approach will be for reading and writing form definition and submission XML but I think it should be possible using FileProvider functionality. @Shobhit_Agarwal, @dexter21, @Mickys0918 is this something you've explored? I think it will require changes to Collect. Do we know of other Android applications that do things explicitly with the /sdcard/odk directory? @Jason_Rogena (Ona)?

CC @tomsmyth (NEMO), @Ukang_a_Dickson (Ona), @jnm (Kobo)

Thanks for flagging this @LN. I'll use this as a reason to loop back around with various people who do OSM data collection (especially Humanitarian OpenStreetMap Team folks) and restart conversations around the future of OSM mobile data collection. Maybe we can find/pool resources to continue @zestyping's great work (with the geo widgets and more recently the 'viewing filled forms on a map' functionality) instead of further investment in the OMK Android app.

1 Like

it will be /storage/emulated/0/Android/data/org.odk.collect.android/files

You are correct that this is likely to be the actual path. /sdcard/ is a symbolic link to /storage/self/primary which itself links to the current user's primary storage (e.g. /mnt/user/0/primary) which is itself a link into emulated storage. There's more info in this Android StackExchange post. I believe we'll want to document the /sdcard prefix because we can't know the exact actual path. For example, if there are multiple users and a non-default one is logged in, the actual path prefix would be something like /storage/emulated/1/.

I don't think we should force new installs to use the dedicated directory. We don't know for certain if new users are less likely to use apps that read the odk folder. Given that the migration is not yet necessary, we shouldn't force it. I'd rather new users see the opt-in screen, get all the necessary context, and decide then.

Everything else about the proposed course of action is, as always, thoughtfully done. In particular, I think the early opt-in is nice because it provides lots of warning about the upcoming change very early. I don't necessary think that enumerators are best positioned to decide if they should do this migration, but we can start by defaulting to not migrating, explaining the timeline, adding language in the dialog for them to speak with supervisors, etc.

Thanks for your leadership on this, @LN.

I think we should use a banner for this:


If we want to inform users about upcoming changes first we can have just LEARN MORE option and then add FIX IT in the future (but personally I'm not sure whether we should separate it or not).
I think a banner is better because dialogs might be ignored by users, @ln you have mentioned a button in our conversation but it would be ugly as you noticed.

As the doc says banners are for: prominent message and related optional actions so I think it's what we need.

1 Like

A banner on the Main Menu seems a like good call to me :+1:

Ah right yeah that makes sense. I guess it's always going to have to be optional.

Hi @LN , does it mean that the sdcard will not be used anymore ? Or does it "only" mean that the path will change on the sdcard ?
I have in mind the necessity to put big mbtiles on the sdcard when internal space is too small...

The /sdcard/ path is a bit misleading. It will use the sdcard if one exists and shared internal storage if not. That aspect of the behavior will not change. So yes, from an external perspective, it's "only" changing the path on the sdcard.

Are you currently using physical sdcards? Have you had any issues with users taking them out?

1 Like

In fact not now because it is not allowed on our phones/android version but it was a possibility on older and smaller phones.

1 Like