| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 1 | page.title=Android for Work Developer Guide |
| 2 | page.tags="work", "android for work", "afw", "developer", "android" |
| 3 | page.metaDescription=Android for Work provides organizations with a secure, flexible, and unified Android mobility platform combining devices, applications, and management. |
| 4 | page.image=images/work/cards/android-studio_600px.png |
| 5 | |
| 6 | @jd:body |
| 7 | |
| 8 | <div id="qv-wrapper"> |
| 9 | <div id="qv"> |
| 10 | <h2>In this document</h2> |
| 11 | <ul> |
| 12 | <li><a href="#managed-profiles">Managed Profiles</a></li> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 13 | <li><a href="#managed-configurations">Implementing Managed Configurations</a></li> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 14 | <li><a href="#cosu">COSU Devices</a></li> |
| 15 | <li><a href="#sso">Set up Single Sign-on with Chrome Custom Tabs</a></li> |
| 16 | <li><a href="#testing">Test Your App</a></li> |
| 17 | </ul> |
| 18 | </div> |
| 19 | </div> |
| 20 | |
| 21 | <p> |
| 22 | Android for Work provides organizations with a secure, flexible, and |
| 23 | unified Android mobility platform—combining devices, applications, |
| 24 | and management. By default, Android apps are compatible with Android |
| 25 | for Work. However, there are additional features you can use to make |
| 26 | your Android app work best on a managed device: |
| 27 | </p> |
| 28 | |
| 29 | <ul> |
| 30 | <li> |
| 31 | <a href="#managed-profiles">Managed profile compatibility</a>—Modify your Android |
| 32 | app so it functions best on an Android device with a work profile. |
| 33 | </li> |
| 34 | <li> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 35 | <a href="#managed-configurations">Managed configurations</a>—Modify |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 36 | your app to allow IT administrators the option to specify custom |
| 37 | settings for your apps. |
| 38 | </li> |
| 39 | <li> |
| 40 | <a href="#cosu">Corporate-owned, single-use (COSU)</a>—Optimize your |
| 41 | app so that it can be deployed on an Android device as a kiosk. |
| 42 | </li> |
| 43 | <li> |
| 44 | <a href="#sso">Single Sign-On (SSO)</a>—Simplify the sign-on process |
| 45 | for users signing in to different apps on their Android device |
| 46 | running Android for Work. |
| 47 | </li> |
| 48 | </ul> |
| 49 | |
| 50 | <h3>Prerequisites</h3> |
| 51 | |
| 52 | <ol> |
| 53 | <li>You’ve created an Android app.</li> |
| 54 | <li>You’re ready to modify your app so that it works best with |
| 55 | Android for Work.</li> |
| 56 | <li>Minimum version: Android 5.0 Lollipop recommended version: |
| 57 | Android 6.0 Marshmallow and later.</li> |
| 58 | </ol> |
| 59 | |
| 60 | <p> |
| 61 | <strong>Note:</strong> Android for Work functions natively on most |
| 62 | Android 5.0 devices; however, Android 6.0 and later offers |
| 63 | additional features for Android for Work, especially with regard to |
| 64 | COSU. |
| 65 | </p> |
| 66 | |
| 67 | <h2 id="managed-profiles">Manage Profiles</h2> |
| 68 | |
| 69 | <p> |
| 70 | You can manage a user’s business data and applications through a |
| 71 | work profile. A work profile is a managed corporate profile |
| 72 | associated with the primary user account on an Android device. A |
| 73 | work profile securely isolates work apps and data from personal apps |
| 74 | and data. This work profile is in a separate container from the |
| 75 | personal profile, which your user controls. These separate profiles |
| 76 | allow organizations to manage the business data they care about, but |
| 77 | leave everything else on a user’s device under the user’s control. |
| 78 | For a deep dive into best practices, see the |
| 79 | <a href="{@docRoot}work/managed-profiles.html">Set up Managed Profiles</a> |
| 80 | guide. For an overview of those best practices, see below. |
| 81 | </p> |
| 82 | |
| 83 | <h3>Key features of a managed profile</h3> |
| 84 | |
| 85 | <ul> |
| 86 | <li>Separate and secure profile</li> |
| 87 | <li>Google Play for Work for application distribution</li> |
| 88 | <li>Separate badged work applications</li> |
| 89 | <li>Profile-only management capabilities controlled by an administrator</li> |
| 90 | </ul> |
| 91 | |
| 92 | <h3>Managed profile benefits on Android 5.0+</h3> |
| 93 | |
| 94 | <ul> |
| 95 | <li>Full device encryption</li> |
| 96 | <li>One Android application package (APK) for both profiles when |
| 97 | there’s a personal profile and a work profile present on the device</li> |
| 98 | <li><a href="https://support.google.com/work/android/answer/6192678" |
| 99 | >Device policy controller</a> (DPC) is limited to the managed profile</li> |
| 100 | <li>Device administration via the |
| 101 | <a href="{@docRoot}reference/android/app/admin/DevicePolicyManager.html" |
| 102 | >DevicePolicyManager</a> class</li> |
| 103 | </ul> |
| 104 | |
| 105 | <h3>Considerations for managed profiles</h3> |
| 106 | <ul> |
| 107 | <li>The Android system prevents intents |
| 108 | <a href="{@docRoot}reference/android/app/admin/DevicePolicyManager.html#clearCrossProfileIntentFilters(android.content.ComponentName)" |
| 109 | >from crossing profiles</a> and IT administrators can |
| 110 | <a href="{@docRoot}reference/android/app/admin/DevicePolicyManager.html#enableSystemApp(android.content.ComponentName,%20java.lang.String)" |
| 111 | >enable or disable system apps</a>.</li> |
| 112 | <li>A file path (Uniform Resource Identifier [URI]) that’s valid on |
| 113 | one profile may not be valid on the other.</li> |
| 114 | </ul> |
| 115 | |
| 116 | <h3>Prevent intents from failing between profiles</h3> |
| 117 | <p> |
| 118 | It’s difficult to know which intents can cross between profiles, and |
| 119 | which ones are blocked. The only way to know for sure is by testing. |
| 120 | Before your app starts an activity, you should verify that the |
| 121 | request is resolved by calling |
| 122 | <a href="{@docRoot}reference/android/content/Intent.html#resolveActivity(android.content.pm.PackageManager)" |
| 123 | ><code>Intent.resolveActivity()</code></a>. |
| 124 | <ul> |
| 125 | <li>If it returns <code>null</code>, the request doesn’t resolve.</li> |
| 126 | <li>If it returns something, it shows that the intent resolves, |
| 127 | and it’s safe to send the intent.</li> |
| 128 | </ul> |
| 129 | </p> |
| 130 | <p> |
| 131 | <strong>Note</strong>: For detailed testing instructions, see |
| 132 | <a href="{@docRoot}work/managed-profiles.html#prevent_failed_intents" |
| 133 | >Prevent Failed Intents</a>. |
| 134 | </p> |
| 135 | |
| 136 | <h3>Share files across profiles</h3> |
| 137 | <p> |
| 138 | Some developers use URIs to mark file paths in Android. However, |
| 139 | with Android for Work, because there are separate profiles, we |
| 140 | recommend: |
| 141 | </p> |
| 142 | |
| 143 | <table> |
| 144 | <tr> |
| 145 | <td style="white-space:nowrap;"> |
| 146 | <strong>Use:</strong><br/> |
| 147 | Content URIs |
| 148 | </td> |
| 149 | <td> |
| 150 | <ul> |
| 151 | <li> |
| 152 | The <a href="{@docRoot}reference/android/content/ContentUris.html" |
| 153 | >content URIs</a> contain the authority, path, and ID for a |
| 154 | specific file. You can generate this using |
| 155 | <a href="{@docRoot}reference/android/support/v4/content/FileProvider.html" |
| 156 | >FileProvider</a> subclass. |
| 157 | <a href="{@docRoot}training/secure-file-sharing/index.html">Learn more</a> |
| 158 | </li> |
| 159 | <li> |
| 160 | Share and grant permissions to access the content URI using |
| 161 | an Intent. Permissions can only be passed across the profile |
| 162 | boundary using Intents. If you grant another app access rights |
| 163 | to your file using |
| 164 | <a href="{@docRoot}reference/android/content/Context.html#grantUriPermission(java.lang.String,%20android.net.Uri,%20int)" |
| 165 | ><code>Context.grantUriPermission()</code></a>, it only is granted for |
| 166 | that app in the same profile.</li> |
| 167 | </ul> |
| 168 | </td> |
| 169 | </tr> |
| 170 | <tr> |
| 171 | <td style="white-space:nowrap;"> |
| 172 | <strong>Don't use:</strong><br/> |
| 173 | File URI |
| 174 | </td> |
| 175 | <td> |
| 176 | <ul> |
| 177 | <li>Contains the absolute path of the file on the device’s |
| 178 | storage.</li> |
| 179 | <li>A file path URI that’s valid on one profile isn’t valid on |
| 180 | the other.</li> |
| 181 | <li>If you attach a file URI to an intent, a handler is unable |
| 182 | to access the file in another profile.</li> |
| 183 | </ul> |
| 184 | </td> |
| 185 | </tr> |
| 186 | </table> |
| 187 | |
| 188 | <p> |
| 189 | <strong>Next steps</strong>: Once your app supports managed |
| 190 | profiles, test it in a work profile. See |
| 191 | <a href="#testing">Test your app with Android for Work</a>. |
| 192 | </p> |
| 193 | |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 194 | <h2 id="managed-configurations">Implementing Managed Configurations</h2> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 195 | |
| 196 | <p> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 197 | Managed configurations are a set of instructions that IT administrators |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 198 | can use to manage their users’ mobile devices in a specific way. |
| 199 | These instructions are universal and work across any EMM, allowing |
| 200 | administrators to remotely configure applications on their users’ |
| 201 | phones. |
| 202 | </p> |
| 203 | |
| 204 | <p> |
| 205 | If you’re developing apps for business or government, you may need |
| 206 | to satisfy your industry’s specific set of requirements. Using |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 207 | managed configurations, the IT administrator can remotely specify |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 208 | settings and enforce policies for their users’ Android apps; for |
| 209 | example: |
| 210 | </p> |
| 211 | |
| 212 | <ul> |
| 213 | <li>Configure if an app can sync data via cellular/3G, or only Wi-Fi</li> |
| 214 | <li>Whitelist or blacklist URLs on a web browser</li> |
| 215 | <li>Configure an app's email settings</li> |
| 216 | <li>Enable or disable printing</li> |
| 217 | <li>Manage bookmarks</li> |
| 218 | </ul> |
| 219 | |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 220 | <h3>Best practices for implementing managed configurations</h3> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 221 | |
| 222 | <p> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 223 | The <a href="{@docRoot}work/managed-configurations.html">Set up Managed Configurations</a> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 224 | guide is the key source for information on how to build and deploy |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 225 | managed configurations. After you’ve reviewed this documentation, see |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 226 | recommendations below for additional guidance. |
| 227 | </p> |
| 228 | |
| 229 | <h4>When first launching the app</h4> |
| 230 | <p> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 231 | As soon as you launch an application, you can see if managed |
| 232 | configurations are already set for this app in <code>onStart()</code> or |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 233 | <code>onResume()</code>. Additionally, you can find out if your |
| 234 | application is managed or unmanaged. For example, if |
| 235 | <a href="{@docRoot}reference/android/content/RestrictionsManager.html#getApplicationRestrictions()" |
| 236 | ><code>getApplicationRestrictions()</code></a> returns: |
| 237 | <ul> |
| 238 | <li><strong>A set of application-specific restrictions</strong>—You |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 239 | can configure the managed configurations silently (without requiring |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 240 | user input).</li> |
| 241 | <li><strong>An empty bundle</strong>—Your application acts like |
| 242 | it’s unmanaged (for example, how the app behaves in a personal |
| 243 | profile).</li> |
| 244 | <li><strong>A bundle with a single key value pair with |
| 245 | <a href="{@docRoot}reference/android/os/UserManager.html#KEY_RESTRICTIONS_PENDING" |
| 246 | ><code>KEY_RESTRICTIONS_PENDING</code></a> set to true</strong>—your |
| 247 | application is being managed, but the DPC isn’t configured |
| 248 | correctly. You should block this user from your app, and direct |
| 249 | them to their IT administrator.</li> |
| 250 | </ul> |
| 251 | </p> |
| 252 | |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 253 | <h4>Listen for changes to managed configurations</h4> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 254 | <p> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 255 | IT administrators can change managed configurations and what |
| 256 | policies they want to enforce on their users at any time. Because of |
| 257 | this, we recommend you ensure that your app can accept new |
| 258 | restrictions for your managed configuration as follows: |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 259 | </p> |
| 260 | |
| 261 | <ul> |
| 262 | <li><strong>Fetch restrictions on launch</strong>—Your app should |
| 263 | call <code>getApplicationRestrictions()</code> in <code>onStart()</code> |
| 264 | and <code>onResume()</code>, and compare against old restrictions |
| 265 | to see if changes are required.</li> |
| 266 | <li><strong>Listen while running</strong>—Dynamically register |
| 267 | <a href="{@docRoot}reference/android/content/Intent.html#ACTION_APPLICATION_RESTRICTIONS_CHANGED" |
| 268 | ><code>ACTION_APPLICATION_RESTRICTIONS_CHANGED</code></a> in your |
| 269 | running activities or services, after you’ve checked for new |
| 270 | restrictions. This intent is sent only to listeners that are |
| 271 | dynamically registered, and not to listeners declared in the app |
| 272 | manifest.</li> |
| 273 | <li><strong>Unregister while not running</strong>—In <code>onPause()</code>, |
| 274 | you should unregister for the broadcast of |
| 275 | <code>ACTION_APPLICATION_RESTRICTIONS_CHANGED</code>.</li> |
| 276 | </ul> |
| 277 | |
| 278 | <h2 id="cosu">COSU Devices</h2> |
| 279 | |
| 280 | <p> |
| 281 | Corporate-owned, single-use devices (COSU) are kiosk devices used |
| 282 | for a single purpose, such as digital signage displays, ticket |
| 283 | printing kiosks, or checkout registers. |
| 284 | </p> |
| 285 | <p> |
| 286 | When an Android device is configured as a COSU device, the user sees |
| 287 | an application locked to the screen with no Home or Recent Apps |
| 288 | buttons to escape the app. COSU can also be configured to show a set |
| 289 | of applications, such as a library kiosk with an app for the library |
| 290 | catalog and a web browser. |
| 291 | </p> |
| 292 | <p> |
| 293 | For instructions, see |
| 294 | <a href="{@docRoot}work/cosu.html">Set up Single-Purpose Devices</a>. |
| 295 | </p> |
| 296 | |
| 297 | <h2 id="sso">Set up Single Sign-on with Chrome Custom Tabs</h2> |
| 298 | |
| 299 | <p> |
| 300 | Enterprise users often have multiple apps on their device, and they |
| 301 | prefer to sign in once to access all of their work applications. |
| 302 | Typically, users sign in through a |
| 303 | <a href="https://developer.chrome.com/multidevice/webview/overview">WebView</a>; |
| 304 | however, there are a couple reasons why this isn’t ideal: |
| 305 | </p> |
| 306 | <ol> |
| 307 | <li> |
| 308 | Users often need to sign in multiple times with the same |
| 309 | credentials. The WebView solution often isn’t a true Single |
| 310 | Sign-On (SSO) experience. |
| 311 | </li> |
| 312 | <li> |
| 313 | There can be security risks, including malicious applications |
| 314 | inspecting cookies or injecting JavaScript® to access a user’s |
| 315 | credentials. Even trusted developers are at risk if they rely on |
| 316 | potentially malicious third-party SDKs. |
| 317 | </li> |
| 318 | </ol> |
| 319 | |
| 320 | <p> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 321 | A solution to both problems is to authenticate users using browser |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 322 | Custom Tabs, instead of WebView. This ensures that authentication: |
| 323 | </p> |
| 324 | <ul> |
| 325 | <li> |
| 326 | Occurs in a secure context (the system browser) where the host app |
| 327 | cannot inspect contents. |
| 328 | </li> |
| 329 | <li> |
| 330 | Has a shared cookie state, ensuring the user has to sign in only |
| 331 | once. |
| 332 | </li> |
| 333 | </ul> |
| 334 | |
| 335 | <h3>Requirements</h3> |
| 336 | |
| 337 | <p> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 338 | <a href="https://developer.android.com/topic/libraries/support-library/features.html#custom-tabs" |
| 339 | >Custom Tabs</a> are supported back to API level 15 (Android 4.0.3). |
| 340 | To use Custom Tabs you need a supported browser, such as Chrome. |
| 341 | Chrome 45 and later implement this feature as |
| 342 | <a href="https://developer.chrome.com/multidevice/android/customtabs">Chrome Custom Tabs</a>. |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 343 | </p> |
| 344 | |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 345 | <h3>How do I implement SSO with Custom Tabs?</h3> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 346 | |
| 347 | <p> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 348 | Google has open sourced an OAuth client library that uses Custom |
| 349 | Tabs, contributing it to the OpenID Connect working group of the |
| 350 | OpenID Foundation. To set up Custom Tabs for SSO with the |
| 351 | AppAuth library, see the <a href="https://github.com/openid/AppAuth-Android" |
| 352 | >documentation and sample code on GitHub</a>, or try |
| 353 | <a href="https://codelabs.developers.google.com/codelabs/appauth-android-codelab/" |
| 354 | >the codelab</a>. |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 355 | </p> |
| 356 | |
| 357 | <h2 id="testing">Test your App with Android for Work</h2> |
| 358 | |
| 359 | <p> |
| 360 | Once you’ve developed your app, you’ll want to test it in a work |
| 361 | profile—both as a profile owner and device owner. See the |
| 362 | instructions below. |
| 363 | </p> |
| 364 | |
| 365 | <h3>Use TestDPC to test your Android app</h3> |
| 366 | |
| 367 | <p> |
| 368 | TestDPC is a tool you can use to test your Android app in a variety |
| 369 | of Android for Work environments. You can configure it as a profile |
| 370 | owner or a device owner to launch management APIs on your device, |
| 371 | using one of these methods: |
| 372 | </p> |
| 373 | <ul> |
| 374 | <li>Download the source code for TestDPC from |
| 375 | <a href="https://github.com/googlesamples/android-testdpc">GitHub</a>.</li> |
| 376 | <li>Install TestDPC directly from |
| 377 | <a href="https://play.google.com/store/apps/details?id=com.afwsamples.testdpc" |
| 378 | >Google Play</a>.</li> |
| 379 | </ul> |
| 380 | <p> |
| 381 | For more information on how to configure TestDPC, see the |
| 382 | instructions below and the |
| 383 | <a href="https://github.com/googlesamples/android-testdpc">TestDPC User Guide</a>. |
| 384 | </p> |
| 385 | |
| 386 | <p> |
| 387 | <strong>REQUIRED</strong>: Your test Android device needs to run |
| 388 | Android 5.0 or later and be able to natively support Android for Work. |
| 389 | </p> |
| 390 | |
| 391 | <h3>Provision a profile owner</h3> |
| 392 | |
| 393 | <p> |
| 394 | To test your app in a work profile, you need to first provision a |
| 395 | profile owner on the TestDPC app: |
| 396 | </p> |
| 397 | |
| 398 | <ol> |
| 399 | <li>Launch the TestDPC app and click <strong>Set up profile</strong>.</li> |
| 400 | <li>When prompted, click <strong>Set up</strong>, ensuring the |
| 401 | TestDPC’s logo is highlighted on the screen.</li> |
| 402 | <li>If your device isn’t encrypted, you need to encrypt your device. |
| 403 | Follow the briefcase notification after reboot to continue |
| 404 | provisioning.<br/> |
| 405 | Once you’ve provisioned the profile owner correctly, badged |
| 406 | applications appear at the end of your app tray. Install your app |
| 407 | on the device and test to see how it runs in the work profile. |
| 408 | </li> |
| 409 | <li> |
| 410 | Install your app on the device and test to see how it runs in the |
| 411 | work profile. |
| 412 | </li> |
| 413 | </ol> |
| 414 | |
| smain@google.com | 99e44c9 | 2016-08-26 16:25:24 -0700 | [diff] [blame] | 415 | <p class="caution"><b>Caution</b>: When running your app with Instant Run in |
| 416 | Android Studio, attempting to open your app with a Work profile or secondary |
| 417 | profile will crash your app. To use your app with the Work profile, we |
| 418 | recommend you create a new <a href="/studio/run/rundebugconfig.html">run |
| 419 | configuration</a> that includes the <code>--user <var>user_id</var></code> flag, |
| 420 | specifying the Work profile user ID. You can find the user ID by executing |
| 421 | <code>adb shell pm list users</code> from command line. For more information, |
| 422 | see the <a href="/studio/run/index.html#ir-work-profile">Instant Run |
| 423 | documentation</a>.</p> |
| 424 | |
| 425 | |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 426 | <h3>Provision a device owner</h3> |
| 427 | |
| 428 | <p> |
| 429 | Testing your app as a device owner requires more steps than testing |
| 430 | as a profile owner. You first need to provision the device owner on |
| 431 | your test device using the |
| 432 | <a href="{@docRoot}samples/NfcProvisioning/index.html" |
| 433 | >NfcProvisioning sample app</a>. For complete instructions to |
| 434 | provision TestDPC in device owner mode using the NfcProvisioning |
| 435 | app, see the <a href="https://github.com/googlesamples/android-testdpc" |
| 436 | >TestDPC User Guide</a>. |
| 437 | </p> |
| 438 | |
| 439 | <ol> |
| 440 | <li>Download the <a href="{@docRoot}samples/NfcProvisioning/index.html" |
| 441 | >NfcProvisioning</a> app sample files to your development environment.</li> |
| 442 | <li>Unpack the project, open your shell, and <code>cd</code> to the project directory.</li> |
| 443 | <li>Add a file to the directory with the <code>local.properties</code> name |
| 444 | and the following content: |
| 445 | <pre>sdk.dir=/path/to/your/android/sdk</pre> |
| 446 | </li> |
| 447 | <li>While in the project directory, enter these commands to build the NfcProvisioning APK: |
| 448 | <pre>./gradlew init |
| 449 | ./gradlew build</pre> |
| 450 | The NfcProvisioning APK you need is now located in <code>./Application/build/outputs/apk</code>. |
| 451 | </li> |
| 452 | <li>Install the APK on your programmer device, which you can use to provision other devices.</li> |
| 453 | <li>Create a text file called <code>nfcprovisioning.txt</code> and |
| 454 | include the following information: |
| 455 | <pre>android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME=com.afwsamples.testdpc |
| 456 | android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION=https://testdpc-latest-apk.appspot.com |
| 457 | android.app.extra.PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM=gJD2YwtOiWJHkSMkkIfLRlj-quNqG1fb6v100QmzM9w= |
| 458 | # note: checksum must be URL-safe |
| 459 | android.app.extra.PROVISIONING_LOCALE=en_US |
| 460 | android.app.extra.PROVISIONING_TIME_ZONE=America/New_York</pre> |
| 461 | <p> |
| 462 | <strong>Note:</strong> If you’re developing for Android 5.0 |
| 463 | Lollipop, see the instructions in the |
| 464 | <a href="https://github.com/googlesamples/android-testdpc" |
| 465 | >TestDPC User Guide</a>. |
| 466 | </p> |
| 467 | </li> |
| 468 | <li>Push that text file to your programmer device by entering: |
| 469 | <pre>adb push <path-to-nfcprovisioning.txt> /sdcard/</pre> |
| 470 | </li> |
| 471 | <li> |
| 472 | Ensure that the programmer device is connected to Wi-Fi on either |
| 473 | an unsecured or WPA2 secured network. |
| 474 | <p> |
| 475 | The NFC Provisioning app will automatically pass those Wi-Fi |
| 476 | credentials onto the target device. |
| 477 | </p> |
| 478 | </li> |
| 479 | <li>Open the NFC Provisioning app and ensure <code>com.google.android.testdpc</code> |
| 480 | is auto-populated.</li> |
| 481 | <li>Bump the devices to transfer the data.</li> |
| 482 | <li>Follow the onscreen instructions to set up your target device.</li> |
| 483 | <li>Once you’ve completed provisioning the device owner, you can test your app on that device. You |
| 484 | should specifically test how |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 485 | <a href="{@docRoot}work/managed-configurations.html">managed configurations</a>, |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 486 | <a href="{@docRoot}work/managed-profiles.html#sharing_files">URIs</a>, and |
| 487 | <a href="{@docRoot}work/managed-profiles.html#prevent_failed_intents">intents</a> |
| 488 | work on that device.</li> |
| 489 | </ol> |
| 490 | |
| 491 | <h3>End-to-end testing</h3> |
| 492 | |
| 493 | <p> |
| 494 | After you’ve finished testing your app in the environments above, |
| 495 | you’ll likely want to test your app in an end-to-end production |
| 496 | environment. This process includes the steps a customer needs to |
| 497 | take to deploy your app in their organization, including: |
| 498 | </p> |
| 499 | |
| 500 | <ul> |
| 501 | <li>App distribution through Play</li> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 502 | <li>Server-side managed configuration</li> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 503 | <li>Server-side profile policy control</li> |
| 504 | </ul> |
| 505 | |
| 506 | <p> |
| 507 | You need to access an EMM console to complete the end-to-end |
| 508 | testing. The easiest way to get one is to request a testing console |
| 509 | from your EMM. Once you have access, complete these tasks: |
| 510 | </p> |
| 511 | |
| 512 | <ol> |
| 513 | <li>Create a test version of your application with a |
| 514 | <a href="http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename" |
| 515 | >new ApplicationId</a>.</li> |
| 516 | <li>Claim a <a href="https://support.google.com/work/android/answer/6174056" |
| 517 | >managed Google domain</a> and bind it to your EMM. If you |
| 518 | already have a testing domain that’s bound to an EMM, you may need |
| 519 | to unbind it to test it with your preferred EMM. Please consult your |
| 520 | EMM for the specific unbinding steps.</li> |
| 521 | <li><a href="https://support.google.com/a/answer/2494992" |
| 522 | >Publish your application to the private channel</a> for their |
| 523 | managed Google domain.</li> |
| 524 | <li>Use the EMM console and EMM application to: |
| 525 | <ol> |
| 526 | <li>Set up work devices.</li> |
| 527 | <li>Distribute your application.</li> |
| Billy Lamberta | 9fec73a | 2016-05-19 14:27:49 -0700 | [diff] [blame] | 528 | <li>Set managed configuration.</li> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 529 | <li>Set device policies.</li> |
| 530 | </ol> |
| 531 | </ol> |
| 532 | |
| 533 | <p> |
| 534 | This process will differ based on your EMM. Please consult your |
| 535 | EMM’s documentation for further details. Congrats! You’ve completed |
| 536 | these steps and verified that your app works well with Android for |
| 537 | Work. |
| 538 | </p> |
| 539 | |
| 540 | <p> |
| Billy Lamberta | 2b3870c | 2016-05-17 10:17:00 -0700 | [diff] [blame] | 541 | <a href="https://www.google.com/work/android/developers/applyDevHub/"> |
| Billy Lamberta | e1277eb | 2016-05-03 16:23:59 -0700 | [diff] [blame] | 542 | <span class="dac-sprite dac-auto-chevron"></span> |
| 543 | Learn about the Android for Work DevHub. |
| 544 | </a> |
| 545 | </p> |