锁定或者关闭屏幕的编程实现

4

我希望能够通过编程 关闭/ 锁定 设备的屏幕。

目前,当我尝试以下操作时:

DevicePolicyManager mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
mDPM.lockNow();

我遇到了这个错误:

java.lang.SecurityException: uid为10176的用户没有拥有策略#3的活跃管理员

这是我的AndroidManifest.xml文件内容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="opteamit.com.belami" >

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-feature android:name="android.hardware.location.gps" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <application...

什么出了问题?

1
展示你的manifest.xml文件。 - user6490462
完成了!您只想查看权限吗? - Jéwôm'
3个回答

14

对于一些高度必要的操作,仅凭两行代码是无法完成的,需要锁定屏幕权限 设备管理员。您可以按照以下步骤进行:

private void lock() {
    PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
    if (pm.isScreenOn()) {
        DevicePolicyManager policy = (DevicePolicyManager)
                getSystemService(Context.DEVICE_POLICY_SERVICE);
        try {
            policy.lockNow();
        } catch (SecurityException ex) {
            Toast.makeText(
                    this, 
                    "must enable device administrator",
                    Toast.LENGTH_LONG).show();
                ComponentName admin = new ComponentName(context, AdminReceiver.class);
                Intent intent = new Intent(
                    DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN).putExtra(
                        DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
                context.startActivity(intent);
        }           
    }
}

以及AdminReceiverClass

public class AdminReceiver extends DeviceAdminReceiver {
    public static final String ACTION_DISABLED = "device_admin_action_disabled";
    public static final String ACTION_ENABLED = "device_admin_action_enabled";

    @Override
    public void onDisabled(Context context, Intent intent) {
        super.onDisabled(context, intent);
        LocalBroadcastManager.getInstance(context).sendBroadcast(
            new Intent(ACTION_DISABLED));
    }
    @Override
    public void onEnabled(Context context, Intent intent) {
        super.onEnabled(context, intent);
        LocalBroadcastManager.getInstance(context).sendBroadcast(
            new Intent(ACTION_ENABLED));
    }
}

同时,我们还需要声明元数据中使用的安全策略,例如路径为 android:resource="@xml/device_admin_sample":

 <device-admin xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-policies>
    <limit-password />
    <watch-login />
    <reset-password />
    <force-lock />
    <wipe-data />
    <expire-password />
    <encrypted-storage />
    <disable-camera />
  </uses-policies>
</device-admin>

在我们的情况下,我们只需要:

<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <force-lock />
    </uses-policies>
</device-admin>`

现在在我们的manifist.xml文件中声明它:

<receiver
        android:name=".AdminReceiver"
        android:label="@string/device_admin"
        android:description="@string/device_admin_description"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
        <meta-data
            android:name="android.app.device_admin"
            android:resource="@xml/device_admin_sample" />
        <intent-filter>
            <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
        </intent-filter>
    </receiver>`

希望它能帮助你。

@Jéwôm' 这是什么新的异常?发生时间是什么时候? - user6490462
它发生在startActivity(intent)行上。 - Jéwôm'
@Jéwôm' 只需通过构造函数缓存Context对象,并在启动活动之前使用此行 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - user6490462
我收到了“必须启用设备管理员”的消息,但没有任何反应。 - Jéwôm'
1
@Jéwôm' 只需按照此链接进行操作即可。 - user6490462
显示剩余3条评论

0
请参考下面用户6490462的答案。
private void lock() {
    PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
    if (pm.isScreenOn()) {
       DevicePolicyManager policy = (DevicePolicyManager)
               getSystemService(Context.DEVICE_POLICY_SERVICE);
       try {
           policy.lockNow();
       } catch (SecurityException ex) {
           Toast.makeText(
                   this, 
                   "must enable device administrator",
                   Toast.LENGTH_LONG).show();
               ComponentName admin = new ComponentName(context, AdminReceiver.class);
               Intent intent = new Intent(
                   DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN).putExtra(
                       DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
               context.startActivity(intent);
       }           
   }
}
对于我们这些从谷歌跳转而来,无法弹出管理员请求的人,我最终解决了这个问题,确保我从当前正在运行的 Activity 中启动了该活动(因此,在调用时不需要在前面加上 context.)。虽然有些人可能会在服务中使用 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 取得成功,但我必须将调用移至一个 Activity 中。
ComponentName admin = new ComponentName(context, AdminReceiver.class);
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
  .putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
startActivity(intent);


0

在遵循user6490462的指示后,这对我起作用了,但我必须稍微调整一下Intent

即使进行了这些更改,由于某种原因,我无法让活动窗口弹出以批准设备管理员权限。但是当我进入生物识别和安全 ->其他安全设置 ->设备管理员应用程序时,我可以看到我的应用程序在那里等待批准其管理员权限。

    ComponentName admin = new ComponentName(getApplicationContext(), AdminReceiver.class);
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                    "Allow this app to turn screen off");
startActivity(intent);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接