Java、Kotlin圣战之:安卓如何判断省电模式?

1,341 阅读2分钟

有的时候,需要判断是否激活了省电模式,如果是,那么有自定义动画的可以削减特效,要保活的则需要更加激进的保活手段。有标准API,isPowerSaveMode :

PowerManager powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
powerManager.isPowerSaveMode()

但一些机型,比如华为,小米并未适配此接口,总是返回False。不过可以通过反射SystemProperties、Settings.System.getInt 获取内部的省电模式标识。

参考我在stackoverflow网站上的一篇回答:

stackoverflow.com/questions/4…

Settings.System.getInt方法是在SO的其他答案中找到的。原理是省电模式下,华为的SmartModeStatus为4,正常为1;小米省电模式则POWER_SAVE_MODE_OPEN为1。

不过经过实际测试,华为除了普通省电模式外,还存在超级省电模式(ultra power saving mode),此模式下,SmartModeStatus也为1,上述判断就会失效。于是结合github上别人上传的华为AOSP框架代码,我自行摸索出了反射SystemProperties的方法,原理是超级省电模式下sys.super_power_save为true。

	final int _HX =  Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")?2
			:Build.MANUFACTURER.equalsIgnoreCase("Huawei")?1
			:0;
	private boolean isPowerSaveModeCompat(){
		if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
				&& powerManager.isPowerSaveMode()) { // hopefully...
			return true;
		}
		if (_HX==0) {
			return false;
		}
		else if (_HX==1) {
			try {
				int value = Settings.System.getInt(getContentResolver(), "SmartModeStatus");
				//CMN.debug("isPowerSaveModeCompat::huawei::", value);
				if(value==4) {
					return true;
				}
				if(value==1) { // test Ultra save mode???
					return "true".equals(getSystemProperty("sys.super_power_save"));
				}
			} catch (Exception e) {
				//CMN.debug(e);
			}
		}
		else if (_HX==2){
			try {
				int value = Settings.System.getInt(getContentResolver(), "POWER_SAVE_MODE_OPEN");
				//CMN.debug("isPowerSaveModeCompat::xiaomi::", value);
				return value==1;
			} catch (Exception e) {
				//CMN.debug(e);
			}
		}
		// else if...
		return false;
	}
	
	// https://stackoverflow.com/questions/9937099/how-to-get-the-build-prop-values
	public String getSystemProperty(String key) {
		String value = null;
		
		try {
			value = (String) Class.forName("android.os.SystemProperties")
					.getMethod("get", String.class).invoke(null, key);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return value;
	}

可以看到平直铺叙的Java代码还是很容易弄明白的,一二逻辑就那么两三个分支,如果需要适配更多的机型,拓展起来也很方便。反观另一个基于kotlin的回答,区区两种情况就用了三次for循环、两次arrayOf、一次mapOf,给人的感觉是连if..else..都不会用,拓展起来也极为麻烦,可能需要所谓的重构,换个程序员来接手就是一头雾水。

奈何人家分数高啊,一万多声望值,我的天这就是正道的光嘛?


P.S. 这个粘贴代码自动解析的功能还真难用,瞎揣测圣意不说还总是闪眼睛,怎么关掉啊? 解决速度好快,已经没问题了……

`