Reputation: 6360
When location updates are requested with LocationManager as well as FusedLocationProviderClient, I'm unable to receive location updates in my app. So I have tried below code to allow the location updates in my app, but it is not working.
manager = (DevicePolicyManager)
getSystemService(Context.DEVICE_POLICY_SERVICE);
if (manager.isProfileOwnerApp(getApplicationContext().getPackageName())) {
ComponentName componentName = new ComponentName(this, CommCareDeviceAdminReceiver.class);
manager.setSecureSetting(componentName, Settings.Secure.LOCATION_MODE, String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY));
}
I received following error in my logcat -
06-15 20:00:33.885 18226-18226/? W/System.err: java.lang.SecurityException: Permission denial: Profile owners cannot update location_mode
at android.os.Parcel.readException(Parcel.java:1684)
at android.os.Parcel.readException(Parcel.java:1637)
at android.app.admin.IDevicePolicyManager$Stub$Proxy.setSecureSetting(IDevicePolicyManager.java:6238)
at android.app.admin.DevicePolicyManager.setSecureSetting(DevicePolicyManager.java:5533)
at org.commcare.devicepolicycontroller.CommCareDeviceAdminReceiver.enableProfile(CommCareDeviceAdminReceiver.java:69)
at org.commcare.devicepolicycontroller.CommCareDeviceAdminReceiver.onProfileProvisioningComplete(CommCareDeviceAdminReceiver.java:51)
at android.app.admin.DeviceAdminReceiver.onReceive(DeviceAdminReceiver.java:665)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3061)
at android.app.ActivityThread.-wrap18(ActivityThread.java)
06-15 20:00:33.886 18226-18226/? W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1574)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6165)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
So far, I have found this link, which is not much helpful to me for now. Can anyone please help me guide in this issue?
Upvotes: 3
Views: 932
Reputation: 6360
After almost 5 days of research, I have found the solution to this issue.
This link helped me a lot to find a solution to this problem.
To request enabling the Work/Managed Profile for Admin access, we need to do it as below:
/**
* Initiates the managed profile provisioning. If we already have a managed profile set up on
* this device, we will get an error dialog in the following provisioning phase.
*/
private void provisionManagedProfile() {
Activity activity = getActivity();
if (null == activity) {
return;
}
PackageManager packageManager = activity.getPackageManager();
if (!packageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
String message = getString(R.string.managed_users_unsupported);
HyperLog.e(Constants.TAG, message);
((TextView)activity.findViewById(R.id.setup_text)).setText(message);
return;
}
Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE);
if (Build.VERSION.SDK_INT >= 24) {
intent.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
CommCareDeviceAdminReceiver.getComponentName(activity));
}
else {
intent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
activity.getApplicationContext().getPackageName());
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, CommCareDeviceAdminReceiver.getComponentName(activity));
}
if (intent.resolveActivity(packageManager) != null) {
startActivityForResult(intent, REQUEST_PROVISION_MANAGED_PROFILE);
activity.finish();
} else {
Toast.makeText(activity, "Device provisioning is not enabled. Stopping.",
Toast.LENGTH_SHORT).show();
}
}
And once it is enabled, you need to add below code in onEnabled method of DeviceAdminReceiver. We will use setPermissionGrantState method from DevicePolicyManager. Additionally, we can also prevent these managed profile user from going into safe mode by using addUseRestriction Method.
/**
* Handles events related to managed profile.
*/
public class MyDeviceAdminReceiver extends DeviceAdminReceiver {
/**
* Called after the administrator is first enabled
*/
@Override
public void onEnabled(Context context, Intent intent) {
super.onEnabled(context, intent);
DevicePolicyManager manager =
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (manager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//ADDING DYNAMIC LOCATIONS PERMISSIONS IS VERY IMPORTANT IS MANAGED PROFILE
manager.setPermissionGrantState(getComponentName(context)
, "com.example.mypackagename"
, Manifest.permission.ACCESS_FINE_LOCATION
, DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
manager.setPermissionGrantState(getComponentName(context)
, "com.example.mypackagename"
, Manifest.permission.ACCESS_COARSE_LOCATION
, DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
//------------------------------------------
// To disable safe boot
manager.addUserRestriction(getComponentName(context), UserManager.DISALLOW_SAFE_BOOT);
// To enable safe boot again
// manager.clearUserRestriction(admin, UserManager.DISALLOW_SAFE_BOOT);
Log.i(TAG, "addUserRestriction is done");
}
}
}
}
This code is working fine and properly tested.
I hope this might help someone looking for similar answers.
Thank You.
Upvotes: 4