Android亮屏、熄屏的時候會發(fā)出廣播,通常在熄屏廣播中啟動屏保
- 注冊屏幕廣播
/**
* 注冊廣播
*
* @param mContext 上下文環(huán)境
* @param receiver 將要注冊的廣播
*/
public void registerScreenSaverReceiver(Context mContext, ScreenReceiver receiver) {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
mContext.registerReceiver(receiver, filter);
}
在該廣播的Action中有著這樣的注釋:
/**
* Broadcast Action: Sent when the device wakes up and becomes interactive.
* <p>
* For historical reasons, the name of this broadcast action refers to the power
* state of the screen but it is actually sent in response to changes in the
* overall interactive state of the device.
* </p><p>
* This broadcast is sent when the device becomes interactive which may have
* nothing to do with the screen turning on. To determine the
* actual state of the screen, use {@link android.view.Display#getState}.
* </p><p>
* See {@link android.os.PowerManager#isInteractive} for details.
* </p>
* You <em>cannot</em> receive this through components declared in
* manifests, only by explicitly registering for it with
* {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
* Context.registerReceiver()}.
*
* <p class="note">This is a protected intent that can only be sent
* by the system.
*/
這就是說,由于歷史原因,該廣播Action表示屏幕的電信號狀態(tài),但是實際上該廣播是在屏幕不可進行交互時發(fā)出
注:不能通過在Manifest.xml文件注冊的方式接收該廣播,僅僅支持通過代碼registerReceiver(Broadcast ,IntentFilter)的方式進行注冊
在 onReceive(Context context, Intent intent) 方法中進行開啟自定義屏保:
public class ScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//拿到屏幕鎖,亮屏,隨即釋放,否則屏幕就會保持常量
WakeUtil.getInstance().wakeScreenLock();
WakeUtil.getInstance().releaseScreenLock();
//屏蔽系統(tǒng)的屏保
mKeyguardManager = (KeyguardManager) MyApplication.getInstance().getSystemService(Context.KEYGUARD_SERVICE);
mKeyguardLock = mKeyguardManager.newKeyguardLock("ScreenLockService");
mKeyguardLock.disableKeyguard();
//TODO 開啟自定義的屏保;例如:跳轉(zhuǎn)一個Activity,顯示屏保圖片
}
}
- 保持屏幕常量
通常,保持屏幕常量有如下方法:
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
官方注釋:
/** Window flag: as long as this window is visible to the user, keep the device's screen turned on and bright. */
public static final int FLAG_KEEP_SCREEN_ON = 0x00000080;
即當window對用戶可見時,保持屏幕常量。
- 通過PowerManager.WakeLock
mScreenWakeLock = powerManager.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK,
this.getClass().getCanonicalName());
if (!mScreenWakeLock.isHeld()) {
mScreenWakeLock.acquire();
}
對于方法newWakeLock(int levelAndFlags, String tag),下面看看該flag和level分別代表什么意義。
PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_DIM_WAKE_LOCK
/**
* 獲得喚醒鎖時亮屏
* <p>
* 正常情況下,喚醒鎖并不能真正喚醒設(shè)備,一旦屏幕已經(jīng)打開,它們就只能繼續(xù)工作。
* 正如視頻軟件正常工作一樣。
* </p>
*/
public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000;
/**
* 保證亮屏狀態(tài) (可能會變暗);
* 允許關(guān)閉背光
* @deprecated Most applications should use
* {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} instead
* of this type of wake lock, as it will be correctly managed by the platform
* as the user moves between applications and doesn't require a special permission.
*/
@Deprecated
public static final int SCREEN_DIM_WAKE_LOCK = 0x00000006;
可以看出該方法已經(jīng)過時,系統(tǒng)更推薦使用方法1.
3.通過設(shè)置系統(tǒng)進入屏保的時間
try {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, paramInt);
} catch (Exception localException) {
localException.printStackTrace();
}
paramInt代表進入屏?;蜴i屏的時間,單位毫秒ms。這里可設(shè)置為Integer.MAX_VALUE。
同樣可以通過這種方式進行屏幕亮度(0-255)等的設(shè)置:
try {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, paramInt);
} catch (Exception localException) {
localException.printStackTrace();
}
- 進入淺休眠(熄屏狀態(tài)下CPU仍在運行)
mCpuWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getCanonicalName());
synchronized (WakeUtil.class) {
if (!mCpuWakeLock.isHeld()) {
mCpuWakeLock.acquire();
}
}