Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android wakeLock issue

I have foreground service.

Manifest contains this permissions:

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

In Splash activity i request this permisssion once:

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);

In onCreate service method i calling createAlarm method:

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

And after all initializations calling 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();
    }
}

I am confused in these functions and as a result I do not get awakening, please help me.

like image 456
AlexS Avatar asked Jul 26 '26 16:07

AlexS


1 Answers

boolean wasHeld = false;
if (wakeLock != null) {
    if (wakeLock.isHeld()) {
        wasHeld = true;
        wakeLock.release();
    }
    wakeLock = null;
}

You are only setting 'wasHeld' to true if 'wakeLock.isHeld()'. You are only calling acquire if 'wasHeld' is true:

if (wasHeld) {
    wakeLock.acquire();
}

Take out the 'if (wasHeld)...' and just call acquire no matter what, I'm guessing wasHeld is always false, so acquire never gets called.

If it still doesn't work, as per AndroidStudio documentation you can just:

PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
        "MyApp::MyWakelockTag");
wakeLock.acquire();

and call

wakeLock.release();

when finished.

like image 162
vasmos Avatar answered Jul 30 '26 09:07

vasmos



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!