My understanding is,existing Screen OFF and ON intents are not exactly mean that the device is in sleep and waked up respectively. Any applications on the device holds partial wake lock, device will not be in deep sleep but screen may be off/on.
Is there any intents to listen CPU "WAKE UP" and "SLEEP" ?
Is there any way, we know CPU is waked UP from deep sleep ?
I needed a tool to do exactly this when troubleshooting some timing behavior on my app in the background. So I made my own class to do it. See code below. Here's how you use it:
CpuSleepDetector.getInstance().setSleepEndNotifier(new CpuSleepDetector.SleepEndNotifier() {
@Override
public void cpuSleepEnded(long sleepDurationMillis) {
Log.d(TAG, "The CPU just exited sleep. It was sleeping for "+sleepDurationMillis+" ms.");
}
});
CpuSleepDetector.getInstance().logDump();
The logDump
method will dump the last 100 sleep events to LogCat. This is useful in troubleshooting, becaue to get the CPU to sleep, I had to not only disconnect my USB cable from my phone, I actually had to turn off my adb connection over WiFi. This way, you can reconnect adb at a later time and use the logDump
method to get recent detections.
I know this is an old question, but hopefully this will be useful to somebody else.
Here's the code for the detector class:
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
public class CpuSleepDetector {
private static final String TAG = CpuSleepDetector.class.getSimpleName();
private static CpuSleepDetector instance = null;
private HandlerThread thread;
private Handler handler;
private SleepEndNotifier notifier;
public static CpuSleepDetector getInstance() {
if (instance == null) {
instance = new CpuSleepDetector();
}
return instance;
}
private CpuSleepDetector() {
thread = new HandlerThread("cpuSleepDetectorThread");
thread.start();
handler = new Handler(thread.getLooper());
watchForSleep();
}
private void watchForSleep(){
// uptime stalls when cpu stalls
final long uptimeAtStart = SystemClock.uptimeMillis();
final long realtimeAtStart = SystemClock.elapsedRealtime();
handler.postDelayed(new Runnable() {
@Override
public void run() {
long uptimeAtEnd = SystemClock.uptimeMillis();
long realtimeAtEnd = SystemClock.elapsedRealtime();
long realtimeDelta = realtimeAtEnd - realtimeAtStart;
long uptimeDelta = uptimeAtEnd - uptimeAtStart;
final long sleepTime = realtimeDelta - uptimeDelta;
if (sleepTime > 1) {
detectedStalls.put(new Date(), sleepTime);
prune();
if (notifier != null) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
notifier.cpuSleepEnded(sleepTime);
}
});
}
}
watchForSleep();
}
}, 1000);
}
private HashMap<Date,Long> detectedStalls = new HashMap<Date,Long>();
private HashMap<Date,Long> getDetectedStalls() {
return detectedStalls;
}
private void prune() {
int numberToPrune = detectedStalls.size() - 100;
if (numberToPrune > 0) {
HashMap<Date,Long> newDetectedStalls = new HashMap<Date,Long>();
ArrayList<Date> dates = new ArrayList<>(getDetectedStalls().keySet());
Collections.sort(dates);
for (int i = numberToPrune; i < detectedStalls.size(); i++) {
newDetectedStalls.put(dates.get(i), detectedStalls.get(dates.get(i)));
}
detectedStalls = newDetectedStalls;
}
}
public void logDump() {
Log.d(TAG, "Last 100 known CPU sleep incidents:");
ArrayList<Date> dates = new ArrayList<>(getDetectedStalls().keySet());
Collections.sort(dates);
for (Date date: dates) {
Log.d(TAG, ""+date+": "+getDetectedStalls().get(date));
}
}
public void setSleepEndNotifier(SleepEndNotifier notifier) {
this.notifier = notifier;
}
public interface SleepEndNotifier {
public void cpuSleepEnded(long sleepDurationMillis);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With