Reputation: 4571
I have the following code in my BroadcastReceiver's onReceive function.
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null) return;
if (action.equals(ACTION_ALARM)) {
Intent alarmPopup = new Intent(context, AlarmPopup.class);
int vibrateDuration = context.getSharedPreferences(PREF, 0)
.getInt(VIBRATE_DURATION, DEFAULT_VIBRATE_DURATION)
alarmPopup.putExtra(VIBRATE_DURATION, vibrateDuration);
alarmPopup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmPopup);
}
}
This code starts activity AlarmPopup
as it receives alarm manager's broadcast.
Once the AlarmPopup activity is started, it shows a typical alarm message and vibrates during vibrateDuration
passed through Intent#putExtra
.
In AlarmPopup's onCreate method, the activity holds WakeLock
to make the device keep turning on.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wl = getLock(this);
if (!wl.isHeld()) {
Log.d(PREF, "Alarm popup acquires wake lock");
wl.acquire();
thread.run();
}
.
.
.
}
getLock
is a synchronized method that manages WakeLock
as WakefulIntentService does.
private static volatile PowerManager.WakeLock wlStatic = null;
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (wlStatic == null) {
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wlStatic = mgr.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, PREF);
wlStatic.setReferenceCounted(true);
}
return wlStatic;
}
Now here is the problem: even though context.startActivity(alarmPopup)
is called, startActivity
rarely does not start the activitiy or starts not on time, usually 1-2 minutes later.
It seems that OS kills my AlarmPopup activitiy in the middle of its creation or let the activity be created a little bit later than the time when startActivity
was actually called.
What is really interesting is, when the above problem happens, sometimes the log message "Alarm popup acquires wake lock"
is recorded and sometimes it is not even recorded. I think, in this case, OS kills the activity while it executes the first or second line of onCreate
method.
How can I solve this problem?
Should I put some dummy code that holds the CPU at the end of onReceive while the AlarmPopup activity is being created by another thread?
Upvotes: 1
Views: 1571
Reputation: 1006584
It seems that OS kills my AlarmPopup activitiy in the middle of its creation or let the activity be created a little bit later than the time when startActivity was actually called.
No. The device simply fell asleep. startActivity()
is an asynchronous operation. The WakeLock
held by the OS for the AlarmManager
work (assuming that you are, indeed, using AlarmManager
) will be released when onReceive()
returns. onCreate()
of your activity will not have run by the time onReceive()
returns. Hence, the device might fall asleep in the window of time between the end of onReceive()
and when you acquire your WakeLock
in onCreate()
.
How can I solve this problem?
Acquire the WakeLock
in onReceive()
.
Upvotes: 4