天天看點

Android定義亮屏、滅屏、鎖屏、退出應用監聽器

有的時候我們的項目需要監聽手機亮屏滅屏鎖屏等狀态,來做一些自己的事,比如解鎖後要求使用者輸入app密碼等。 由于螢幕狀态變化時,系統會發出對應的廣播,這時候我們可以定義一個監聽器來接收廣播,然後做一些對應的事。 我們需要首先建立一個類ScreenListener,然後在這個class裡面定義一個接口ScreenStateListener,接口裡面寫亮屏、滅屏、解鎖、退出應用時的操作:

public class ScreenListener {

    ......

    public interface ScreenStateListener {
        public void onScreenOn();

        public void onScreenoff();

        public void onUserPrisent();

        public void exitAPP();
    }

           

為了調用這個接口裡面的方法,需要有這個接口的實作類的對象ScreenStateListener stateListener,當接收到廣播後通過這個stateListener來調用onScreenOn()、onScreenoff()、onUserPrisent()、exitAPP()方法。由于我們需要在這些方法中使用和處理activity中的變量等,

是以stateListener一定是在activity中建立的,然後需要通過listener的構造方法或者其他方法把這個實作類對象傳遞過來。

為了接收到系統的廣播,我們需要在ScreenListener.class裡面寫一個内部類classScreenBroadcastReceiverextendsBroadcastReceiver來接收廣播,并重寫其中的onReceive方法:

/*
    * Screen狀态廣播接收者
    * */
    private class ScreenBroadcastReceiver extends BroadcastReceiver {
        private String action;

        /*
        * 當接收到廣播時将會運作這個方法
        * */
        @Override
        public void onReceive(Context context, Intent intent) {

            action = intent.getAction();
            switch (action) {
                case Intent.ACTION_SCREEN_ON:   //開屏
                    stateListener.onScreenOn();
                    break;
                case Intent.ACTION_SCREEN_OFF:  //鎖屏
                    stateListener.onScreenoff();
                    break;
                case Intent.ACTION_USER_PRESENT:    //解鎖
                    stateListener.onUserPrisent();
                    break;
                case "ExitAPP":         //退出APP
                    stateListener.exitAPP();
                    break;
            }
        }
    }
           

既然用到了廣播,那麼就涉及到了注冊和反注冊廣播,是以我們需要寫這樣兩個方法:registListener()、unregistListener()。當需要監聽廣播時,我們就就注冊監聽器,當不需要監聽時我們就反注冊。這兩個方法中分别對廣播進行注冊registerReceiver和反注冊unregisterReceiver,由于注冊和反注冊廣播都是Context的方法,是以我們還要在建立screenBroadcastReceiver的時候傳入activity的Context。

傳遞stateListener對象的方法我是寫了一個begin(ScreenStateListenerstateListener)方法,調用此方法開始監聽(注冊廣播)。

好了,基本的思路已經說完了,那麼下面我将會給出這個Listener的全部代碼:

/**
 * Created by 泥巴城  on 2016/11/21.
 * 監聽螢幕亮,滅,解鎖
 */

public class ScreenListener {
    private Context context;
    private ScreenBroadcastReceiver screenBroadcastReceiver;
    private ScreenStateListener stateListener;

    public ScreenListener(Context context) {
        this.context = context;
        screenBroadcastReceiver = new ScreenBroadcastReceiver();
    }

    /*
    * Screen狀态廣播接收者
    * */
    private class ScreenBroadcastReceiver extends BroadcastReceiver {
        private String action;

        /*
        * 當接收到廣播時将會運作這個方法
        * */
        @Override
        public void onReceive(Context context, Intent intent) {

            action = intent.getAction();
            switch (action) {
                case Intent.ACTION_SCREEN_ON:   //開屏
                    stateListener.onScreenOn();
                    break;
                case Intent.ACTION_SCREEN_OFF:  //鎖屏
                    stateListener.onScreenoff();
                    break;
                case Intent.ACTION_USER_PRESENT:    //解鎖
                    stateListener.onUserPrisent();
                    break;
                case "ExitAPP":         //退出APP
                    stateListener.exitAPP();
                    break;
            }
        }
    }

    /*
    * 啟動screen狀态廣播接收器
    * */
    private void registListener() {
        IntentFilter filter = new IntentFilter();   //filter将會設定監聽的地點,當有操作就會發出廣播
        filter.addAction("ExitAPP");
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        context.registerReceiver(screenBroadcastReceiver, filter);
    }

    /*
    * 當不需要監聽螢幕時,使用此方法可以解除綁定
    * */
    public void unregistListener() {
        context.unregisterReceiver(screenBroadcastReceiver);
    }

    /*
    * 擷取螢幕狀态并直接運作該狀态下的操作
    * */
    private void getScreenState() {
        PowerManager manager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (manager.isScreenOn()) {
            if (stateListener != null) {
                stateListener.onScreenOn();
            }
        } else {
            if (stateListener != null) {
                stateListener.onScreenoff();
            }
        }

    }

    /*
    * 直接使用類2的對象調用此函數,開始監聽螢幕
    * */
    public void begin(ScreenStateListener stateListener) {
        this.stateListener = stateListener;
        registListener();
        getScreenState();
    }

    /*
    * 提供給使用者,用來設定螢幕解鎖,鎖屏的操作
    * */
    public interface ScreenStateListener {
        public void onScreenOn();

        public void onScreenoff();

        public void onUserPrisent();

        public void exitAPP();
    }
}
           

監聽器寫好了,那麼activity怎麼用呢?下面給出代碼:

在activity的OnCreate方法中寫一下代碼:

//監聽鎖屏狀态 和 退出程式信号
        ScreenListener listener = new ScreenListener(context);
        listener.begin(new ScreenListener.ScreenStateListener() {
            @Override
            public void onScreenOn() {

            }

            @Override
            public void onScreenoff() {

            }

            @Override
            public void onUserPrisent() {
                if (useWhat != 0) {

                    Intent intent = new Intent();
                    switch (useWhat) {

                        case 1:
                            intent.setClass(context, DLockActivity.class);
                            break;
                        case 2:
                            intent.setClass(context, PLockActivity.class);
                            break;
                        case 3:
                            intent.setClass(context, DIYLockActivity.class);
                            break;
                    }
                    intent.putExtra("flag", "openScreen");
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(intent);
                }
            }

            @Override
            public void exitAPP() {
                finish();
            }
        });

    }
           

這樣,activity就開始監聽螢幕了,當螢幕有相應的廣播發出來的時候,我們就能監聽到。而且,我相信大家已經注意到了ExitAPP這個廣播,這是自定義的一個廣播,當我們需要退出應用的時候,我們隻需要調用以下代碼,就可以讓所有監聽螢幕的activity銷毀,以達到退出應用的目的:

getApplicationContext().sendBroadcast(newIntent("ExitAPP"));

最後提醒大家,為了節約寶貴的資源,不要忘記在onDestory方法中反注冊監聽器哦!!