Android PowerManager PROXIMITY_SCREEN_OFF_WAKE_LOCK release not working

What am I doing wrong in this code, it doesn’t release, it continues to work until I close the application.

package com.powermanager.powermanager

import android.content.Context
import android.os.PowerManager
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result


/** PowermanagerPlugin */
class PowermanagerPlugin: FlutterPlugin, MethodCallHandler {
  private lateinit var applicationContext: Context
  private lateinit var channel : MethodChannel
  private lateinit var powerManager: PowerManager
  private lateinit var lock: PowerManager.WakeLock

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    applicationContext = flutterPluginBinding.getApplicationContext();
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "powermanager")
    channel.setMethodCallHandler(this)
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "toogle") {
      powerManager = applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
      if(powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
        lock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,"PROXIMITYSCREENOFFWAKELOCK")
        lock.setReferenceCounted(false)
        if(lock.isHeld) {
          lock.release(1)
          result.success(true)
        } else {
          lock.acquire()
          result.success(true)
        }
      } else {
        result.error("notSupported", "PowerManager PROXIMITY_SCREEN_OFF_WAKE_LOCK is notSupported", null)
      }
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}

>Solution :

It seems like the issue with your code is that you’re creating a new instance of PowerManager.WakeLock every time the toogle method is called, instead of reusing the existing instance.

To fix the issue, you should create a single instance of PowerManager.WakeLock when the plugin is attached to the engine and reuse it in the toogle method. You can also add the release method call in the onDetachedFromEngine method to ensure that the lock is released when the plugin is detached.

Here’s an updated version of your code:

    ```

package com.powermanager.powermanager

import android.content.Context
import android.os.PowerManager
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result


/** PowermanagerPlugin */
class PowermanagerPlugin: FlutterPlugin, MethodCallHandler {
  private lateinit var applicationContext: Context
  private lateinit var channel : MethodChannel
  private lateinit var powerManager: PowerManager
  private lateinit var lock: PowerManager.WakeLock

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    applicationContext = flutterPluginBinding.getApplicationContext();
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "powermanager")
    channel.setMethodCallHandler(this)

    powerManager = applicationContext.getSystemService(Context.POWER_SERVICE) as PowerManager
    if(powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
      lock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,"PROXIMITYSCREENOFFWAKELOCK")
      lock.setReferenceCounted(false)
    }
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "toogle") {
      if(powerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
        if(lock.isHeld) {
          lock.release(1)
          result.success(true)
        } else {
          lock.acquire()
          result.success(true)
        }
      } else {
        result.error("notSupported", "PowerManager PROXIMITY_SCREEN_OFF_WAKE_LOCK is notSupported", null)
      }
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    if(lock.isHeld) {
      lock.release(1)
    }

    channel.setMethodCallHandler(null)
  }
}

Leave a Reply