I'm working on an Alarm Clock. As part of it, I have an IntentService
that starts an activity when the alarm actually goes off. In the Activity's onCreate
I'm waking up the screen, obtaining wake lock, forcing the activity to full screen, and playing a sound. Here's all that in the onCreate:
super.onCreate(savedInstanceState);
// Get Alarm ID from the extras
Bundle extras = getIntent().getExtras();
int id = extras.getInt("AlarmID", -1);
// Get Alarm info from the DB
DB = new DatabaseHelper(this);
alarm = DB.getAlarm(id);
if (alarm == null || !alarm.isEnabled()) finish();
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_alarm);
// My root view
View contentView = findViewById(R.id.fullscreen_content);
// Hide action bar for full screen
ActionBar bar = getActionBar();
if (bar != null) bar.hide();
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Hide nav bar
mSystemUiHider = SystemUiHider.getInstance(this, contentView, HIDER_FLAGS);
mSystemUiHider.setup();
mSystemUiHider.hide();
// Show over lock screen
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
// Wake up screen
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "MyWakeLock");
wakeLock.acquire();
// Get UI Elements
TextView time = (TextView)findViewById(R.id.Time);
TextView name = (TextView)findViewById(R.id.SmallAlarmName);
// Fill UI Elements
time.setText(Alarm.FormatTime(alarm.getHour(), alarm.getMinute()));
name.setText(alarm.getName());
// Play selected ringtone
tone = RingtoneManager.getRingtone(this, alarm.getSound());
tone.setStreamType(RingtoneManager.TYPE_ALARM);
tone.play();
The view is rather simple: 2x TextViews to show the time and the name of the alarm, and 2x clickable ImageViews for Snooze and Disable.
The problem I'm having is that the first time I touch the screen, nothing happens. Both of the ImageViews start with a Log.i
so I know when I push it if the event fires. On the first push, there's no log output. On the second push, the proper ImageView's event is fired. It doesn't matter if the screen was originally on or off when the activity is created, the first touch is very repeatably ignored. What's happening and how can I fix it so that the first touch works as expected?
I'm testing on my Nexus 5, 4.4.3, Rooted, stock rom, Xposed Framework (but no module that would affect my app). I can't really test in a virtual machine because of the need to use ringtones (of which the VM has none).
Also, for the record, no other logs happen for the first tap. I have no clue what the phone thinks I'm tapping.
EDIT: I thought it had something to do with the flags. I noticed that I was calling setFlags
instead of addFlags
in my call getWindow().setFlags(...)
. Instead, I changed it to addFlags
and tried changing it to:
int flags = WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
getWindow().addFlags(flags);
But no change.
Is there a way I can tell what might be intercepting the first tap?
I tried setting a break point at the end of onCreate and continually stepping over until it eventually is awaiting for an event to arise, but even in this state the first tap won't make a change in the debugger. A second tap on one of my ImageViews will, as expected, stop the debugger at the first line inside my click handlers.
EDIT 2: I think I'm on to something. I was watching the logcat through a filter, only seeing things relating to my app. I tried looking at the logcat without a filter and was able to reliably get these kinds of messages on first tap:
06-12 23:28:04.437 812-844/? W/InputEventReceiver﹕ Attempted to finish an input event but the input event receiver has already been disposed.
The first tap would respond with two of these warnings. Additional taps after the first would give no such warning and my handlers would execute as expected.
A quick search came back with this question but is unhelpful for my situation. More than just a warning, I think this may be the root cause for why the first tap is ignored. However, I still don't have any idea as to how to fix it.