androiddevice-admin

Device Admin Receiver not working in few versions


I am working on a security app, which protects device from strangers.

In my application, I have a feature that should capture the image from front camera if user tries to unlock device with wrong PIN/Pattern/Password.

I have a code something like this.

public class MyAdminReceiver extends DeviceAdminReceiver {

    @Override
    public void onPasswordFailed(Context context, Intent intent, UserHandle user) {


        Log.d("MyTag", "onPasswordFailed called");
        //Code for starting a service for image capture goes here
        .
        .
        .
    }
    ....
    ....
}

In almost all the versions, I am getting the image captured properly, and the app is working fine.

Issue is: In a few devices the function onPasswordFailed is not working. Device admin is activated properly. I tried disabling it again and re-activating it. I tried restarting the device. But nothing worked. I can see this log in my stacktrace.

03-09 12:04:48.078 18491-18491/com.my.pkgname D/ActivityThread: BDC-Calling onReceive: intent=Intent { act=android.app.action.ACTION_PASSWORD_FAILED flg=0x10 cmp=com.my.pkgname/.receivers.MyAdminReceiver }, receiver=com.my.pkgname.receivers.MyAdminReceiver@30c2044b
03-09 12:04:48.079 18491-18491/com.my.pkgname D/ActivityThread: BDC-RECEIVER handled : 0 / ReceiverData{intent=Intent { act=android.app.action.ACTION_PASSWORD_FAILED flg=0x10 cmp=com.my.pkgname/.receivers.MyAdminReceiver } packageName=com.my.pkgname resultCode=-1 resultData=null resultExtras=null}

This issue is so far seen in all the devices I could see of Android 6.0 (Marshmallow version) and Android 7.1.1 (Its Motorola device, if that helps).

I have already checked below questions:

They are not relevant as my admin.xml file, and Manifest declaration is alright and its working in all other devices with version Android 7, 8, 9.

And I have tested using pattern, valid PIN which is more than minimum length. I have not set other password restrictions at all.

Still I am showing the Manifest part an admin.xml for verifying.

Manifest declaration:

....
<application>
    ....
    <receiver
        android:name=".receivers.MyAdminReceiver"
        android:exported="true"
        android:enabled="true"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
        <meta-data
            android:name="android.app.device_admin"
            android:resource="@xml/admin" />

        <intent-filter>
            <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            <action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
        </intent-filter>
    </receiver>
    ....
</application>

admin.xml file:

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <watch-login />
    </uses-policies>
</device-admin>

Can someone help with this issue?

Let me know if there is any special permission required / or setting that is mandatory.

P.S: I tested with some changes in code. Same device admin can perform lockNow() function properly when I added necessary policy in admin.xml. So device admin is setup correctly. So what is the issue that onPasswordFailed might not be called?

I also tried adding intent filter for ACTION_PASSWORD_FAILED in manifest. Made no difference.

<intent-filter>
    <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    <action android:name="android.app.action.ACTION_PASSWORD_FAILED" />
    <action android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED"/>
</intent-filter>

Solution

  • void onPasswordFailed(Context context, Intent intent, UserHandle user) only works with Oreo and above.

    For backward compatibility, you also need to override onPasswordFailed(Context context, Intent intent). That will make your code work on Nougat and below.