KeyguardManager FLAG_DISMISS_KEYGUARD for Service

2019-02-11 01:17发布

问题:

When the screen is turned on, I want to check is power button activated it, if yes, it will auto dismiss the keyguard and run the toast.

When the screen is turned off, the keyguard will be re-enabled. (the code works till here)

However, when the screen is OFF, and i pressed "Volume up" button, the screen turns ON. (but it goes into the loop where it detects "power" button is pressed).

The case should be it shall not activate "Dismiss keyguard" when other buttons(except "power" button) are pressed.

any help is much appreciated to solve this bug :)

another question - how do I use FLAG_DISMISS_KEYGUARD in Service?

public class myService extends Service{

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

}

@Override
public void onStart(Intent intent, int startId) {
    boolean screenOn = intent.getBooleanExtra("screen_state", false);
    boolean pressed = false;       
    Vibrator myVib;

    //screen is turned on
    if (!screenOn) 
    {
        pressed = onKeyDown(26, null);

        //if it turned on by power button. bug = always go into this loop
        if(pressed)
        {
            Context context = getApplicationContext();
            CharSequence text = "Service started. power button pressed";
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();               

            //dimiss keyguard
            KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
            KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
            lock.disableKeyguard();


            Context context2 = getApplicationContext();
            CharSequence text2 = "SCREEN ON";
            int duration2 = Toast.LENGTH_SHORT;

            Toast toast2 = Toast.makeText(context2, text2, duration2);
            toast2.show();

        }           
        else
        {
            Context context = getApplicationContext();
            CharSequence text = "Service started. NOT power button pressed";
            int duration = Toast.LENGTH_SHORT;

            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
        }

    }

    //screen is turned off
    else {
        myVib = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
        myVib.vibrate(500);

        KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
        KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
        lock.reenableKeyguard();

    }
}

 public boolean onKeyDown(int keyCode, KeyEvent event) {
     if(keyCode == KeyEvent.KEYCODE_POWER)
         return true;
     else
        return false;
 }
}//end of myService class

回答1:

Okay so this is not as simple as it would seem Services cannot actually own the currently running activity but you need an activity to get a reference to the window

So you could do that bit a couple of different ways.

Turning off the screen from a service
In the answer given in this question a dummy activity is created (one that is not inflated) and used to get the window (works but not sure what if the uninflated activity causes a leak or other issues. Plus it seems kinda like a dirty hack)

Or.....

The CommonWares way

how can i get the current foreground activity from a service
You could handle the actual window manipulation in a callback fired when your service broadcasts an intent to the activity that will be doing this. (Better design but a bit more archetectural reworking) Example

Once you decide how you want to do (I would recommend #2) The following should work but, note I have not tested it.

//Get the window from the context
WindowManager wm = Context.getSystemService(Context.WINDOW_SERVICE);

//Unlock
//http://developer.android.com/reference/android/app/Activity.html#getWindow()
Window window = getWindow();  
window.addFlags(wm.LayoutParams.FLAG_DISMISS_KEYGUARD);  

//Lock device
DevicePolicyManager mDPM;
mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);