isPowerSaveMode() 对于华为设备总是返回 false [英] isPowerSaveMode() always returns false for Huawei devices

查看:16
本文介绍了isPowerSaveMode() 对于华为设备总是返回 false的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently implement a feature where the users are requested to ignore battery optimisation for the application. The reason for doing so, is that the main functionality of the application is unfortunately drastically affected by power save mode.

为了实现我的目标,我通过创建一个 Intent 并将 Action 设置为 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS.

To achieve my goal, I prompt the users by creating an Intent and setting the Action to ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS.

虽然,在触发 Intent 之前,我都会检查 isPowerSaveMode()isIgnoringBatteryOptimizations() 以确保我不会提示未启用省电模式时的用户;这是该功能的要求.我这样做的方式是:

Although, before firing the Intent, I both check for isPowerSaveMode() and isIgnoringBatteryOptimizations() to ensure that I don't prompt the users when power save mode is not enabled; which is a requirement for the feature. The way I do so is by:

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isPowerSaveMode = pm.isPowerSaveMode(); // always returns false for Huawei devices

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

This works fine for the most devices, but for Huawei devices, isPowerSaveMode() always returns false. Consequently, since the preconditions fail, the prompt is never shown.

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

Has anyone else possibly encountered this issue? If so, what did you do to solve it?

请注意,Xamarin.Android SDK 中也存在同样的问题.

As a note, the same issue is also present in the Xamarin.Android SDK.

推荐答案

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

Some Chinese ROM like Huawei or Xiaomi didn't implement the standard API for power save mode query. But like other system settings, a state flag will be saved to database when user turn power save mode on/off.

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

So we can utilize this state flag to solve the compatibility problem. Also a specific intent will send by system when toggle power save mode, we can listen this intent action to monitor power save mode changing.

以下是华为小米设备的详细kotlin代码实现.

Below is the detailed kotlin code implementation for Huawei or Xiaomi devices.

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
    }
}

这篇关于isPowerSaveMode() 对于华为设备总是返回 false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆