位置更新在设备管理/托管工作配置文件模式下不起作用
Location updates are not working in Device Admin / Managed Work Profile Mode
当使用 LocationManager 和 FusedLocationProviderClient 请求位置更新时,我无法在我的应用程序中接收位置更新。所以我尝试了以下代码以允许在我的应用程序中更新位置,但它不起作用。
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));
}
我在 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)
到目前为止,我找到了这个,目前对我帮助不大。
谁能帮我指导这个问题?
经过近 5 天的研究,我找到了解决这个问题的方法。
This link helped me a lot to find a solution to this problem.
要请求启用 Work/Managed 配置文件以供管理员访问,我们需要按以下方式进行:
/**
* 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();
}
}
启用后,您需要在 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 方法中添加以下代码。
/**
* 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");
}
}
}
}
此代码工作正常并经过正确测试。
我希望这对寻找类似答案的人有所帮助。
谢谢。
当使用 LocationManager 和 FusedLocationProviderClient 请求位置更新时,我无法在我的应用程序中接收位置更新。所以我尝试了以下代码以允许在我的应用程序中更新位置,但它不起作用。
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));
}
我在 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)
到目前为止,我找到了这个
经过近 5 天的研究,我找到了解决这个问题的方法。
This link helped me a lot to find a solution to this problem.
要请求启用 Work/Managed 配置文件以供管理员访问,我们需要按以下方式进行:
/**
* 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();
}
}
启用后,您需要在 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 方法中添加以下代码。
/**
* 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");
}
}
}
}
此代码工作正常并经过正确测试。
我希望这对寻找类似答案的人有所帮助。
谢谢。