Short version:
In my tests with Android 5.0 Lollipop I have noticed android.bluetooth.le.BluetoothLeScanner detects BLE devices less frequently than Android 4.4 KitK
I have experienced very similar results with my Nexus 4, in both KitKat and Lollipop.
With KitKat the bluetooth adapter also eventually went unresponsive; at first I though that it could be related to a short scan interval (200ms) but increasing that number to even a second didn't help, in that matter I found that, when unresponsive disabling and enabling the adapter programmatically, sometimes solves the problem. Unfortunately I can't say that it works all the time.
Now with Lollipop, in which I had high hopes to solve this issues, I experienced the same behaviour that you describe. I also had to use the startScan / stopScan implementation, getting similar results regarding the detection times. Sadly, I haven't found a work around to get results more quickly.
Based on what you describe I suppose it could be a hardware issue, even though the Nexus 7 and Nexus 4 are from different manufacturers (Asus and LG).
I know I'm not providing much help here besides trying to answer your question about you missing something; I don't think so, I think the problem is something like the hardware or the bluetooth API that still doesn't behave the way it should across different devices.
if you search for BW13_DayOne_Session1 Bluetooth Advanced
on google, you will find a pdf document that gives you the latencies for devices based on the settings for discovery (see page 8). I'm guessing your problem has to do with these timings. You can verify by figuring out the advertising configuration for the device you are testing (Adv Int, Duty Cycle) then figure out what the API settings are doing for configuring the scan interval, etc. Once you have these, you can then use that table to interpolate to see if your getting the results you expect.
I know this is a software site, but often when interfacing with hardware you need to know the protocol otherwise your shooting in the dark.
I don't have 50 reputation for a comment yet, so bear with me, this comment will be in the form of an answer. In your code, shouldn't this part:
if (isScanning) {
scanner.startScan(...)
be this instead:
if (!isScanning) {
scanner.startScan(...)
Because following your code, you're calling stopScan() before starting a scan. It may not have a direct effect on the result if the stopScan() method is idempotent/safe. But you know, for the sake of code intelligibility you should edit the question. And do the same to your code, sometimes byzantine things are at play ;)
Have you tried larger values for SCAN_INTERVAL_MS? If yes, how large?
Beyond API 21 android uses SCAN_MODE_LOW_POWER by default. SCAN_MODE_LOW_POWER
Try SCAN_MODE_BALANCED and see if it gets better.
SCAN_MODE_BALANCED
I have gotten very different results with a Nexus 5 running the new Android 5.0 scanning APIs. Detections of BLE packets came in at near real time when using SCAN_MODE_LOW_LATENCY, at every 100ms for BLE beacons transmitting at 10Hz.
You can read the full results here:
http://developer.radiusnetworks.com/2014/10/28/android-5.0-scanning.html
These tests are based off of running the open source Android Beacon Library 2.0's experimental android-l-apis branch here.
It is not obvious what the difference is in your test results, but it is possible that starting and stopping scanning is changing the results.
EDIT: it is possible the hardware is the difference. See a report of similar timings on the Nexus 4: https://github.com/AltBeacon/android-beacon-library/issues/59#issuecomment-64281446