简体   繁体   中英

No active admin owned … - locking a screen in Android

I want to simply lock the screen. Here's what I did:

public class MainActivity : ActionBarActivity() {
    var dpm: DevicePolicyManager? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        getMenuInflater()?.inflate(R.menu.menu_main, menu)
        dpm?.lockNow()
        return true
    }
}

It's in Kotlin but those who Java will understand it.

And manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.me.com.app123" >
    <uses-permission
        android:name="android.permission.USES_POLICY_FORCE_LOCK">
    </uses-permission>

    <application
        android:allowBackup="true"

The error is:

android.me.com.app123 E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: android.me.com.app123, PID: 22964
    java.lang.SecurityException: No active admin owned by uid 10121 for policy #3
            at android.os.Parcel.readException(Parcel.java:1472)

Haven't I gotten enough permissions when I said "android.permission.USES_POLICY_FORCE_LOCK"? If not how to fix it?

In order to be able to lock the screen, you need to add a Device Admin as described here .

Second: If you got any properties, which you cant assign a value in the constructor, use the notNull-Delegate.

var dpm: DevicePolicyManager by Delegates.notNull()

When you access dpm before it is set, a NPE is thrown. If not, you wont have to check dpm for null all the time.

(previous answer links the correct tutorial)

Your received error because your app not enabled as Device Admin.

Key points for the (pof) implementation:

Policy definition resource (res/xml/....):

<device-admin>
    <uses-policies>
        <force-lock />
    </uses-policies>
</device-admin>

Broadcast receiver:

<receiver android:name="your.LockDeviceAdminReceiver" 
        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>

Check enabled state of your Admin (and start activity if not and handle the result):

val devicePolicyManager = getSystemService(Context.DEVICE_POLICY_SERVICE) 
    as DevicePolicyManager
val deviceAdminReceiver = ComponentName(context, 
    LockDeviceAdminReceiver::class.java)

if (devicePolicyManager.isAdminActive(deviceAdminReceiver)) {
   devicePolicyManager.lockNow()
} else {
    val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
    intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, 
        deviceAdminReceiver))
    startActivityForResult(intent, ENABLE_ADMIN_REQUEST_CODE);
}

You would need 3 thing to do :

  1. add <receiver> to AndroidManifest
  2. make new xml file for <device-admin>
  3. make new .kt file for DeviceAdminReceiver

Here is an answer I already did (with code in Kotlin) : stackoverflow.com

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM