當前位置:編程學習大全網 - 編程語言 - Android底層是否支持屏保狀態的觸發通知

Android底層是否支持屏保狀態的觸發通知

有壹部分三星的手機關閉屏幕以後,剛打開屏幕,前臺的activity就會resume狀態,因為我們使用cocos2d-x引擎,默認resume和activity的resume事件是壹致的,我們在resume裏把關閉的聲音重新打開,所以導致,用戶點亮屏幕以後(尚未解鎖),就會聽到遊戲內的聲音(如果在關閉屏幕時我們遊戲處於前臺)。

為了解決這個問題,我們需要修改我們resume觸發的時機。確保在解鎖以後才進入我們遊戲的resume狀態。

那麽我們遊戲應該在什麽時機進入resume狀態呢?

系統activity進入resume狀態時刻,並且屏幕是亮的,屏幕未鎖定

屏幕剛剛亮起,並且屏幕 未鎖定,系統activity已經進入resume狀態

屏幕 解鎖,這是屏幕肯定是亮的,並且activity已經進入resume狀態

那麽有了上面的三點相信邏輯代碼不難寫,下面介紹壹下如何堅挺系統屏幕滅,屏幕亮,解鎖屏幕 的事件,以及如何判斷當前屏幕 是否是解鎖狀態(因為用戶可以設置關閉屏幕後是否鎖定屏幕 ,所以解鎖屏幕 事件可能根本就不會被觸發,那麽我們就不能通過跟蹤事件來確定其狀態)

要堅挺屏幕亮、屏幕滅、屏幕 解鎖三個事件我們需要在代碼中註冊監聽ACTION_SCREEN_ON、ACTION_SCREEN_OFF、ACTION_USER_PRESENT三個Action,具體的寫法如下:

[java] view plaincopy

/**

* screen狀態廣播接收者

*/

private class ScreenBroadcastReceiver extends BroadcastReceiver{

@Override

public void onReceive(Context context, Intent intent) {

if(Intent.ACTION_SCREEN_ON.equals(intent.getAction())){

mScreenStateListener.onScreenOn();

}else if(Intent.ACTION_SCREEN_OFF.equals(intent.getAction())){

mScreenStateListener.onScreenOff();

}else if(Intent.ACTION_USER_PRESENT.equals(intent.getAction())){

mScreenStateListener.onUserPresent();

}

}

}

[java] view plaincopy

/**

* 停止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);

filter.addAction(Intent.ACTION_USER_PRESENT);

mContext.registerReceiver(mScreenReceiver, filter);

}

因為屏幕在滅了以後是否鎖定可以由用戶設置,所以我們不能通過跟蹤解鎖事件來判斷其狀態,需要壹個可以時時獲取狀態的函數:

[java] view plaincopy

//判斷屏幕是否被鎖定

public final static boolean isScreenLocked(Context c) {

android.app.KeyguardManager mKeyguardManager = (KeyguardManager) c.getSystemService(c.KEYGUARD_SERVICE);

return mKeyguardManager.inKeyguardRestrictedInputMode();

}

需要註意的是,大部分事件都可以在AndroidManifest.xml中註冊,但是ACTION_SCREEN_ON、ACTION_SCREEN_OFF、ACTION_USER_PRESENT這幾個事件在PowerManager那邊做了限制,必須像上面那樣在代碼中註冊,才能監聽到,所以大家不要踩到坑哦~~~

下面是包裝屏幕事件的壹個類代碼,僅供參考:

[java] view plaincopy

package com.example.myfirstapp;

import java.lang.reflect.Method;

import android.app.Activity;

import android.app.KeyguardManager;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.PowerManager;

import android.util.Log;

/**

* 監聽屏幕ON和OFF PRESENT狀態

*

* @author

* @2014

*

*/

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 (Exception nsme) {

Log.d(TAG, "API < 7," + nsme);

}

}

/**

* screen狀態廣播接收者

*/

private class ScreenBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {

mScreenStateListener.onScreenOn();

} else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {

mScreenStateListener.onScreenOff();

} else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) {

mScreenStateListener.onUserPresent();

}

}

}

/**

* 請求screen狀態更新

*/

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);

filter.addAction(Intent.ACTION_USER_PRESENT);

mContext.registerReceiver(mScreenReceiver, filter);

}

/**

* screen是否打開狀態

*/

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();

public void onUserPresent();

}

public final static boolean isScreenLocked(Context c) {

android.app.KeyguardManager mKeyguardManager = (KeyguardManager) c

.getSystemService(c.KEYGUARD_SERVICE);

return mKeyguardManager.inKeyguardRestrictedInputMode();

}

}

  • 上一篇:為什麽有的遊戲可以做mod,有的不能?
  • 下一篇:疫情期間員工工資怎麽發
  • copyright 2024編程學習大全網