how to know what resources an android studio program has access to
This developer's guide explains how your device policy controller (DPC) tin manage multiple Android users on dedicated devices.
Overview
Your DPC can help multiple people share a unmarried defended device. Your DPC running on a fully managed device can create and manage two types of users:
- Secondary users are Android users with separate apps and data saved between sessions. You manage the user with an admin component. These users are useful for cases where a device is picked up at the starting time of a shift, such every bit delivery drivers or security workers.
- Ephemeral users are secondary users that the system deletes when the user stops, switches away, or the device reboots. These users are useful for cases where data can be deleted after the session finishes, such as public-access internet kiosks.
Y'all utilise your existing DPC to manage the dedicated device and the secondary users. An admin component in your DPC sets itself equally the admin for new secondary users when you create them.
Admins of a secondary user must vest to the same package as the admin of the fully managed device. To simplify development, nosotros recommend sharing an admin between the device and secondary users.
Managing multiple users on dedicated devices typically requires Android 9.0, even so some of the methods used in this programmer'due south guide are available in before versions of Android.
Create users
Your DPC can create additional users in the groundwork and then can switch them to the foreground. The process is almost the same for both secondary and ephemeral users. Implement the following steps in the admins of the fully managed device and secondary user:
- Call
DevicePolicyManager.createAndManageUser(). To create an ephemeral user, includeMAKE_USER_EPHEMERALin the flags argument. - Call
DevicePolicyManager.startUserInBackground()to get-go the user in the background. The user starts running but yous will want to finish setup before bringing the user to the foreground and showing it to the person using the device. - In the admin of the secondary user, call
DevicePolicyManager.setAffiliationIds()to chapter the new user with the main user. Encounter DPC coordination below. - Dorsum in the admin of the fully managed device, call
DevicePolicyManager.switchUser()to switch the user to the foreground.
The post-obit sample shows how you can add together stride 1 to your DPC:
Kotlin
val dpm = getContext().getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager // If possible, reuse an existing affiliation ID across the // master user and (subsequently) the ephemeral user. val identifiers = dpm.getAffiliationIds(adminName) if (identifiers.isEmpty()) { identifiers.add(UUID.randomUUID().toString()) dpm.setAffiliationIds(adminName, identifiers) } // Pass an amalgamation ID to the ephemeral user in the admin extras. val adminExtras = PersistableBundle() adminExtras.putString(AFFILIATION_ID_KEY, identifiers.first()) // Include whatsoever other config for the new user here ... // Create the ephemeral user, using this component equally the admin. try { val ephemeralUser = dpm.createAndManageUser( adminName, "tmp_user", adminName, adminExtras, DevicePolicyManager.MAKE_USER_EPHEMERAL or DevicePolicyManager.SKIP_SETUP_WIZARD) } catch (e: UserManager.UserOperationException) { if (e.userOperationResult == UserManager.USER_OPERATION_ERROR_MAX_USERS) { // Detect a mode to free up users... } } Java
DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE); // If possible, reuse an existing affiliation ID across the // primary user and (after) the imperceptible user. Set<String> identifiers = dpm.getAffiliationIds(adminName); if (identifiers.isEmpty()) { identifiers.add together(UUID.randomUUID().toString()); dpm.setAffiliationIds(adminName, identifiers); } // Pass an affiliation ID to the ephemeral user in the admin extras. PersistableBundle adminExtras = new PersistableBundle(); adminExtras.putString(AFFILIATION_ID_KEY, identifiers.iterator().side by side()); // Include whatsoever other config for the new user here ... // Create the ephemeral user, using this component as the admin. try { UserHandle ephemeralUser = dpm.createAndManageUser( adminName, "tmp_user", adminName, adminExtras, DevicePolicyManager.MAKE_USER_EPHEMERAL | DevicePolicyManager.SKIP_SETUP_WIZARD); } catch (UserManager.UserOperationException e) { if (e.getUserOperationResult() == UserManager.USER_OPERATION_ERROR_MAX_USERS) { // Observe a way to free up users... } } When y'all create or outset a new user, you tin can check the reason for any failures by catching the UserOperationException exception and calling getUserOperationResult(). Exceeding the user limits are common failure reasons:
-
USER_OPERATION_ERROR_MAX_USERS -
USER_OPERATION_ERROR_MAX_RUNNING_USERS
Creating a user can take some time. If y'all're frequently creating users, you can improve the user experience by preparing a set up-to-go user in the background. You might demand to balance the advantages of a ready-to-go user with the maximum number of users allowed on a device.
Identification
After creating a new user, yous should refer to the user with a persistent series number. Don't persist the UserHandle because the organisation recycles these equally you create and delete users. Get the serial number by calling UserManager.getSerialNumberForUser():
Kotlin
// Afterward calling createAndManageUser() use a device-unique series number // (that isn't recycled) to identify the new user. secondaryUser?.let { val userManager = getContext().getSystemService(UserManager::class.coffee) val ephemeralUserId = userManager!!.getSerialNumberForUser(it) // Save the series number to storage ... } Java
// Afterwards calling createAndManageUser() use a device-unique series number // (that isn't recycled) to identify the new user. if (secondaryUser != null) { UserManager userManager = getContext().getSystemService(UserManager.course); long ephemeralUserId = userManager.getSerialNumberForUser(secondaryUser); // Save the serial number to storage ... } User config
Depending on the needs of your users, y'all can customize the setup of secondary users. You tin can include the following flags when calling createAndManageUser():
-
SKIP_SETUP_WIZARD - Skips running the new-user setup magician that checks for and installs updates, prompts the user to add a Google Account along with Google services, and sets a screen lock. This can take some time and might not be applicable for all users—public internet kiosks, for example.
-
LEAVE_ALL_SYSTEM_APPS_ENABLED - Leaves all the arrangement apps enabled in the new user. If yous don't set this flag, the new user contains simply the minimal set of apps that the telephone needs to operate—typically a file browser, phone dialer, contacts, and SMS messages.
Follow the user lifecycle
Your DPC (if information technology'southward an admin of the fully managed device) might find information technology useful to know when secondary users change. To run follow-on tasks subsequently changes, override these callback methods in your DPC'southward DeviceAdminReceiver subclass:
-
onUserStarted() - Called later the system starts a user. This user might nevertheless exist setting upwards or exist running in the background. You can get the user from the
startedUserargument. -
onUserSwitched() - Chosen after the organization switches to a different user. You can get the new user that's now running in the foreground from the
switchedUserargument. -
onUserStopped() - Chosen after the system stops a user because they logged out, switched to a new user (if the user is ephemeral), or your DPC stopped the user. You can get the user from the
stoppedUserstatement. -
onUserAdded() - Called when the organization adds a new user. Typically, secondary users aren't fully set up when your DPC gets the callback. Yous can get the user from the
newUserargument. -
onUserRemoved() - Called after the organisation deletes a user. Considering the user is already deleted, you can't access the user represented by the
removedUserargument.
To know when the system brings a user to the foreground or sends a user to the background, apps tin annals a receiver for the ACTION_USER_FOREGROUND and ACTION_USER_BACKGROUND broadcasts.
Discover users
To get all the secondary users, an admin of a fully managed device can call DevicePolicyManager.getSecondaryUsers(). The results include whatsoever secondary or ephemeral users the admin created. The results also include any secondary users (or a guest user) a person using the device might have created. The results don't include work profiles because they aren't secondary users. The following sample shows how yous can use this method:
Kotlin
// The device is stored for the night. Stop all running secondary users. dpm.getSecondaryUsers(adminName).forEach { dpm.stopUser(adminName, it) } Java
// The device is stored for the night. Stop all running secondary users. for (UserHandle user : dpm.getSecondaryUsers(adminName)) { dpm.stopUser(adminName, user); } Here are other methods you tin call to detect out the status of secondary users:
-
DevicePolicyManager.isEphemeralUser() - Phone call this method from the admin of a secondary user to detect out if this is an ephemeral user.
-
DevicePolicyManager.isAffiliatedUser() - Call this method from the admin of a secondary user to detect out if this user is affiliated with the master user. To learn more about amalgamation, meet DPC coordination below.
User management
If you want to completely manage the user lifecycle, y'all tin call APIs for fine-grained control of when and how the device changes users. For example, yous can delete a user when a device hasn't been used for a period of time or you can send any unsent orders to a server before a person'due south shift finishes.
Logout
Android 9.0 added a log-out push to the lock screen and so that a person using the device can end their session. After tapping the push, the system stops the secondary user, deletes the user if it's ephemeral, and the primary user returns to the foreground. Android hides the button when the chief user is in the foreground because the primary user can't log out.
Android doesn't testify the end-session push button past default but your admin (of a fully managed device) tin enable it past calling DevicePolicyManager.setLogoutEnabled(). If yous need to confirm the electric current state of the button, phone call DevicePolicyManager.isLogoutEnabled().
The admin of a secondary user can programmatically log out the user and render to the main user. Showtime, confirm the secondary and the master users are affiliated, then call DevicePolicyManager.logoutUser(). If the logged-out user is an ephemeral user, the system stops and then deletes the user.
Switch users
To switch to a unlike secondary user, the admin of a fully managed device tin can call DevicePolicyManager.switchUser(). Equally a convenience, you can pass null to switch to the primary user.
Stop a user
To end a secondary user, a DPC that owns a fully managed device can call DevicePolicyManager.stopUser(). If the stopped user is an ephemeral user, the user is stopped and so deleted.
We recommend stopping users whenever possible to assist stay below the device'south maximum number of running users.
Delete a user
To permanently delete a secondary user a DPC tin can telephone call one of the following DevicePolicyManager methods:
- An admin of a fully managed device tin can telephone call
removeUser(). - An admin of the secondary user tin phone call
wipeData().
The system deletes ephemeral users when they're logged out, stopped, or switched abroad from.
Disable the default UI
If your DPC provides a UI to manage users, you can disable Android's congenital-in multi-user interface. You tin do this by calling DevicePolicyManager.setLogoutEnabled() and adding the DISALLOW_USER_SWITCH restriction as shown in the following example:
Kotlin
// Explicitly disallow logging out using Android UI (disabled by default). dpm.setLogoutEnabled(adminName, false) // Disallow switching users in Android's UI. This DPC tin yet // telephone call switchUser() to manage users. dpm.addUserRestriction(adminName, UserManager.DISALLOW_USER_SWITCH)
Java
// Explicitly disallow logging out using Android UI (disabled past default). dpm.setLogoutEnabled(adminName, fake); // Disallow switching users in Android'due south UI. This DPC tin can however // phone call switchUser() to manage users. dpm.addUserRestriction(adminName, UserManager.DISALLOW_USER_SWITCH);
The person using the device tin't add together secondary users with Android'southward congenital-in UI considering admins of fully managed devices automatically add together the DISALLOW_ADD_USER user restriction.
Session messages
When the person using a device switches to a new user, Android shows a panel to highlight the switch. Android shows the following messages:
- Start-user-session message shown when the device switches to a secondary user from the primary user.
- Cease-user-session bulletin shown when the device returns to the primary user from a secondary user.
The system doesn't prove the messages when switching between ii secondary users.
Because the messages might non be suitable for all situations, you can change the text of these messages. For instance, if your solution uses ephemeral user sessions, you tin can reverberate this in the messages such as: Stopping browser session & deleting personal data…
The system shows the message for merely a couple of seconds, and so each message should be a curt, clear phrase. To customize the messages, your admin tin call the DevicePolicyManager methods setStartUserSessionMessage() and setEndUserSessionMessage() as shown in the following instance:
Kotlin
// Curt, easy-to-read messages shown at the start and end of a session. // In your app, store these strings in a localizable resource. internal val START_USER_SESSION_MESSAGE = "Starting guest session…" internal val END_USER_SESSION_MESSAGE = "Stopping & clearing data…" // ... dpm.setStartUserSessionMessage(adminName, START_USER_SESSION_MESSAGE) dpm.setEndUserSessionMessage(adminName, END_USER_SESSION_MESSAGE)
Java
// Short, piece of cake-to-read messages shown at the start and end of a session. // In your app, shop these strings in a localizable resource. private static final String START_USER_SESSION_MESSAGE = "Starting guest session…"; individual static terminal Cord END_USER_SESSION_MESSAGE = "Stopping & clearing data…"; // ... dpm.setStartUserSessionMessage(adminName, START_USER_SESSION_MESSAGE); dpm.setEndUserSessionMessage(adminName, END_USER_SESSION_MESSAGE);
Laissez passer nada to delete your custom messages and return to Android's default messages. If you need to cheque the current bulletin text, call getStartUserSessionMessage() or getEndUserSessionMessage().
Your DPC should gear up localized messages for the user's current locale. You as well demand to update the messages when the user's locale changes:
Kotlin
override fun onReceive(context: Context?, intent: Intent?) { // Added the <action android:name="android.intent.action.LOCALE_CHANGED" /> // intent filter for our DeviceAdminReceiver subclass in the app manifest file. if (intent?.action === ACTION_LOCALE_CHANGED) { // Android's resources return a string suitable for the new locale. getManager(context).setStartUserSessionMessage( getWho(context), context?.getString(R.cord.start_user_session_message)) getManager(context).setEndUserSessionMessage( getWho(context), context?.getString(R.string.end_user_session_message)) } super.onReceive(context, intent) } Java
public void onReceive(Context context, Intent intent) { // Added the <action android:proper name="android.intent.activeness.LOCALE_CHANGED" /> // intent filter for our DeviceAdminReceiver subclass in the app manifest file. if (intent.getAction().equals(ACTION_LOCALE_CHANGED)) { // Android'due south resource render a string suitable for the new locale. getManager(context).setStartUserSessionMessage( getWho(context), context.getString(R.string.start_user_session_message)); getManager(context).setEndUserSessionMessage( getWho(context), context.getString(R.string.end_user_session_message)); } super.onReceive(context, intent); } DPC coordination
Managing secondary users typically needs two instances of your DPC—i that owns the fully managed device while the other owns the secondary user. When creating a new user, the admin of the fully managed device sets some other instance of itself as the admin of the new user.
Affiliated users
Some of the APIs in this developer's guide only work when the secondary users are affiliated. Because Android disables some features (network logging for example) when you add new unaffiliated secondary users to the device, you should affiliate users as soon as possible. Run into the case in Setup beneath.
Setup
Set up new secondary users (from the DPC that owns the secondary user) earlier letting people employ them. You can do this setup from the DeviceAdminReceiver.onEnabled() callback. If you previously set any admin extras in the telephone call to createAndManageUser(), y'all can get the values from the intent argument. The following example shows a DPC affiliating a new secondary user in the callback:
Kotlin
override fun onEnabled(context: Context?, intent: Intent?) { super.onEnabled(context, intent) // Get the affiliation ID (our DPC previously put in the extras) and // set the ID for this new secondary user. intent?.getStringExtra(AFFILIATION_ID_KEY)?.let { val dpm = getManager(context) dpm.setAffiliationIds(getWho(context), setOf(information technology)) } // Continue setup of the new secondary user ... } Java
public void onEnabled(Context context, Intent intent) { // Get the affiliation ID (our DPC previously put in the extras) and // set the ID for this new secondary user. String affiliationId = intent.getStringExtra(AFFILIATION_ID_KEY); if (affiliationId != zippo) { DevicePolicyManager dpm = getManager(context); dpm.setAffiliationIds(getWho(context), new HashSet<String>(Arrays.asList(affiliationId))); } // Proceed setup of the new secondary user ... } RPCs betwixt DPCs
Even though the two DPC instances are running nether split up users, the DPCs that ain the device and the secondary users can communicate with each other. Considering calling another DPC's service crosses user boundaries, your DPC can't call bindService() equally you normally would in Android. To bind to a service running in another user, phone call DevicePolicyManager.bindDeviceAdminServiceAsUser().
Your DPC can just bind to services running in the users returned past DevicePolicyManager.getBindDeviceAdminTargetUsers(). The post-obit case shows the admin of a secondary user binding to the admin of the fully managed device:
Kotlin
// From a secondary user, the list contains simply the primary user. dpm.getBindDeviceAdminTargetUsers(adminName).forEach { // Set up the callbacks for the service connectedness. val intent = Intent(mContext, FullyManagedDeviceService::form.java) val serviceconnection = object : ServiceConnection { override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) { // Phone call methods on service ... } override fun onServiceDisconnected(componentName: ComponentName) { // Clean up or reconnect if needed ... } } // Bind to the service as the primary user [information technology]. val bindSuccessful = dpm.bindDeviceAdminServiceAsUser(adminName, intent, serviceconnection, Context.BIND_AUTO_CREATE, it) } Coffee
// From a secondary user, the list contains merely the primary user. List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(adminName); if (targetUsers.isEmpty()) { // If the users aren't affiliated, the listing doesn't incorporate any users. return; } // Prepare the callbacks for the service connectedness. Intent intent = new Intent(mContext, FullyManagedDeviceService.form); ServiceConnection serviceconnection = new ServiceConnection() { @Override public void onServiceConnected( ComponentName componentName, IBinder iBinder) { // Call methods on service ... } @Override public void onServiceDisconnected(ComponentName componentName) { // Clean up or reconnect if needed ... } }; // Demark to the service as the primary user. UserHandle primaryUser = targetUsers.go(0); boolean bindSuccessful = dpm.bindDeviceAdminServiceAsUser( adminName, intent, serviceconnection, Context.BIND_AUTO_CREATE, primaryUser); To learn more, including providing a service that other users can demark to, read Profile communication.
Additional resources
To acquire more about dedicated devices, read the following documents:
- Dedicated devices overview is an overview of dedicated devices.
- Lock task mode explains how to lock a defended device to a single app or gear up of apps.
- Dedicated devices cookbook with further examples to restrict the dedicated devices and enhance the user experience.
Source: https://developer.android.com/work/dpc/dedicated-devices/multiple-users
0 Response to "how to know what resources an android studio program has access to"
Post a Comment