com.achep.acdisplay.ui.fragments.PocketFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.achep.acdisplay.ui.fragments.PocketFragment.java

Source

/*
 * Copyright (C) 2014 AChep@xda <artemchep@gmail.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */
package com.achep.acdisplay.ui.fragments;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;

/**
 * Non-UI fragment that listens to the proximity sensor to let us know
 * when to turn screen off.
 * <p>
 * <b>Please note, that you must
 * {@link #setListener(PocketFragment.OnSleepRequestListener) initialize listener}
 * before attaching fragment!</b>
 * </p>
 *
 * @author Artem Chepurnoy
 * @see #setListener(PocketFragment.OnSleepRequestListener)
 */
public class PocketFragment extends Fragment implements SensorEventListener {

    public static final String TAG = "PocketFragment";

    private static final int SLEEP_DELAY = 1500; // 1.5 sec.
    private static final int MSG_SLEEP = 0;

    private SensorManager mSensorManager;
    private Sensor mProximitySensor;

    private boolean mProximityAvailable;

    private boolean mNear;
    private boolean mFirstChange;
    private float mMaximumRange;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case MSG_SLEEP:
                if (mListener != null) {
                    mListener.onSleepRequest();
                }
                break;
            }
        }
    };

    private OnSleepRequestListener mListener;

    /**
     * Interface definition for a callback to be invoked
     * when device has been put to the pocket.
     */
    public interface OnSleepRequestListener {

        /**
         * Called when parent activity may go to sleep because we're
         * in pocket at this moment.
         */
        boolean onSleepRequest();

    }

    public static PocketFragment newInstance() {
        return new PocketFragment();
    }

    public PocketFragment setListener(OnSleepRequestListener listener) {
        mListener = listener;
        return this;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mSensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
        mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        mProximityAvailable = mProximitySensor != null;

        if (mProximityAvailable) {
            mMaximumRange = mProximitySensor.getMaximumRange();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mProximityAvailable) {
            mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
            mFirstChange = true;
            mNear = false;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        mHandler.removeCallbacksAndMessages(null);
        mSensorManager.unregisterListener(this);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mSensorManager = null;
        mProximitySensor = null;
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        final float distance = event.values[0];
        final boolean isNear = distance < mMaximumRange || distance < 1.0f;
        final boolean changed = mNear != (mNear = isNear) || mFirstChange;

        if (!changed) {
            // Well just in cause if proximity sensor is NOT always eventual.
            // This should not happen, but who knows... I found maximum
            // range buggy enough.
            return;
        }

        mHandler.removeCallbacksAndMessages(null);

        if (!isNear) {
            return;
        }

        mHandler.sendEmptyMessageDelayed(MSG_SLEEP, SLEEP_DELAY);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
        /* unused */ }
}