Help with PROXIMITY_SCREEN_OFF_WAKE_LOCK in Android
Asked Answered
A

7

8

I've enabled the proximity wakelock in my app, and it turns off the screen when the proximity sensor detects something. But there is a problem when the screen wakes back up -- it goes to the lockscreen, not my app. This happens regardless of the time that the screen was off (even if the sensor is cleared after a few seconds). Here's the code I used:

int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;    
mProximityWakeLock = pm.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
if(!mProximityWakeLock.isHeld()){
    mProximityWakeLock.acquire();
}

Is there any way to correct that behavior?

Autorotation answered 13/6, 2011 at 20:24 Comment(0)
R
5

You can dismiss the lock screen, if it is not a secure one, using:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

You can either call it on creation to prevent the lock screen from ever appearing or when you need to. I use it in combination with:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

Which does not seem to interfere with the proximity lock.

Repetition answered 4/7, 2011 at 9:8 Comment(1)
Wouldn't that disable the lockscreen for my app? I don't want to do that -- I want the lockscreen to function properly. I just don't want it to get locked when it shouldn't (namely, when the proximity sensor is releases and the screen turns back on). The expected behavior is that the screen returns to my app, unless a long enough timeout period has pssed that the lockscreen is enabled.Autorotation
T
4

I use this code

import android.content.Context;
import android.os.PowerManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private PowerManager mPowerManager;
    private PowerManager.WakeLock mWakeLock;

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    }

    public void activateSensor(View v) {
        Toast.makeText(MainActivity.this, "Proximity On", Toast.LENGTH_LONG).show();
        if (mWakeLock == null) {
            mWakeLock = mPowerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "incall");
        }
        if (!mWakeLock.isHeld()) {
            Log.d(TAG, "New call active : acquiring incall (CPU only) wake lock");
            mWakeLock.acquire();
        } else {
            Log.d(TAG, "New call active while incall (CPU only) wake lock already active");
        }
    }

    public void deactivateSensor(View v) {
        Toast.makeText(MainActivity.this, "Proximity Off", Toast.LENGTH_LONG).show();
        if (mWakeLock != null && mWakeLock.isHeld()) {
            mWakeLock.release();
            Log.d(TAG, "Last call ended: releasing incall (CPU only) wake lock");
        } else {
            Log.d(TAG, "Last call ended: no incall (CPU only) wake lock were held");
        }
    }

}

In the manifest:

<uses-permission android:name="android.permission.WAKE_LOCK" />

In my layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.proximitysensor.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/activity_main_turn_on_screen"
        android:onClick="activateSensor"
        android:text="@string/activity_main_activate_sensor" />

    <Button
        android:id="@+id/activity_main_turn_on_screen"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:onClick="deactivateSensor"
        android:text="@string/activity_main_deactivate_sensor" />
</RelativeLayout>
Titre answered 8/3, 2016 at 12:50 Comment(15)
Very nice code, good job! I've got a question. Can I just turn off the display using your code with only the button press? (no proximity sensor!)Durman
I don't know without proximity sensor... you can check this link... sorry.Titre
No problem. There's a small issue though. Your current code turns off the display but also "pauses" any open app. For example, if the display turns off during a game, the game is "paused". I just want to turn off the display and keep the device running normally. Is it possible?Durman
Or is this a restriction by Android?Durman
I used this code when I made a app for calls. This is the reason I need proximity when user calls. I think that Android prefers to restriction. Because I didn't found any code and anything in documentation, except PROXIMITY_SCREEN_OFF_WAKE_LOCKTitre
Thanks for the reply. What about PARTIAL_WAKE_LOCK?Durman
I read the documentation and it says that If the user presses the power button, then the screen will be turned off PARTIAL_WAKE_LOCK I think that you don't need this.Titre
That's what I want if it doesn't "pause" any open app such as a game.Durman
I would like turn off the display of my device while mirroring on my TV.Durman
You can check this tutorial.Titre
Thanks, but what can I learn from your link? Again: my goal is to turn off the display of my device while mirroring on my TV. :)Durman
With PROXIMITY_SCREEN_OFF_WAKE_LOCK you can turn off screen. With PARTIAL_WAKE_LOCK you can wake lock. That's all.Titre
I know, but this also "pauses" any open app when the screen turns off. A video will be paused or a game will be paused.Durman
Did you understand?Durman
Sorry... If you gonna turn off the screen without proximity sensor... I don't know how to make.Titre
S
3

Besides wakeLock from PowerManager you must create KeyGuard lock like this:

private WakeLock mWakeLock = null;
private KeyguardLock mKeyguardLock = null;

public void enableProximitySensor() {
  PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
  mWakeLock = pm.newWakeLock(PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);
  mWakeLock.acquire();

  KeyguardManager km = (KeyguardManager) getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE);
  mKeyguardLock = mManager.newKeyguardLock( KEYGUARD_TAG );
}

public void disableProximitySensor() {
  if ( null != mWakeLock ) {
    mWakeLock.release();
    mWakeLock = null;
  }
  if ( null != mKeyguardLock ) {
    mKeyguardLock.disableKeyguard();
    mKeyguardLock = null;
  }
}

Create this lock only for the same time as you acquire proximity wake lock and lock screen will work all other time in your application.

Sustenance answered 22/2, 2012 at 17:41 Comment(3)
How would this stop the lockscreen from coming on?Autorotation
Well, this solution helped me in same situation =) I faced with same problem - after the phone moves away from ear lock screen appears. Using of KeyguardLock helps me. Sample code was edited a bit to clarify my thoughts.Sustenance
Worth noting that this requires an extra permission (DISABLE_KEYGUARD)Variety
A
2

If you're using mProximityWakeLock.release();, try using mProximityWakeLock.release(1);

The API reference is also hidden, but you can look at the source code: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/os/PowerManager.java#PowerManager.WakeLock.release%28int%29

Aegrotat answered 13/6, 2011 at 22:17 Comment(4)
Thanks, I'm already using mProximityWakeLock.release(1). I used reflection to get it working, and it definitely works -- the screen turns off when I cover the proximity sensor, and turns back on when I clear it. It just goes into the lockscreen, which obviously isn't what I want.Autorotation
@Autorotation Could you explain how do you use reflection to can use mProximityWakeLock.release(1) ??. Thanks in advanceLeatherwood
There is no easy way to post it as a comment, but go ahead ans start your own question about how to do it, and I can post the code there as an answerAutorotation
For anyone wondering as I was, the 1 in mProximityWakeLock.release(1) refers to the PowerManager flag RELEASE_WAIT_FOR_NO_PROXIMITY. (See docs), which doesn't release the WakeLock until the object is no longer close.Charmain
L
1

How did u manage to turn back the screen on? I managed to turn the screen off, when the sensor is covered, using:

WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
etWindow().setAttributes(lp);

and after this, "releasing" or "reseting" the cover from/on the sensor, won't execute the other part of the code:

WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.buttonBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
etWindow().setAttributes(lp);
Layette answered 30/1, 2012 at 15:41 Comment(0)
T
1
private WakeLock mProximityWakeLock= null;

mProximityWakeLock= pm.newWakeLock(PowerManager.FULL_WAKE_LOCK|PowerManager.ACQUIRE_CAUSES_WAKEUP , LOG_TAG);

Acquiring lock when screen needed to turn on and releasing when needed to off i.e. reverse to above wakeLock will work fine.

Turtle answered 11/4, 2013 at 11:6 Comment(0)
T
0

If it is appropriate for your app you can use

getWindow().addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED | LayoutParams.FLAG_IGNORE_CHEEK_PRESSES);
Trap answered 24/2, 2012 at 9:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.