{"record":{"id":"2ca2f55978f2e746","repo":"MuntashirAkon/AppManager","slug":"could-not-enable-enable-disable-sensor","errorCode":null,"errorMessage":"Could not ${enable ? \"enable\" : \"disable\"} sensor.","messagePattern":"Could not (.+?) sensor\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/compat/SensorServiceCompat.java","lineNumber":44,"sourceCode":"        try {\n            BinderShellExecutor.ShellResult result = BinderShellExecutor.execute(getSensorService(), command);\n            return \"active\".equals(result.getStdout().trim());\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return true;\n    }\n\n    @RequiresPermission(ManifestCompat.permission.MANAGE_SENSORS)\n    public static void enableSensor(@NonNull String packageName, @UserIdInt int userId, boolean enable) throws IOException {\n        String state = enable ? \"active\" : \"idle\";\n        String[] command;\n        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {\n            command = new String[]{\"set-uid-state\", packageName, state, \"--user\", String.valueOf(userId)};\n        } else command = new String[]{\"set-uid-state\", packageName, state};\n        BinderShellExecutor.ShellResult result = BinderShellExecutor.execute(getSensorService(), command);\n        if (result.getResultCode() != 0) {\n            throw new IOException(\"Could not \" + (enable ? \"enable\" : \"disable\") + \" sensor.\");\n        }\n    }\n\n    @RequiresPermission(ManifestCompat.permission.MANAGE_SENSORS)\n    public static void resetSensor(@NonNull String packageName, @UserIdInt int userId) throws IOException {\n        String[] command;\n        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {\n            command = new String[]{\"reset-uid-state\", packageName, \"--user\", String.valueOf(userId)};\n        } else command = new String[]{\"reset-uid-state\", packageName};\n        BinderShellExecutor.ShellResult result = BinderShellExecutor.execute(getSensorService(), command);\n        if (result.getResultCode() != 0) {\n            throw new IOException(\"Could not reset sensor.\");\n        }\n    }\n\n    @NonNull\n    private static IBinder getSensorService() {\n        return ProxyBinder.getService(\"sensorservice\");","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/compat/SensorServiceCompat.java#L26-L62","documentation":"Thrown by SensorServiceCompat.enableSensor when the binder shell command ('set-uid-state') sent to the system 'sensorservice' service returns a non-zero exit code, meaning Android's sensor privacy manager refused to enable or disable sensor access for the package. This reflects a failure of the privileged remote operation, not a local API misuse.","triggerScenarios":"Calling SensorServiceCompat.enableSensor(packageName, userId, enable) on Android > Q without sufficient privileges (MANAGE_SENSORS / shell or root identity), on a ROM where the sensorservice set-uid-state command is unavailable or rejects the target user, or when the binder call itself fails.","commonSituations":"Non-rooted devices where the app's shell identity lacks sensor-management permission; restricted users/work profiles where the target userId is invalid; vendor ROMs that removed or altered the set-uid-state interface.","solutions":["Verify the app is running with root, ADB shell, or a privileged (system) identity that holds MANAGE_SENSORS permission","Check the target userId exists (adb shell am get-current-user / list users) before calling","Log BinderShellExecutor.ShellResult output to read the underlying error from sensorservice","Test on the same Android version in a shell: cmd sensorservice or service call sensorservice equivalents to confirm support"],"exampleFix":"// before\nBinderShellExecutor.execute(getSensorService(), command); // ignore result details\n// after\nBinderShellExecutor.ShellResult result = BinderShellExecutor.execute(getSensorService(), command);\nif (result.getResultCode() != 0) {\n    Log.e(TAG, \"set-uid-state failed: \" + result.getResultCode() + \" \" + result.getOutput());\n    throw new IOException(\"Could not \" + (enable ? \"enable\" : \"disable\") + \" sensor.\");\n}","handlingStrategy":"try-catch","validationCode":"// requires privileged identity\nboolean privileged = appIsRootOrShellOrSystem();\nif (!privileged) throw new SecurityException(\"MANAGE_SENSORS requires root/shell\");","typeGuard":null,"tryCatchPattern":"try {\n    SensorServiceCompat.enableSensor(pkg, userId, enable);\n} catch (IOException e) {\n    Log.w(TAG, \"Sensor toggle failed for \" + pkg, e);\n    showSensorToggleFailedNotice();\n}","preventionTips":["Only invoke on rooted/ADB/system contexts","Verify userId validity before calls","Log ShellResult output for diagnosis","Test on target Android versions"],"tags":["android","binder","shell","sensor-privacy"],"backgroundTag":"insufficient-permissions","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}