Generate a signed Android app that syncs your internal contact files into the device contacts, configured by your EMM or baked in.
‹The Bayton Contacts App Generator produces a signed Android app that syncs your internal contact files into the device contact list. Point it at one or more sources - a built-in file baked into the app, or a URL fetched from your intranet - and it generates a ready-to-deploy app for your EMM. Each build produces a unique package name, along with an optional source zip so you can audit or reproduce the build independently.
Most options are also exposed as Android managed configuration. An EMM admin can override the sources, sync policy, and appearance at runtime, without rebuilding the app - the configuration baked in at build time is the default. Packaging choices (signing, output format, the embedded source files, and whether plain HTTP is permitted) are fixed at build time and need a rebuild to change.
Generated apps target API 37 (Android 17) and require API 28 (Android 9 Pie) or above to install. Devices running Android 8.1 or older are not supported.
Add at least one source. A built-in source bakes a contacts file into the app, so it works offline with no hosting. A URL source is fetched from your intranet on each sync. Supported formats are VCF (vCard), CSV, and JSON. Any source can be overridden later by your EMM through managed configuration.
For CSV sources, an optional column mapping lets you point the importer at non-standard column names. Supply a small JSON object whose keys are the importer's field names and whose values are your column headers - for example {"given_name":"First Name","family_name":"Surname","email_work":"Work Email"}. Use the canonical field names (display_name, given_name, family_name, organization, job_title, phone_work, phone_mobile, email_work, address_work, notes, id); common header spellings are already auto-detected, so a mapping is only needed for non-obvious columns.
Starter files. Download a sample CSV or JSON to see the expected layout, then edit and upload your own. The only required column is display_name; everything else is optional. The JSON sample also shows the richer optional forms - arrays of phones, emails, and structured addresses, plus x_ custom fields. VCF needs no template: it is the standard vCard format, so export one straight from your existing contacts app (Google Contacts, Outlook, iOS) rather than building it by hand.
The sync interval sets how often the app refreshes contacts from its sources (minimum 15 minutes, per Android background-work limits). You can additionally trigger a sync when the managed config changes, when the network becomes available, and restrict syncing to Wi-Fi only.
By default, contacts that disappear from a source are removed from the device on the next sync, keeping the device list in step with the source. Turn this off to keep contacts on the device even after they vanish from the source.
Allow plain HTTP is off by default; URL sources are fetched over HTTPS only. Note this is baked at build time: a build made with HTTP disabled blocks cleartext at the OS level, so turning network_allow_http on later via managed config will not enable an http:// source - that requires a rebuild with HTTP allowed.
.jks, .keystore, .p12, or .pfx keystore with the key alias and the store and key passwords. Always use a unique keystore for builds produced by this generator - never share it with another production app. Credentials are never stored and are purged immediately after the build completes.Every new build generates a unique update code returned once in the submission response. Store it securely - it is never shown again. Only a SHA-256 hash is kept server-side, so the raw code cannot be recovered or regenerated.
When you need to update an existing app and must keep the same Android package name (required for EMM silent-update flows and Managed Google Play uploads beyond the first), enter the original update code in the Update code field before submitting. The service will reuse the registered package name for the new build.
Every successful build offers a config.json download - a portable JSON file capturing every form field plus the build's update_code. Use it to skip refilling the form on later rebuilds.
To re-import, click Import config at the top of the form and pick a previously-downloaded JSON. Every field populates, including the source list and the update code. Built-in source files and the app icon are not in the JSON (binary), so they must be re-attached manually after import.
The generated app has a built-in Status screen (overall health, last successful and last attempted sync, and a per-source result line) and a Troubleshooting screen (permissions and connectivity checks). Start there when contacts are missing or stale.
For a deeper trace, enable Verbose logging (Behaviour, or the logging_verbose managed-config key) and capture logcat: adb logcat -s ManagedContactsSync. It logs each sync's trigger, every source's result (including HTTP 304 "unchanged"), the reconcile plan (created / updated / deleted counts), and the outcome - enough to see whether a source is failing to fetch, returning no contacts, or being skipped.
Common causes: a URL source unreachable from the device's network/VPN; the contacts permission not granted (so writes are blocked); an HTTPS-only build pointed at an http:// source (see Contacts policy); or a source whose contacts all share an id. Disabled and built-in sources never make a network request.
Download links expire 5 minutes after first click and build files are purged at that point. All builds are purged after 24 hours regardless of download activity. The source download includes post-substitution Kotlin, XML, and Gradle files so you can audit exactly what was compiled.
A label for this source. Shown as the group header in the app.
Built-in bakes a file into the app (offline, no hosting). URL is fetched from your intranet on each sync.
The contact file format: vCard (VCF), CSV, or JSON. Not sure of the layout? Download a sample CSV or JSON, edit it, and upload. VCF needs no template - it is the standard vCard format, so export one from your existing contacts app (Google Contacts, Outlook, iOS).
Optional. Keys are the importer's canonical fields (display_name, given_name, family_name, email_work, …); values are your column headers. Common spellings are auto-detected, so a mapping is only needed for non-obvious columns.
Optional. Overrides the global accent for this source's avatars and chip. Leave off to inherit.
On by default. Turn off to keep this source in the configuration but skip it on every sync - a way to pause a source (e.g. a URL that's down, or one staged but not ready) without losing its settings. Your EMM can also toggle it at runtime.