27

My app is a dialer and when user holding the phone near his head I need to turn screen off and prevent clicking on the controls - like native Android dialer behavior. What API level I need and how can I do this in right way?

Solkin
  • 906
  • 1
  • 9
  • 16
  • 2
    Possible duplicate of [android: turn off screen when close to face](http://stackoverflow.com/questions/3018716/android-turn-off-screen-when-close-to-face) – kotucz Feb 16 '16 at 15:35

4 Answers4

52

I found solution by disassembling one very famous VoIP application. This activity after pressing button1 will disable screen and hardware keys when you close sensors. After pressing button2 this function will be switched off.

Also, this function required permission:

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

Activity. Try it.

public class MainActivity extends Activity {

    private Button button1;
    private Button button2;
    private PowerManager powerManager;
    private PowerManager.WakeLock wakeLock;
    private int field = 0x00000020;

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

        try {
            // Yeah, this is hidden field.
            field = PowerManager.class.getClass().getField("PROXIMITY_SCREEN_OFF_WAKE_LOCK").getInt(null);
        } catch (Throwable ignored) {
        }

        powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(field, getLocalClassName());

        setContentView(R.layout.main);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);

        button1.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(!wakeLock.isHeld()) {
                    wakeLock.acquire();
                }
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if(wakeLock.isHeld()) {
                    wakeLock.release();
                }
            }
        });
    }
}
Solkin
  • 906
  • 1
  • 9
  • 16
3

The following code shows you how to use the proximity sensor:

public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mProximity;

 @Override
 public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Get an instance of the sensor service, and use that to get an instance of
// a particular sensor.
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
 }

 @Override
 public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
 }

 @Override
  public final void onSensorChanged(SensorEvent event) {
   float distance = event.values[0];
// Do something with this sensor data.
   }

 @Override
 protected void onResume() {
// Register a listener for the sensor.
super.onResume();
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
 }

 @Override
  protected void onPause() {
// Be sure to unregister the sensor when the activity pauses.
super.onPause();
mSensorManager.unregisterListener(this);
 }}

try this link for the use of Proximity Sensor while Face is close to screen turn off the screen.

Hope this Helps you.

i.n.e.f
  • 1,773
  • 13
  • 22
  • 1
    Yes, this will send me lots of events, but have no idea, how to turn screen off... In the answer by the link used only private Android API. – Solkin Feb 19 '14 at 15:27
  • I don't see what the OP would want the accelerometer for. He's more likely to be interested in events from [the proximity sensor](http://developer.android.com/guide/topics/sensors/sensors_position.html#sensors-pos-prox). – Michael Feb 19 '14 at 15:39
  • as Suggested by Michael use Proximity Sensor.Proximity Sensor will turn OFF screen when Any Object is near to the Screen. For Ex: while Calling/Dialling any call when we keep device near to the Face the Screen display turn OFF. So @Solkin What you want will get through proximity Sensor. by this link http://developer.android.com/guide/topics/sensors/sensors_position.html#sensors-pos-prox – i.n.e.f Feb 20 '14 at 07:52
  • 1
    Thanks, but... This is only sensors listener. But I need to disable screen. – Solkin Feb 20 '14 at 14:46
  • check this link http://stackoverflow.com/questions/9561320/android-how-to-turn-screen-on-and-off-programmatically in that check answer posted by @hackbod & try this code `params.flags |= LayoutParams.FLAG_KEEP_SCREEN_OFF; params.screenBrightness = 0; getWindow().setAttributes(params)` hope this helps. – i.n.e.f Feb 20 '14 at 15:04
  • 1
    @i.n.e.f,thereis no `FLAG_KEEP_SCREEN_OFF` – suitianshi Dec 23 '15 at 02:44
  • Good job. and try it: if (distance > 0){ fake_frame_layout.setVisibility(View.GONE); }else{ fake_frame_layout.setVisibility(View.VISIBLE); } – serif Oct 23 '22 at 14:56
2

There are lot of devices where the CPU usage goes high if you try the method posted by Solkin (using the wakelock). This is a bug in android devices.

You should use the onSensorChanged event and just display a black screen to avoid any issues.

  • 1
    "just display a black screen to avoid any issues"? you mean, aside from all the new issues caused by the fact that the screen is actually *still on*? – Michael Jan 18 '19 at 18:46
0

The best way is to use DialogFragment، you show a black screen and dismiss that

@Override
  public final void onSensorChanged(SensorEvent event) {
   float distance = event.values[0];
     if(distance <10f)
    showDialogFragment()
     else
    hideDialogFragment()

   }
AmirMohamamd
  • 301
  • 3
  • 14
  • In this case user will touch screen, incoming notifications, etc. That's why you must turn screen off while calling. – Solkin Apr 23 '21 at 08:45