一、概述
手机管家或者电池管理中,常常有省电模式的功能切换,其功能主要是对机器上的硬件开关进行控制,其中涉及我们经常看到的屏幕亮度,GPS,BT,数据流量等开关的控制,再细节一些还可以进行CPU核数和频率的控制,本文主要介绍一些控制开关的接口。
二、省电模式内容
三、具体软件接口
休眠时长控制
public static int getScreenOffTimeOut(Context context) {
return Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_OFF_TIMEOUT, PowerSaveManagerContant.mPowerSaveScreenOffTimeoutValue);
}
public static void setScreenOffTimeOut(Context context, int value) {
Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_OFF_TIMEOUT, value);
}
屏幕亮度控制
public static int getBrightnessValue(Context context) {
return Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, PowerSaveManagerContant.mPowerSaveBrightnessValue);
}
/**
* Used by the settings application and brightness control widgets to
* temporarily override the current screen brightness setting so that the
* user can observe the effect of an intended settings change without
* applying it immediately.
* <p/>
* The override will be canceled when the setting value is next updated.
*
* @param brightness The overridden brightness.
* @see android.provider.Settings.System#SCREEN_BRIGHTNESS
*/
public static void setBrightnessValue(Context mContext, int value) {
try {
IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE));
if (power != null) {
power.setTemporaryScreenBrightnessSettingOverride(value);
}
} catch (RemoteException doe) {
Log.w(TAG, doe);
}
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, value);
}
自动亮度控制
public static int getBrightnessMode(Context context) {
return Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
}
public static void setBrightnessMode(final Context mContext, final int mode) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(680);
} catch (Exception e) {
// TODO: handle exception
}
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_MODE, mode);
}
}).start();
}
蓝牙控制
/**
* Get the current state of the local Bluetooth adapter.
* <p/>
* Possible return values are {@link #STATE_OFF}, {@link #STATE_TURNING_ON},
* {@link #STATE_ON}, {@link #STATE_TURNING_OFF}.
* <p/>
* Requires {@link android.Manifest.permission#BLUETOOTH}
*
* @return current state of Bluetooth adapter
*/
public static boolean isBlueToothOpened() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
int state = mBluetoothAdapter.getState();
return (state == BluetoothAdapter.STATE_TURNING_ON || state == BluetoothAdapter.STATE_ON);
}
private static boolean isBluetoothHeadsetConnected = false;
private static boolean isBluetoothProfileConnected = false;
private static boolean isBluetoothInputDeviceConnected = false;
class InteractiveStateReceiver extends BroadcastReceiver {
public InteractiveStateReceiver() {
IntentFilter filter = new IntentFilter();
// Requires {@link android.Manifest.permission#BLUETOOTH} to receive
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(this, filter);
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null)
return;
String action = intent.getAction();
if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothProfile.STATE_CONNECTED) {
isBluetoothHeadsetConnected = true;
} else if (state == BluetoothProfile.STATE_DISCONNECTED) {
isBluetoothHeadsetConnected = false;
}
Log.d(TAG, TAG + "!!!! BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED state : " + isBluetoothHeadsetConnected);
} else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothProfile.STATE_CONNECTED) {
isBluetoothProfileConnected = true;
} else if (state == BluetoothProfile.STATE_DISCONNECTED) {
isBluetoothProfileConnected = false;
}
Log.d(TAG, TAG + "!!!! BluetoothProfile.ACTION_CONNECTION_STATE_CHANGED state : " + isBluetoothProfileConnected);
} else if (BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothProfile.STATE_CONNECTED) {
isBluetoothInputDeviceConnected = true;
} else if (state == BluetoothProfile.STATE_DISCONNECTED) {
isBluetoothInputDeviceConnected = false;
}
Log.d(TAG, TAG + "!!!! BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED state : " + isBluetoothInputDeviceConnected);
} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_ON && isLavaSuperPowerSave && PowerSaveManagerContant.mSuperPowerSaveCloseBt) {
setBlueToothEnable(false);
Log.d(TAG, TAG + "!!!! close Bluetooth by super power mode");
}
} else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
if (wifiState == WifiManager.WIFI_STATE_ENABLED && isLavaSuperPowerSave && PowerSaveManagerContant.mSuperPowerSaveCloseWifi) {
setWiFiEnable(mContext, false);
Log.d(TAG, TAG + "!!!! close Wi-Fi by super power mode");
}
}
}
}
/**
* Get the current connection state of the local Bluetooth adapter. This can
* be used to check whether the local Bluetooth adapter is connected to any
* profile of any other remote Bluetooth Device.
* <p/>
* <p/>
* Use this function along with {@link #ACTION_CONNECTION_STATE_CHANGED}
* intent to get the connection state of the adapter.
*
* @return One of {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTED},
* {@link #STATE_CONNECTING} or {@link #STATE_DISCONNECTED}
*/
public static boolean isBlueToothConnected() {
/*
* BluetoothAdapter mBluetoothAdapter =
* BluetoothAdapter.getDefaultAdapter(); int state =
* mBluetoothAdapter.getConnectionState(); Log.d(TAG,
* "isBlueToothStateConnect state = " + state); return (state ==
* BluetoothAdapter.STATE_CONNECTED || state ==
* BluetoothAdapter.STATE_CONNECTING);
*/
return isBluetoothHeadsetConnected || isBluetoothProfileConnected || isBluetoothInputDeviceConnected;
}
/**
* Turn off the local Bluetooth adapter—do not use without explicit
* user action to turn off Bluetooth.
* <p>
* This gracefully shuts down all Bluetooth connections, stops Bluetooth
* system services, and powers down the underlying Bluetooth hardware.
* <p class="caution">
* <strong>Bluetooth should never be disabled without direct user
* consent</strong>. The {@link #disable()} method is provided only for
* applications that include a user interface for changing system settings,
* such as a "power manager" app.
* </p>
* <p/>
* This is an asynchronous call: it will return immediately, and clients
* should listen for {@link #ACTION_STATE_CHANGED} to be notified of
* subsequent adapter state changes. If this call returns true, then the
* adapter state will immediately transition from {@link #STATE_ON} to
* {@link #STATE_TURNING_OFF}, and some time later transition to either
* {@link #STATE_OFF} or {@link #STATE_ON}. If this call returns false then
* there was an immediate problem that will prevent the adapter from being
* turned off - such as the adapter already being turned off.
* <p/>
* Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
* permission
*
* @return true to indicate adapter shutdown has begun, or false on
* immediate error
*/
public static void setBlueToothEnable(boolean value) {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (value) {
mBluetoothAdapter.enable();
} else {
mBluetoothAdapter.disable();
}
}
WiFi控制
/**
* Gets the Wi-Fi enabled state.
*
* @return One of {@link #WIFI_STATE_DISABLED},
* {@link #WIFI_STATE_DISABLING}, {@link #WIFI_STATE_ENABLED},
* {@link #WIFI_STATE_ENABLING}, {@link #WIFI_STATE_UNKNOWN}
* @see #isWifiEnabled()
*/
public static boolean isWiFiOpened(Context mContext) {
WifiManager mWifiManager = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE));
int state = mWifiManager.getWifiState();
return (state == WifiManager.WIFI_STATE_ENABLED || state == WifiManager.WIFI_STATE_ENABLING);
}
public static boolean isWiFiConnected(Context mContext) {
ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifiNetworkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
return wifiNetworkInfo.isConnected();
}
/**
* Enable or disable Wi-Fi.
*
* @param enabled {@code true} to enable, {@code false} to disable.
* @return {@code true} if the operation succeeds (or if the existing state
* is the same as the requested state).
*/
public static void setWiFiEnable(Context mContext, boolean value) {
WifiManager mWifiManager = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE));
mWifiManager.setWifiEnabled(value);
}
WiFi Ap控制
/**
* Gets the Wi-Fi enabled state.
*
* @return One of {@link #WIFI_AP_STATE_DISABLED},
* {@link #WIFI_AP_STATE_DISABLING}, {@link #WIFI_AP_STATE_ENABLED},
* {@link #WIFI_AP_STATE_ENABLING}, {@link #WIFI_AP_STATE_FAILED}
* @see #isWifiApEnabled()
*/
public static boolean isWiFiApOpened(Context mContext) {
WifiManager mWifiManager = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE));
int state = mWifiManager.getWifiApState();
return (state == WifiManager.WIFI_AP_STATE_ENABLING || state == WifiManager.WIFI_AP_STATE_ENABLED);
}
/**
* Start AccessPoint mode with the specified configuration. If the radio is
* already running in AP mode, update the new configuration Note that
* starting in access point mode disables station mode operation
*
* @param wifiConfig SSID, security and channel details as part of
* WifiConfiguration
* @return {@code true} if the operation succeeds, {@code false} otherwise
*/
public static void setWiFiApEnable(Context mContext, boolean value) {
WifiManager mWifiManager = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE));
mWifiManager.setWifiApEnabled(null, value);
}
GPRS 数据流量开关控制
public static boolean isGprsOpened(Context mContext) {
TelephonyManager mTelephonyManager = TelephonyManager.from(mContext);
return mTelephonyManager.getDataEnabled();
}
public static void setGprsEnable(Context mContext, boolean value) {
TelephonyManager mTelephonyManager = TelephonyManager.from(mContext);
mTelephonyManager.setDataEnabled(value);
}
Google自动更新服务控制
/**
* Gets the master auto-sync setting that applies to all the providers and
* accounts. If this is false then the per-provider auto-sync setting is
* ignored.
* <p/>
* This method requires the caller to hold the permission
* {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
*
* @return the master auto-sync setting that applies to all the providers
* and accounts
*/
public static boolean isSyncAutoOpened() {
return ContentResolver.getMasterSyncAutomatically();
}
/**
* Sets the master auto-sync setting that applies to all the providers and
* accounts. If this is false then the per-provider auto-sync setting is
* ignored.
* <p/>
* This method requires the caller to hold the permission
* {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
*
* @param sync the master auto-sync setting that applies to all the providers
* and accounts
*/
public static void setSyncAutoEnable(boolean value) {
ContentResolver.setMasterSyncAutomatically(value);
}
GPS开关控制
public static boolean isGpsOpen(Context mContext) {
return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) != Settings.Secure.LOCATION_MODE_OFF;
}
public static int getGpsMode(Context mContext) {
return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
}
/**
* The degree of location access enabled by the user.
* <p/>
* When used with {@link #putInt(ContentResolver, String, int)}, must be one
* of {@link #LOCATION_MODE_HIGH_ACCURACY},
* {@link #LOCATION_MODE_SENSORS_ONLY},
* {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}.
* When used with {@link #getInt(ContentResolver, String)}, the caller must
* gracefully handle additional location modes that might be added in the
* future.
* <p/>
* Note: do not rely on this value being present in settings.db or on
* ContentObserver notifications for the corresponding Uri. Use
* {@link LocationManager#MODE_CHANGED_ACTION} to receive changes in this
* value.
*/
public static void setGpsEnable(Context mContext, int value) {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCATION_MODE, value);
}
屏保开关控制
public static boolean isScreenSaverOpen(Context mContext) {
return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.SCREENSAVER_ENABLED, 0) == 1;
}
/**
* Whether screensavers are enabled.
* <p/>
* SCREENSAVER_ENABLED = "screensaver_enabled"
*/
public static void setScreenSaverEnable(Context mContext, boolean value) {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SCREENSAVER_ENABLED, value ? 1 : 0);
}
自动旋转控制
/**
* Returns true if rotation lock is enabled.
*/
public static boolean isRotationLockedOpen(Context mContext) {
return !RotationPolicy.isRotationLocked(mContext);
}
/**
* Enables or disables rotation lock from the system UI toggle.
*/
public static void setRotationLockeEnable(Context mContext, boolean value) {
RotationPolicy.setRotationLock(mContext, !value);
}
振动开关控制
/**
* Whether the haptic feedback (long presses, ...) are enabled. The value is
* boolean (1 or 0).
* <p/>
* HAPTIC_FEEDBACK_ENABLED = "haptic_feedback_enabled";
*/
public static boolean isVibrateOnTouchOpen(Context mContext) {
return Settings.System.getInt(mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 1;
}
public static void setVibrateOnTouchEnable(Context mContext, boolean value) {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, value ? 1 : 0);
}
双击相机手势开关控制
/**
* Whether the camera launch gesture to double tap the power button when the
* screen is off should be disabled.
* <p/>
* import static android.provider.Settings.Secure.
* CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED;
*/
public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED = "camera_double_tap_power_gesture_disabled";
public static boolean isCameraDoubleTapPowerGestureDisabledOpen(Context mContext) {
return Settings.Secure.getInt(mContext.getContentResolver(), CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, 0) == 0;
}
public static void setCameraDoubleTapPowerGestureDisabledEnable(Context mContext, boolean value) {
Settings.Secure.putInt(mContext.getContentResolver(), CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED, value ? 0 : 1);
}
通知栏显示控制
/**
* This preference enables notification display on the lockscreen.
*/
public static boolean isLockScreenShowNotificationOpen(Context mContext) {
return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) == 1;
}
public static void setLockScreenShowNotificationEnable(Context mContext, boolean value) {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, value ? 1 : 0);
}
禁用下拉状态栏控制
/**
* Disable some features in the status bar. Pass the bitwise-or of the
* DISABLE_* flags. To re-enable everything, pass {@link #DISABLE_NONE}.
*/
public static void setStatusBarExpandEnable(Context mContext, boolean value) {
StatusBarManager mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
if (value) {
mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
} else {
mStatusBarManager.collapsePanels();
mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
}
}
Google省电模式控制
public static boolean isGooglePowerSaveMode(Context mContext) {
PowerManager mPowerManager = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE));
return mPowerManager.isPowerSaveMode();
}
/**
* android.Manifest.permission.DEVICE_POWER
*
* @param mContext
* @param value
*/
public static void setGooglePowerSaveMode(Context mContext, boolean value) {
PowerManager mPowerManager = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE));
mPowerManager.setPowerSaveMode(value);
}
小结
省电模式中屏幕亮度调节和网络开关控制起到的效果最为明显,在此基础上可以新增查杀后台应用的动作,其中CPU调频MTK平台和高通平台存在差异。具体控制细节根据产品和开发共同制定,作为一个场景式省电用途,一键切换省电延迟使用时间。