Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 对于华为设备,isPowerSaveMode()始终返回false_Android_Xamarin.android_Powermanager - Fatal编程技术网

Android 对于华为设备,isPowerSaveMode()始终返回false

Android 对于华为设备,isPowerSaveMode()始终返回false,android,xamarin.android,powermanager,Android,Xamarin.android,Powermanager,我目前正在实施一项功能,要求用户忽略应用程序的电池优化。这样做的原因是,应用程序的主要功能不幸受到节能模式的严重影响 为了实现我的目标,我通过创建意图并将操作设置为来提示用户 尽管如此,在启动Intent之前,我会检查isPowerSaveMode()和isignoringbatteryooptimizations(),以确保在未启用省电模式时不会提示用户;这是该功能的一个要求。我这样做的方式是: PowerManager pm = (PowerManager) getSystemService

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

为了实现我的目标,我通过创建
意图
并将
操作
设置为来提示用户

尽管如此,在启动
Intent
之前,我会检查
isPowerSaveMode()
isignoringbatteryooptimizations()
,以确保在未启用省电模式时不会提示用户;这是该功能的一个要求。我这样做的方式是:

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isPowerSaveMode = pm.isPowerSaveMode(); // always returns false for Huawei devices
这适用于大多数设备,但对于华为设备,
isPowerSaveMode()
始终返回
false
。因此,由于前置条件失败,因此从不显示提示

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


值得注意的是,同样的问题也出现在
Xamarin.Android
SDK中。

每个oem都会修改SDK以满足其需求。华为设备不使用默认的省电功能,而是使用一种叫做“受保护的应用程序”。受保护的应用程序是一组即使在屏幕关闭时也允许运行的应用程序。这就是它总是返回false的原因。最好在“受保护的应用程序”屏幕上显示“意图”,但无法知道您的应用程序是否已添加到受保护的应用程序列表中。

在实施手持和可穿戴设备时,我遇到了同样的问题。 我找到的唯一解决方案是禁用所有应用程序的电池节约模式。 我建议在禁用所有应用程序的此类模式后检测您的方法的结果。此错误仅出现在华为上。糟糕的供应商。

  • 我找到了一种方法,通过向
    IntentFilter
    添加自定义操作,手动请求当前华为电源模式状态并接收更改事件:
(注:仅在华为P20 Lite(ANE-LX3)@EMUI 8.0.0上测试)

//手动请求省电模式:
公共布尔值isPowerSaveMode(上下文){
if(Build.MANUFACTURER.equalsIgnoreCase(“华为”)){
返回ispowersavemode(上下文);
}否则{
返回isPowerSaveModeAndroid(上下文);
}
}
@塔吉塔皮(21)
专用布尔值isPowerSaveModeAndroid(上下文){
布尔值isPowerSaveMode=false;
if(android.os.Build.VERSION.SDK\u INT>=Build.VERSION\u code.LOLLIPOP){
PowerManager pm=(PowerManager)context.getSystemService(context.POWER\u服务);
如果(pm!=null)isPowerSaveMode=pm.isPowerSaveMode();
}
返回isPowerSaveMode;
}
专用布尔值ispowersavemode(上下文){
试一试{
int value=android.provider.Settings.System.getInt(context.getContentResolver(),“SmartModeStatus”);
返回值(值==4);
}catch(Settings.SettingNotFoundException){
//设置找不到?返回标准android机制,希望一切顺利。。。
返回isPowerSaveModeAndroid(上下文);
}
}
//侦听节能模式中的更改
public void startMonitoringPowerSaveChanges(上下文){
if(android.os.Build.VERSION.SDK\u INT>=Build.VERSION\u code.LOLLIPOP){
如果(mPowerSaveChangeReceiver!=null){
返回;
}
//注册PowerSaver更改更新。
mPowerSaveChangeReceiver=新的PowerSaveChangeReceiver();
//登记接收人
IntentFilter=newintentfilter();
filter.addAction(PowerManager.ACTION\u POWER\u SAVE\u MODE\u CHANGED);
//添加自定义华为操作
filter.addAction(“huawei.intent.action.POWER\u MODE\u CHANGED\u action”);
if(android.os.Build.VERSION.SDK\u INT>=Build.VERSION\u CODES.M){
filter.addAction(android.provider.Settings.ACTION\u IGNORE\u BATTERY\u OPTIMIZATION\u Settings);
}
registerReceiver(mPowerSaveChangeReceiver,筛选器);
}
}
@塔吉塔皮(21)
类PowerSaveChangeReceiver扩展了BroadcastReceiver{
公共void onReceive(上下文、意图){
布尔值isPowerSaveMode=false;
//哦,华为……你为什么不和其他人一样遵守同样的规则呢?
if(intent.getAction().equals(“huawei.intent.action.POWER\u MODE\u CHANGED\u action”)){
Bundle extras=intent.getExtras();
如果((extras!=null)和&extras.containsKey(“状态”)){
int state=intent.getExtras().getInt(“状态”);
isPowerSaveMode=(state==1);//开=1;关=2
}
}否则{
PowerManager pm=(PowerManager)context.getSystemService(context.POWER\u服务);
isPowerSaveMode=pm.isPowerSaveMode();
}
Log.d(“MyTag”、“[powersavechange]isPowerSaveMode?”+isPowerSaveMode);
}
}

一些中文ROM,如
华为
小米
没有实现节能模式查询的标准API。但和其他系统设置一样,当用户打开/关闭省电模式时,状态标志将保存到数据库中

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

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

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

有一个变通方法,已经在@Ch4t4r中描述过,谢谢链接。虽然它不能解决我遇到的问题。你确定它与手机上安装的Android版本无关吗?如果是,你能试试这段代码吗?PowerManager PowerManager=(PowerManager)getActivity().getSystemService(Context.POWER\u服务);if(android.os.Build.VERSION.SDK\u INT>=Build.VERSION\u CODES.LOLLIPOP&&powerManager.isPowerSaveMode()){