You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发Android系统级设备管理器应用:实现系统设置禁用与变更监控

Hey there! Let's walk through how to build these two security-focused features for your system-level device manager app. Since you're working with a system app, we can leverage Android's built-in device management APIs and system privileges to make this happen:

1. Implementing the "Disable System Settings Modification" Toggle

First off, your app needs to be registered as a Device Owner or Profile Owner—this is a prerequisite for modifying system-level restrictions. Here's how to build the toggle functionality:

Step 1: Set Up Device Admin Components

First, register a DeviceAdminReceiver in your AndroidManifest.xml (this acts as the bridge between your app and Android's device policy system):

<receiver
    android:name=".MyDeviceAdminReceiver"
    android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data
        android:name="android.app.device_admin"
        android:resource="@xml/device_admin_policy" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

Then create the device_admin_policy.xml file in res/xml/ to declare the policies your app needs access to:

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <restrict-applications />
        <disable-keyguard-features />
        <!-- Add any other policies your app requires -->
    </uses-policies>
</device-admin>

Step 2: Build the Toggle Logic

Use the DevicePolicyManager to apply or remove restrictions when the user toggles the feature. You can restrict specific system settings (like WiFi, Bluetooth, display) or even hide the Settings app entirely:

val dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val adminComponent = ComponentName(this, MyDeviceAdminReceiver::class.java)
val settingsToggle = findViewById<ToggleButton>(R.id.settings_disable_toggle)

settingsToggle.setOnCheckedChangeListener { _, isEnabled ->
    val restrictedSettings = setOf(
        UserManager.DISALLOW_CONFIG_WIFI,
        UserManager.DISALLOW_CONFIG_BLUETOOTH,
        UserManager.DISALLOW_CONFIG_DISPLAY,
        UserManager.DISALLOW_CONFIG_LOCATION
    )

    if (isEnabled) {
        // Apply restrictions
        restrictedSettings.forEach { restriction ->
            dpm.addUserRestriction(adminComponent, restriction)
        }
        // Optional: Hide the system Settings app entirely
        dpm.setApplicationHidden(adminComponent, "com.android.settings", true)
    } else {
        // Remove restrictions
        restrictedSettings.forEach { restriction ->
            dpm.clearUserRestriction(adminComponent, restriction)
        }
        dpm.setApplicationHidden(adminComponent, "com.android.settings", false)
    }
}
2. Monitoring System Settings Changes (When the Feature is Active)

Even with restrictions in place, it's good to add a monitoring layer as a safety net. We'll use a ContentObserver to watch for changes to system settings and revert them if needed:

Step 1: Create a Custom ContentObserver

This observer will trigger whenever a monitored setting changes:

class SettingsMonitorObserver(
    handler: Handler,
    private val contentResolver: ContentResolver,
    private val isRestrictionActive: () -> Boolean
) : ContentObserver(handler) {

    override fun onChange(selfChange: Boolean, uri: Uri?) {
        super.onChange(selfChange, uri)
        uri ?: return

        // Only act if the restriction feature is enabled
        if (!isRestrictionActive()) return

        when (uri) {
            // Example: Revert WiFi state if changed
            Settings.Global.getUriFor(Settings.Global.WIFI_ON) -> {
                Settings.Global.putInt(contentResolver, Settings.Global.WIFI_ON, 0)
            }
            // Example: Revert screen brightness to a preset value
            Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS) -> {
                Settings.System.putInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS, 100)
            }
            // Add more settings URIs to monitor as needed
        }
    }
}

Step 2: Register/Unregister the Observer

Register the observer when the restriction is enabled, and unregister it when it's turned off to save resources:

private lateinit var settingsObserver: SettingsMonitorObserver
private val mainHandler = Handler(Looper.getMainLooper())
private var isRestrictionEnabled = false

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    settingsObserver = SettingsMonitorObserver(
        mainHandler,
        contentResolver
    ) { isRestrictionEnabled }
}

private fun startMonitoringSettings() {
    contentResolver.apply {
        registerContentObserver(
            Settings.Global.getUriFor(Settings.Global.WIFI_ON),
            true,
            settingsObserver
        )
        registerContentObserver(
            Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),
            true,
            settingsObserver
        )
        // Register more URIs here
    }
}

private fun stopMonitoringSettings() {
    contentResolver.unregisterContentObserver(settingsObserver)
}

// Update this in your toggle's onCheckedChangeListener
settingsToggle.setOnCheckedChangeListener { _, isEnabled ->
    isRestrictionEnabled = isEnabled
    if (isEnabled) startMonitoringSettings() else stopMonitoringSettings()
    // ... rest of your restriction logic from earlier ...
}

Key Notes for System Apps

  • Your app must be installed in /system/priv-app (privileged system app) and signed with the system's signing key to access these APIs.
  • For Android 11+, use the MANAGE_DEVICE_POLICIES_SETTINGS permission to manage setting restrictions.
  • Always test across different Android versions—some restriction constants or API behaviors may vary.

内容的提问来源于stack exchange,提问作者ManDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:40:30