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?

user496854
  • 6,461
  • 10
  • 47
  • 84

7 Answers7

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.

Steelight
  • 3,347
  • 1
  • 20
  • 17
  • 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. – user496854 Jul 04 '11 at 09:23
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>
Cabezas
  • 9,329
  • 7
  • 67
  • 69
  • 1
    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!) – Dake Jul 26 '16 at 16:21
  • I don't know without proximity sensor... you can check this [link](http://stackoverflow.com/questions/6756768/turn-off-screen-on-android)... sorry. – Cabezas Jul 26 '16 at 17:22
  • 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? – Dake Jul 26 '16 at 18:18
  • Or is this a restriction by Android? – Dake Jul 26 '16 at 18:27
  • 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_LOCK](https://developer.android.com/reference/android/os/PowerManager.html#PROXIMITY_SCREEN_OFF_WAKE_LOCK) – Cabezas Jul 27 '16 at 07:18
  • Thanks for the reply. What about `PARTIAL_WAKE_LOCK`? – Dake Jul 27 '16 at 07:23
  • 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](https://developer.android.com/reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK) I think that you don't need this. – Cabezas Jul 27 '16 at 07:34
  • That's what I want if it doesn't "pause" any open app such as a game. – Dake Jul 27 '16 at 07:35
  • I would like turn off the display of my device while mirroring on my TV. – Dake Jul 27 '16 at 07:37
  • You can check this [tutorial.](http://code4reference.com/2012/07/tutorial-on-android-alarmmanager/) – Cabezas Jul 27 '16 at 07:38
  • 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. :) – Dake Jul 27 '16 at 07:46
  • With [PROXIMITY_SCREEN_OFF_WAKE_LOCK](https://developer.android.com/reference/android/os/PowerManager.html#PROXIMITY_SCREEN_OFF_WAKE_LOCK) you can turn off screen. With [PARTIAL_WAKE_LOCK](https://developer.android.com/reference/android/os/PowerManager.html#PARTIAL_WAKE_LOCK) you can wake lock. That's all. – Cabezas Jul 27 '16 at 08:55
  • 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. – Dake Jul 27 '16 at 08:57
  • Did you understand? – Dake Jul 27 '16 at 17:02
  • Sorry... If you gonna turn off the screen without proximity sensor... I don't know how to make. – Cabezas Jul 27 '16 at 17:26
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.

Andrey Starodubtsev
  • 5,139
  • 3
  • 32
  • 46
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

Aleadam
  • 40,203
  • 9
  • 86
  • 108
  • 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. – user496854 Jun 14 '11 at 07:20
  • @user496854 Could you explain how do you use reflection to can use mProximityWakeLock.release(1) ??. Thanks in advance – jegumi Jan 27 '12 at 12:11
  • 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 answer – user496854 Jan 28 '12 at 19:36
  • For anyone wondering as I was, the `1` in `mProximityWakeLock.release(1)` refers to the `PowerManager` flag `RELEASE_WAIT_FOR_NO_PROXIMITY`. (See [docs](https://developer.android.com/reference/android/os/PowerManager#RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY)), which doesn't release the `WakeLock` until the object is no longer close. – Jaween Jul 16 '18 at 06:50
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.

MikO
  • 18,243
  • 12
  • 77
  • 109
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);
Andrei
  • 168
  • 1
  • 8
0

If it is appropriate for your app you can use

getWindow().addFlags(LayoutParams.FLAG_SHOW_WHEN_LOCKED | LayoutParams.FLAG_IGNORE_CHEEK_PRESSES);
Philip Pearl
  • 1,523
  • 16
  • 26