Problems with android lock in custom lock screen a

2020-06-04 07:49发布

I built a custom lock screen app that uses a broadcast receiver and service to listen for when the user turns on or off the screen and from there launch my activity. The activity is supposed to completely replace the lock screen. In order to do this my app is supposed to disable the android stock lock so that my app can function as the new lock screen.

Instead what happens is once the application is first installed the the service first started the application appears to be working. and when the user first turns off the screen of their phone when they turn it back on they are presented with my app running on top and is able to unlock their phone with my app. But then once inside the android OS if the user presses the home button the next time they turn off the screen and turn it back on instead of being brought back to my application they are brought to the stock unlock screen with my application open underneath it, when it should be on top.

Here is my code:

My Service:

public class MyService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {

        super.onCreate();
        Log.d("MyService","Service STARTED");
        final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        final BroadcastReceiver mReceiver = new ScreenReceiver();
        registerReceiver(mReceiver, filter);
    }
}

My broadcast receiver:

public class ScreenReceiver extends BroadcastReceiver {

public static ArrayList<String> runningApplications = new ArrayList<String>();
private Context ctext;
public static boolean screenIsLocked;
public static KeyguardManager keyguardManager;
public static KeyguardLock lock;

@Override
public void onReceive(final Context context, final Intent intent) {
    ctext = context;
    keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
    lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
    lock.disableKeyguard();


    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
        screenIsLocked = true;
        Log.d("ScreenReceiver", "False");

        Intent intenti = new Intent();
        intenti.setClass(context, starterActivity.class);
        intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intenti);


    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
        screenIsLocked = false;
        Log.d("ScreenReceiver", "True");

                    Intent intenti = new Intent();
                    intenti.setClass(context, starterActivity.class);
                    intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intenti);
    }
}

My activity that is started is basically empty with just one unlock button that calls finish(); when pressed.

标签: android
2条回答
淡お忘
2楼-- · 2020-06-04 08:21

I tried to compile your code and got the same error you were talking about. I tried to modify it to make it to work and finally got the problem!!!

public class ScreenReceiver extends BroadcastReceiver {

    public static ArrayList<String> runningApplications = new ArrayList<String>();
    private Context ctext;
    public static boolean screenIsLocked;
    public static KeyguardManager keyguardManager;
    public static KeyguardLock lock;

    @Override
    public void onReceive(final Context context, final Intent intent) {
        ctext = context;
        keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
        lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
        lock.disableKeyguard();


        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            screenIsLocked = true;
            Log.d("ScreenReceiver", "False");

            Intent intenti = new Intent();
            intenti.setClass(context, starterActivity.class);
            intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intenti);


        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            screenIsLocked = false;
            Log.d("ScreenReceiver", "True");

                        Intent intenti = new Intent();
                        intenti.setClass(context, starterActivity.class);
                        intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intenti);
        }
    }

With this change to the broadcast receiver class I was able to overcome the problem

Try it and tell me if there is any problem.

EDIT:I think the problem might lie in the finish() method....Android dumps apps when it requires memory...I think finish() might be helping android in trashing the app(and this might be the reason why your problem occurs randomly)

查看更多
一夜七次
3楼-- · 2020-06-04 08:43

The behavior of keyguard-related logic can vary from device to device. That's because lockscreens are often custom-made by device manufacturers (i.e. not stock), some of them respect the keyguard logic you use, some don't.

Also, afaik the newer way to control keyguard is to use window flags:

// inside activity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

This will not solve the problem though, devices still have their say about this.

E.g. from my experience, Galaxy Nexus will show your activity's window above keyguard but will not dismiss it (you'd think Google-branded device should respect the flag, eh), so if you hit the back button in your activity - you'll get standard lockscreen --- while HTC One X seems to handle the dismiss part properly: your activity window will cause standard lockscreen to get dismissed as expected.

I found no way to force all devices to behave properly. Android API is not meant to enable you to create custom lock screens (at least not currently). Take a look at the ones in the store - they all have the exact same problem of not being stable enough.

As Dianne Hackborn says in this Google Groups answer, anything you can do in this regard is a hack so expect it to break from time to time.

查看更多
登录 后发表回答