nowindxdw
11/2/2017 - 7:08 AM

屏幕在三种状态(开屏、锁屏、解锁)之间变换

接收系统广播事件,屏幕在三种状态(开屏、锁屏、解锁)之间变换的时候,系统都会发送广播,我们只需要监听这些广播即可。
代码如下:

 

?
 
        private 
        ScreenBroadcastReceiver mScreenReceiver; 
       
 
        private 
        class 
        ScreenBroadcastReceiver  
        extends 
        BroadcastReceiver { 
       
 
             
        private 
        String action =  
        null 
        ; 
       

           
       

           
       
 
             
        @Override 
       
 
             
        public 
        void 
        onReceive(Context context, Intent intent) { 
       
 
                 
        action = intent.getAction(); 
       
 
                 
        if 
        (Intent.ACTION_SCREEN_ON.equals(action)) {            
       
 
                     
        // 开屏 
       
 
                 
        }  
        else 
        if 
        (Intent.ACTION_SCREEN_OFF.equals(action)) {  
       
 
                     
        // 锁屏 
       
 
                 
        }  
        else 
        if 
        (Intent.ACTION_USER_PRESENT.equals(action)) {  
       
 
                     
        // 解锁 
       
 
                 
        } 
       
 
             
        } 
       
 
        } 
       
 
        private 
        void 
        startScreenBroadcastReceiver() { 
       
 
             
        IntentFilter filter =  
        new 
        IntentFilter(); 
       
 
             
        filter.addAction(Intent.ACTION_SCREEN_ON); 
       
 
             
        filter.addAction(Intent.ACTION_SCREEN_OFF); 
       
 
             
        filter.addAction(Intent.ACTION_USER_PRESENT); 
       
 
             
        context.registerReceiver(mScreenReceiver, filter); 
       
 
        } 
       
 
        
 
       
 
        
 
       
 
        
 
       
 
        
 
       
 
        
 
       
 
         
         
public class ScreenListener {
    private Context mContext;
    private ScreenBroadcastReceiver mScreenReceiver;
    private ScreenStateListener mScreenStateListener;

    public ScreenListener(Context context) {
        mContext = context;
        mScreenReceiver = new ScreenBroadcastReceiver();
    }

    /** * screen状态广播接收者 */
    private class ScreenBroadcastReceiver extends BroadcastReceiver {
        private String action = null;

        @Override
        public void onReceive(Context context, Intent intent) {
            action = intent.getAction();
            if (Intent.ACTION_SCREEN_ON.equals(action)) { // 开屏
                mScreenStateListener.onScreenOn();
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // 锁屏
                mScreenStateListener.onScreenOff();
            } else if (Intent.ACTION_USER_PRESENT.equals(action)) { // 解锁
                mScreenStateListener.onUserPresent();
            }
        }
    }

    /** * 开始监听screen状态 * * @param listener */
    public void begin(ScreenStateListener listener) {
        mScreenStateListener = listener;
        registerListener();
        getScreenState();
    }

    /** * 获取screen状态 */
    private void getScreenState() {
        PowerManager manager = (PowerManager) mContext
                .getSystemService(Context.POWER_SERVICE);
        if (manager.isScreenOn()) {
            if (mScreenStateListener != null) {
                mScreenStateListener.onScreenOn();
            }
        } else {
            if (mScreenStateListener != null) {
                mScreenStateListener.onScreenOff();
            }
        }
    }

    /** * 停止screen状态监听 */
    public void unregisterListener() {
        mContext.unregisterReceiver(mScreenReceiver);
    }

    /** * 启动screen状态广播接收器 */
    private void registerListener() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_USER_PRESENT);
        mContext.registerReceiver(mScreenReceiver, filter);
    }

    public interface ScreenStateListener {// 返回给调用者屏幕状态信息
        public void onScreenOn();

        public void onScreenOff();

        public void onUserPresent();
    }
}
在上面的代码中,用到了动态注册广播,在需要监听屏幕状态的activity中,当不需要监听的时候,如activity finish的时候,使用unregisterListener解除广播监听; 
下面是在Activity中调用;

 
         
ScreenListener l = new ScreenListener(this);
        l.begin(new ScreenStateListener() {

            @Override
            public void onUserPresent() {
                Log.e("onUserPresent", "onUserPresent");
            }

            @Override
            public void onScreenOn() {
                Log.e("onScreenOn", "onScreenOn");
            }

            @Override
            public void onScreenOff() {
                Log.e("onScreenOff", "onScreenOff");
            }
        });


通过反射机制在屏幕状态发生改变之前就想获取屏幕状态,可以通过反射机制调用PowerManager的isScreenOn方法 。
具体实现,见代码:
实现Screen状态监听的类ScreenObserver,实现如下:
[java]  view plain copy 
package com.isoft.screen;  
  
import java.lang.reflect.Method;  
  
import android.app.Activity;  
import android.content.BroadcastReceiver;  
import android.content.Context;  
import android.content.Intent;  
import android.content.IntentFilter;  
import android.os.PowerManager;  
import android.util.Log;  
  
/** 
 *  
 * @author zhangyg 
 * 
 */  
public class ScreenObserver{  
    private static String TAG = "ScreenObserver";  
    private Context mContext;  
    private ScreenBroadcastReceiver mScreenReceiver;  
    private ScreenStateListener mScreenStateListener;  
    private static Method mReflectScreenState;  
      
    public ScreenObserver(Context context){  
        mContext = context;  
        mScreenReceiver = new ScreenBroadcastReceiver();  
        try {  
            mReflectScreenState = PowerManager.class.getMethod("isScreenOn",  
                    new Class[] {});  
        } catch (NoSuchMethodException nsme) {  
            Log.d(TAG, "API < 7," + nsme);  
        }  
    }  
      
    /** 
     * screen状态广播接收者 
     * @author zhangyg 
     * 
     */  
    private class ScreenBroadcastReceiver extends BroadcastReceiver{  
        private String action = null;  
        @Override  
        public void onReceive(Context context, Intent intent) {  
            action = intent.getAction();  
            if(Intent.ACTION_SCREEN_ON.equals(action)){  
                mScreenStateListener.onScreenOn();  
            }else if(Intent.ACTION_SCREEN_OFF.equals(action)){  
                mScreenStateListener.onScreenOff();  
            }  
        }  
    }  
      
      
    /** 
     * 请求screen状态更新 
     * @param listener 
     */  
    public void requestScreenStateUpdate(ScreenStateListener listener) {  
        mScreenStateListener = listener;  
        startScreenBroadcastReceiver();  
          
        firstGetScreenState();  
    }  
      
    /** 
     * 第一次请求screen状态 
     */  
    private void firstGetScreenState(){  
        PowerManager manager = (PowerManager) mContext  
                .getSystemService(Activity.POWER_SERVICE);  
        if (isScreenOn(manager)) {  
            if (mScreenStateListener != null) {  
                mScreenStateListener.onScreenOn();  
            }  
        } else {  
            if (mScreenStateListener != null) {  
                mScreenStateListener.onScreenOff();  
            }  
        }  
    }  
      
    /** 
     * 停止screen状态更新 
     */  
    public void stopScreenStateUpdate(){  
        mContext.unregisterReceiver(mScreenReceiver);  
    }  
      
    /** 
     * 启动screen状态广播接收器 
     */  
    private void startScreenBroadcastReceiver(){  
        IntentFilter filter = new IntentFilter();  
        filter.addAction(Intent.ACTION_SCREEN_ON);  
        filter.addAction(Intent.ACTION_SCREEN_OFF);  
        mContext.registerReceiver(mScreenReceiver, filter);  
    }  
      
    /** 
     * screen是否打开状态 
     * @param pm 
     * @return 
     */  
    private static boolean isScreenOn(PowerManager pm) {  
        boolean screenState;  
        try {  
            screenState = (Boolean) mReflectScreenState.invoke(pm);  
        } catch (Exception e) {  
            screenState = false;  
        }  
        return screenState;  
    }  
      
    public interface ScreenStateListener {  
        public void onScreenOn();  
        public void onScreenOff();  
    }  
}  

测试ScreenObserver功能的示例类ScreenObserverActivity,实现如下:
[java]  view plain copy 
package com.isoft.screen;  
  
import android.app.Activity;  
import android.os.Bundle;  
import android.util.Log;  
  
import com.isoft.screen.ScreenObserver.ScreenStateListener;  
  
public class ScreenObserverActivity extends Activity {  
    private String TAG = "ScreenObserverActivity";  
    private ScreenObserver mScreenObserver;  
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
  
        mScreenObserver = new ScreenObserver(this);  
        mScreenObserver.requestScreenStateUpdate(new ScreenStateListener() {  
            @Override  
            public void onScreenOn() {  
                doSomethingOnScreenOn();  
            }  
  
            @Override  
            public void onScreenOff() {  
                doSomethingOnScreenOff();  
            }  
        });  
    }  
  
    private void doSomethingOnScreenOn() {  
        Log.i(TAG, "Screen is on");  
    }  
  
    private void doSomethingOnScreenOff() {  
        Log.i(TAG, "Screen is off");  
    }  
      
    @Override  
    protected void onDestroy() {  
        super.onDestroy();  
        //停止监听screen状态  
        mScreenObserver.stopScreenStateUpdate();  
    }  
}