如何以编程方式禁用同步适配器或提供程序作为设备管理员?

How do I disable a syncadapter or provider as Device Admin programmatically?

我需要编写一个可以防止在工作资料中同步联系人的应用程序。 直到 Android 9 我刚刚禁用了包 com.google.android.syncadapters.contacts 就这样。

不幸的是,自 Android10 起,Play 服务负责从 Google 帐户同步联系人。但我不想在工作配置文件中禁用包 com.google.android.gms,因为它有更多的副作用。

所以我目前正在寻找一种方法或 API 以设备管理员或工作配置文件的所有者身份禁用另一个应用程序的特定组件。

感谢和问候, 大卫

我有 3 种方法来尝试完成此操作,但从未测试过它们:

解决方案 1 - 自动设置同步:

Account[] accounts = AccountManager.get(this).getAccountsByType(theAccountType);
for (Account account : accounts) {
    Log.d(TAG, "got " + account.type + " / " + account.name);
    ContentResolver.setSyncAutomatically(account,ContactsContract.AUTHORITY,false); // disable auto-syncing on that sync-adapter

ContentResolver.setIsSyncable(账户,ContactsContract.AUTHORITY,假); // 也禁用定期同步 }

解决方案 2 - 显式删除帐户:

认为 如果你试图禁用一个同步适配器,这取决于你的目标 API Android 可能会抛出异常它属于您自己的应用程序(即使用不同的证书签名)。但是,值得一试。

Account[] accounts = AccountManager.get(this).getAccountsByType(theAccountType);
for (Account account : accounts) {
    Log.d(TAG, "got " + account.type + " / " + account.name);
    AccountManager.removeAccountExplicitly(account); // completely removing the account, not just disabling sync... beware.
}

解决方案 3 - 启动 syncadapter 的设置屏幕:

您的第二个最佳选择是启动特定设置屏幕以允许用户通过单击快速禁用同步:

final SyncAdapterType[] syncs = ContentResolver.getSyncAdapterTypes();
for (SyncAdapterType sync : syncs) {
    Log.d(TAG, "found SyncAdapter: " + sync.accountType);
    if (theAccountType.equals(sync.accountType)) {
        Log.d(TAG, "found it: " + sync);
        String activityStr = sync.getSettingsActivity();
        Intent intent = new Intent(Intent.ACTION_VIEW, activityStr);
        // launch the intent
    }
}