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

Android应用执行命令失败求助:非Root设备无法锁屏

解决未Root Android设备的代码锁屏问题

首先得明确:你遇到的java.io.Exception直接原因是你的设备没有Root权限——su命令是只有Root用户才能执行的,未Root设备里根本不存在这个可执行文件,自然会触发执行错误。

针对未Root设备,Android官方提供了合法的锁屏方式,下面给你两个可行的方案:


方案一:使用DevicePolicyManager(官方推荐)

这是Android系统提供的标准设备管理API,专门用于实现锁屏、重置设备等管理功能,不需要Root,但需要用户手动授权你的应用成为设备管理员。

步骤1:创建设备管理员接收器

新建一个继承自DeviceAdminReceiver的类,基础实现即可(可选重写状态监听方法):

public class MyDeviceAdminReceiver extends DeviceAdminReceiver {
    @Override
    public void onEnabled(Context context, Intent intent) {
        super.onEnabled(context, intent);
        Toast.makeText(context, "设备管理员已激活", Toast.LENGTH_SHORT).show();
    }
}

步骤2:在AndroidManifest中注册接收器

添加BIND_DEVICE_ADMIN权限,并配置对应的meta-data和intent-filter:

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

步骤3:创建设备管理员配置文件

在res/xml目录下新建device_admin.xml,声明锁屏所需的权限:

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <force-lock /> <!-- 锁屏必须的权限 -->
    </uses-policies>
</device-admin>

步骤4:在Activity中申请权限并执行锁屏

在你的MainActivity中,获取实例、引导授权后调用锁屏方法:

public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_CODE_ENABLE_ADMIN = 1001;
    private DevicePolicyManager mDpm;
    private ComponentName mAdminComponent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
        mAdminComponent = new ComponentName(this, MyDeviceAdminReceiver.class);

        // 检查权限状态
        if (mDpm.isAdminActive(mAdminComponent)) {
            mDpm.lockNow(); // 已授权直接锁屏
        } else {
            // 引导用户开启设备管理员
            Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminComponent);
            intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "需要激活权限以实现锁屏");
            startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_ENABLE_ADMIN && resultCode == RESULT_OK) {
            mDpm.lockNow(); // 用户授权成功后锁屏
        } else {
            Toast.makeText(this, "未授权无法执行锁屏", Toast.LENGTH_SHORT).show();
        }
    }
}

方案二:使用AccessibilityService(Android 10+)

如果你的应用目标版本是Android 10(API 29)及以上,还可以通过辅助功能服务模拟锁屏操作,同样不需要Root,但需要用户手动开启辅助功能权限。

步骤1:创建辅助功能服务类

public class LockAccessibilityService extends AccessibilityService {
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {}

    @Override
    public void onInterrupt() {}

    // 对外暴露锁屏方法
    public void lockScreen() {
        performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
    }

    // 用于绑定服务的Binder类
    private final IBinder mBinder = new LocalBinder();
    public class LocalBinder extends Binder {
        LockAccessibilityService getService() {
            return LockAccessibilityService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

步骤2:在Manifest中注册服务

<service
    android:name=".LockAccessibilityService"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_service_config" />
</service>

步骤3:创建辅助功能配置文件

在res/xml目录下新建accessibility_service_config.xml:

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagDefault"
    android:canPerformGestures="true"
    android:description="@string/accessibility_desc" />

记得在strings.xml添加描述:

<string name="accessibility_desc">本服务用于实现锁屏功能</string>

步骤4:引导用户开启权限并锁屏

在Activity中检查权限并调用:

public class MainActivity extends AppCompatActivity {
    private static final int REQUEST_ACCESSIBILITY = 1002;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (!isAccessibilityEnabled()) {
            // 引导用户打开辅助功能设置
            startActivityForResult(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), REQUEST_ACCESSIBILITY);
        } else {
            performLock();
        }
    }

    // 检查辅助功能是否开启
    private boolean isAccessibilityEnabled() {
        final String service = getPackageName() + "/" + LockAccessibilityService.class.getCanonicalName();
        int enabled = 0;
        try {
            enabled = Settings.Secure.getInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        if (enabled == 1) {
            String services = Settings.Secure.getString(getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
            if (services != null) {
                for (String s : services.split(":")) {
                    if (s.equalsIgnoreCase(service)) return true;
                }
            }
        }
        return false;
    }

    // 执行锁屏
    private void performLock() {
        bindService(new Intent(this, LockAccessibilityService.class), new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                LockAccessibilityService.LocalBinder binder = (LockAccessibilityService.LocalBinder) service;
                binder.getService().lockScreen();
                unbindService(this);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {}
        }, Context.BIND_AUTO_CREATE);
    }
}

总结

  • 未Root设备绝对无法使用su命令,这是系统级安全限制,没有合法绕过的方式。
  • 上述两个方案都是Android官方允许的合法途径,虽需用户手动授权,但这是保障用户隐私的必要流程。
  • 优先推荐方案一(DevicePolicyManager),权限逻辑更清晰,用户接受度更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:31:12