Android - 允许在设备所有者应用程序中安装非市场应用程序失败

Android - Allowing installation of non-market-apps fails in device owner app

我正在尝试以编程方式设置安全设置 "Unknown Sources - Allow installation of apps from unknown sources"。

为此,DevicePolicyManager(级别 21)提供了一项功能 ("SetSecureSetting") 来设置此设置(仅适用于配置文件或设备所有者)。

在我的 Device-Owner-App(通过 NFC 配置部署)中,我尝试了以下代码:

public void allowNonMarketApps() {
    DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
    ComponentName deviceAdmin = new ComponentName(this, AdminReceiver.class);
    try {
      devicePolicyManager.setSecureSetting(deviceAdmin, Settings.Secure.INSTALL_NON_MARKET_APPS, "1");
    } catch (SecurityException e) {
      Log.d(TAG, "securityException caught");
    }
}

尽管我的应用程序是设备所有者,但我总是收到 SecurityException!

谁能帮我解决这个问题?

提前致谢!!

编辑 SecurityException 的输出告诉我设备所有者无法更改此设置:

java.lang.SecurityException: Permission denial: Device owners cannot update install_non_market_apps
W/System.err(27634):    at android.os.Parcel.readException(Parcel.java:1547)
W/System.err(27634):    at android.os.Parcel.readException(Parcel.java:1499)
W/System.err(27634):    at android.app.admin.IDevicePolicyManager$Stub$Proxy.setSecureSetting(IDevicePolicyManager.java:7158)
W/System.err(27634):    at android.app.admin.DevicePolicyManager.setSecureSetting(DevicePolicyManager.java:3753)

我很困惑,因为文档讲述了一些不同的东西:

public void setSecureSetting (ComponentName admin, String setting, String value) 

(Added in API level 21)

Called by profile or device owners to update Settings.Secure settings. Validation that the value of the setting is in the correct form for the setting type should be performed by the caller.

The settings that can be updated by a profile or device owner with this method are:

DEFAULT_INPUT_METHOD

INSTALL_NON_MARKET_APPS

SKIP_FIRST_USE_HINTS

显然,更改 INSTALL_NON_MARKET_APPS 的功能已添加到 API 22.

您可以在 2014 年 10 月 21 日完成的代码库中找到更改(在 API 21 发布后)here:

This allows work profile MDM to enable unknown sources even if the user doesn't have UI for it. Installing an app from an unknown source will still prompt the user with the package installer dialog, so it's not like the MDM can now quietly install apps from non-market sources

此功能在 API 21 中明确缺失。

防止用户安装非市场应用程序也可以通过以下方式实现

DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName deviceAdmin = new ComponentName(this, AdminReceiver.class);
try {
  devicePolicyManager.addUserRestriction(deviceAdmin,
               UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
} catch (SecurityException ex) {
  Log.e(TAG, ex.getMessage());
}

您可以按如下方式解除限制

DevicePolicyManager devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName deviceAdmin = new ComponentName(this, AdminReceiver.class);
try {
  devicePolicyManager.clearUserRestriction(deviceAdmin,
               UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
} catch (SecurityException ex) {
  Log.e(TAG, ex.getMessage());
}

以上代码适用于 Device Owner 应用程序的 API 级别 21 (Android 5.0)。