首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对于华为设备,isPowerSaveMode()总是返回false

对于华为设备,isPowerSaveMode()总是返回false
EN

Stack Overflow用户
提问于 2017-08-18 03:25:22
回答 7查看 2.3K关注 0票数 14

我目前正在实现一个功能,要求用户忽略应用程序的电池优化。这样做的原因是,不幸的是,应用程序的主要功能受到省电模式的严重影响。

为了实现我的目标,我通过创建一个Intent并将Action设置为ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS来提示用户。

不过,在启动Intent之前,我同时检查了isPowerSaveMode()isIgnoringBatteryOptimizations(),以确保在未启用省电模式时不提示用户;这是该特性的一个要求。我这样做的方法是:

代码语言:javascript
运行
复制
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isPowerSaveMode = pm.isPowerSaveMode(); // always returns false for Huawei devices

这适用于大多数设备,但对于华为设备,isPowerSaveMode()总是返回false。因此,由于前提条件失败,因此永远不会显示提示。

其他人可能遇到过这个问题吗?如果是这样,你做了什么来解决这个问题?

需要注意的是,同样的问题也存在于Xamarin.Android SDK中。

EN

回答 7

Stack Overflow用户

发布于 2021-01-12 19:12:55

一些中文光盘,如HuaweiXiaomi,没有实现省电模式查询的标准API。但与其他系统设置一样,当用户打开/关闭省电模式时,会将状态标志保存到数据库中。

所以我们可以利用这个状态标志来解决兼容性问题。另外,当切换到省电模式时,系统会发送一个特定的意图,我们可以监听这个意图动作来监控省电模式的变化。

下面是用于HuaweiXiaomi设备的详细kotlin代码实现。

代码语言:javascript
运行
复制
object PowerManagerCompat {

    private const val TAG = "PowerManagerCompat"

    interface PowerSaveModeChangeListener {
        /**
         * will be called when power save mode change, new state can be query via [PowerManagerCompat.isPowerSaveMode]
         */
        fun onPowerSaveModeChanged()
    }

    private val POWER_SAVE_MODE_VALUES = mapOf(
            "HUAWEI" to 4,
            "XIAOMI" to 1
    )

    private val POWER_SAVE_MODE_SETTING_NAMES = arrayOf(
            "SmartModeStatus", // huawei setting name
            "POWER_SAVE_MODE_OPEN" // xiaomi setting name
    )

    private val POWER_SAVE_MODE_CHANGE_ACTIONS = arrayOf(
            "huawei.intent.action.POWER_MODE_CHANGED_ACTION",
            "miui.intent.action.POWER_SAVE_MODE_CHANGED"
    )

    private const val monitorViaBroadcast = true

    /**
     * Monitor power save mode change, only support following devices
     * * Xiaomi
     * * Huawei
     */
    fun monitorPowerSaveModeChange(context: Context, powerSaveModeChangeListener: PowerSaveModeChangeListener) {
        if (Build.MANUFACTURER.toUpperCase(Locale.getDefault()) !in POWER_SAVE_MODE_VALUES.keys) {
            Log.w(TAG, "monitorPowerSaveModeChange: doesn't know how to monitor power save mode change for ${Build.MANUFACTURER}")
        }
        if (monitorViaBroadcast) {
            context.registerReceiver(object : BroadcastReceiver() {
                override fun onReceive(context: Context?, intent: Intent?) {
                    powerSaveModeChangeListener.onPowerSaveModeChanged()
                }
            }, IntentFilter().also {
                for (a in POWER_SAVE_MODE_CHANGE_ACTIONS) {
                    it.addAction(a)
                }
            })
        } else {
            val contentObserver = object : ContentObserver(null) {
                override fun onChange(selfChange: Boolean) {
                    super.onChange(selfChange)
                    powerSaveModeChangeListener.onPowerSaveModeChanged()
                }
            }
            for (name in POWER_SAVE_MODE_SETTING_NAMES) {
                context.contentResolver.registerContentObserver(
                        Uri.parse("content://settings/system/${name}"), false, contentObserver)
            }
        }
    }

    /**
     * Check the system is currently in power save mode
     * @see [PowerManager.isPowerSaveMode]
     */
    fun isPowerSaveMode(context: Context): Boolean {
        if (Build.MANUFACTURER.toUpperCase(Locale.getDefault()) in POWER_SAVE_MODE_VALUES.keys) {
            return isPowerSaveModeCompat(context)
        }
        val powerManager = context.getSystemService(Context.POWER_SERVICE) as? PowerManager
        return powerManager?.isPowerSaveMode ?: false
    }

    private fun isPowerSaveModeCompat(context: Context): Boolean {
        for (name in POWER_SAVE_MODE_SETTING_NAMES) {
            val mode = Settings.System.getInt(context.contentResolver, name, -1)
            if (mode != -1) {
                return POWER_SAVE_MODE_VALUES[Build.MANUFACTURER.toUpperCase(Locale.getDefault())] == mode
            }
        }
        return false
    }
}
票数 2
EN

Stack Overflow用户

发布于 2017-09-05 01:37:37

每个oem都会修改SDK以满足自己的需求。华为设备没有使用默认的省电功能,而是使用了一种名为"Protected apps“的功能。受保护的应用程序是一组即使在屏幕关闭时也允许运行的应用程序。这就是它总是返回false的原因。最好是向受保护的应用程序屏幕抛出一个意图,但是没有办法知道你的应用程序是否被添加到受保护的应用程序列表中。What is protected apps ?

票数 1
EN

Stack Overflow用户

发布于 2020-08-25 01:44:13

通过向IntentFilter添加自定义操作,我已经找到了一种手动请求当前华为电源模式状态和接收更改事件的方法

(注仅在华为P20 Lite (ANE-LX3) @EMUI8.0.0上测试)

代码语言:javascript
运行
复制
// Manually request Power Save Mode:
public Boolean isPowerSaveMode(Context context) {
    if (Build.MANUFACTURER.equalsIgnoreCase("Huawei")) {
        return isPowerSaveModeHuawei(context);
    } else {
        return isPowerSaveModeAndroid(context);
    }
}

@TargetApi(21)
private Boolean isPowerSaveModeAndroid(Context context) {
    boolean isPowerSaveMode = false;
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (pm != null) isPowerSaveMode = pm.isPowerSaveMode();
    }
    return isPowerSaveMode;
}

private Boolean isPowerSaveModeHuawei(Context context) {
    try {
        int value = android.provider.Settings.System.getInt(context.getContentResolver(), "SmartModeStatus");
        return (value == 4);
    } catch (Settings.SettingNotFoundException e) {
        // Setting not found?  Return standard android mechanism and hope for the best...
        return isPowerSaveModeAndroid(context);
    }
}

// Listening for changes in Power Save Mode
public void startMonitoringPowerSaveChanges(Context context) {
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (mPowerSaveChangeReceiver != null) {
            return;
        }
        // Register for PowerSaver change updates.
        mPowerSaveChangeReceiver = new PowerSaveChangeReceiver();

        // Registering the receiver
        IntentFilter filter = new IntentFilter();

        filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
        // Add custom huawei action
        filter.addAction("huawei.intent.action.POWER_MODE_CHANGED_ACTION");

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            filter.addAction(android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
        }
        context.registerReceiver(mPowerSaveChangeReceiver, filter);
    }
}

@TargetApi(21)
class PowerSaveChangeReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        boolean isPowerSaveMode = false;

        // Oh, Huawei...why don't you play by the same rules as everyone else?
        if (intent.getAction().equals("huawei.intent.action.POWER_MODE_CHANGED_ACTION")) {
            Bundle extras = intent.getExtras();
            if ((extras != null) && extras.containsKey("state")) {
                int state = intent.getExtras().getInt("state");
                isPowerSaveMode = (state == 1);  // ON=1; OFF=2
            }
        } else {
            PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
            isPowerSaveMode = pm.isPowerSaveMode();
        }
        Log.d("MyTag", "[powersavechange] isPowerSaveMode? " + isPowerSaveMode);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45743484

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档