Android 唤醒锁问题
Posted
技术标签:
【中文标题】Android 唤醒锁问题【英文标题】:Android wakeLock issue 【发布时间】:2020-08-02 13:28:42 【问题描述】:我有前台服务。
清单包含此权限:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
在 Splash 活动中,我请求此权限一次:
Intent intent = new Intent();
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName))
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
context.startActivity(intent);
在 onCreate 服务方法中我调用 createAlarm 方法:
private void createAlarm()
wakeupIntent = PendingIntent.getBroadcast(getBaseContext(), 0, new Intent("com.android.internal.location.ALARM_WAKEUP"), 0);
powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getPackageName() + ":TrackService");
wakeLock.acquire();
dozeHandler = new Handler();
Runnable heartbeat = new Runnable()
@Override
public void run()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
try
if (powerManager != null && powerManager.isDeviceIdleMode())
try
Log.d("MainService", "In IDLE MODE");
wakeupIntent.send();
catch (SecurityException | PendingIntent.CanceledException e)
Log.d("MainService", "Heartbeat location manager keep-alive failed", e);
else if (!powerManager.isDeviceIdleMode())
Log.d("MainService", "Device alive");
finally
if (dozeHandler != null)
dozeHandler.postDelayed(this, 5000);
;
heartbeat.run();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyWakefulReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
if (Build.VERSION.SDK_INT >= 23)
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, 30000, pendingIntent);
else
alarmManager.setExact(AlarmManager.RTC_WAKEUP, 30000, pendingIntent);
在所有初始化调用 setWakeLock 之后:
@SuppressLint("WakelockTimeout")
public void setWakeMode(Context context, int mode)
boolean wasHeld = false;
if (wakeLock != null)
if (wakeLock.isHeld())
wasHeld = true;
wakeLock.release();
wakeLock = null;
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(mode | PowerManager.ON_AFTER_RELEASE, MainService.class.getName());
wakeLock.setReferenceCounted(false);
if (wasHeld)
wakeLock.acquire();
我对这些功能感到困惑,因此我没有醒来,请帮助我。
【问题讨论】:
【参考方案1】:boolean wasHeld = false;
if (wakeLock != null)
if (wakeLock.isHeld())
wasHeld = true;
wakeLock.release();
wakeLock = null;
只有在“wakeLock.isHeld()”时才将“wasHeld”设置为 true。只有在 'wasHeld' 为真时才调用获取:
if (wasHeld)
wakeLock.acquire();
取出 'if (wasHeld)...' 并调用 acquire 无论如何,我猜 wasHeld 总是假的,所以永远不会调用 acquire。
如果它仍然不起作用,根据 AndroidStudio 文档,您可以:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyApp::MyWakelockTag");
wakeLock.acquire();
并调用
wakeLock.release();
完成后。
【讨论】:
以上是关于Android 唤醒锁问题的主要内容,如果未能解决你的问题,请参考以下文章