Imagine an Android device (possibly any device from any manufacturer) that is connected via bluetooth to a speaker (or any bluetooth audio device)... and there has been a "significant" amount of time where no audio has been played from the device.
At the moment audio resumes playing from this device, there is more often than not a "speaker is slowly waking up" phase where no audio is heard and the audio is late to become audible.
This is less obvious when the audio is being "kept alive" with constant audio, or only taking short breaks of silence, but what if you have an application that makes very short and intermittent sounds at unpredictable times... like an alarm that measures environmental conditions with a sensor?
I'm not sure if:
A) This behavior is some kind of power-saving feature of the output device and we would have no control over it other than to play some kind of fake audio/silence prior to our desired sound... or have a low-volume sound/white noise on a constant loop... in order to pre-empt/prevent the "warm up."
B) It's part of the bluetooth protocol/standard/definition
C) It's controllable in software with something like (on Android):
bluetooth.setMode(BluetoothMode.NO_NAPPING_ALLOWED);
I'm hoping the case is (C), and if so, then what is the proper code for this?
I'm sure there is a similar question out there that is asked in a different way, but I can't find it, and I have searched through the documentation for AudioManager and although bluetooth is mentioned in many places, I can't find this functionality.
For fun, I accessed developer options on my phone and picked the option to keep the device awake. I also tried to disable any battery optimization.
My SONY XB-900 headphones turned off after some minutes of silence, my cheapo Monster headphones did not turn off, and a cheapo Bluetooth Speaker did not turn off.
I repeated the same thing on Windows, exactly the same results.
Then I searched on some forums, using the keywords "Bluetooth" "prevent" "awake" "power saving" "standby" "disconnected" "annoying" and "silence".
This commenter told something interesting:
I read that sony SRS-X1 bluetooth speaker doesn't cut off bluetooth
audio connection after a period of inactivity. It just enters standby
mode which it takes about 0.1 second to exit when audio signals
arrive. So, you can lose 0.1 second of audio when audio is played
after a period of inactivity. However, you can prevent it from
entering standby mode by playing 20Hz noise continuously. Speakers
cannot react to 20Hz noise, so 20Hz noise is silent.
This makes me believe that is a pure playback device-side implementation, and the OS nor Bluetooth have anything to do with it. The fact that you did not find any documentation about it supports the theory. Looks like the solution is the one you already mentioned: Play a very low or very high frequency on loop to keep the device awake.
Related
I'm working on an app that uses a MediaPlayer object to play H.264 MP4 videos from a WallpaperService as it is a live wallpaper app. Battery drain occurs while the device (Nexus 5, Android 6.0.1) is idle and sleeping if I pause/stop the MediaPlayer with mediaPlayer.pause() or mediaPlayer.stop(). The drain is about 3-7%/hour as tested multiple times overnight. As soon as I release the media player with mediaPlayer.release(), the battery drain goes back to a more normal 1%/hour. I pause/stop the mediaPlayer when onVisibilityChanged calls false. The phone is reporting to be going to sleep in both the stock Android battery chart and Better Battery Stats.
How can this battery drain be explained if the CPU is going into a sleep state successfully?
EDIT: Something new I've discovered is that when calling mediaPlayer.setSurface(null) right before mediaPlayer.pause(), the idle battery use comes back to normal. I can then do mediaPlayer.setSurface(surface) to set it back before mediaPlayer.start(). The problem is there's some black artifacting for a couple of seconds after restarting.
I can't give you a precise answer but can give you what to look for. I suspect what is going on is that pause() is checking for events frequently enough to keep the processor from entering the deeper sleep/C-states. In contrast, stop() doesn't need to check for events and so allows the processor to enter a deep sleep state. I wrote an article on sleep states some years back.
I suspect that the writers of the function decided to check more frequently than is necessary. This is a very common mistake due to the developers thinking that shorter sleeps / more frequent checking result in better response (which it almost never does). You can check this by using a processor power monitor that actually checks the hardware sleep states. Unfortunately, most don't and only check for processor independent "equivalents".
So let's get back to your question: What can you do about it. I can give you some advice but none of it is very satisfying:
Check for an API or data structure that allows you to set the
checking interval for pause(). By the way, I don't know of any.
Write your own. Of course, this complicates writing platform independent apps
Use an alternative media player that has done this correctly
Hammer on google until it's fixed
Like I said, none of this is very satisfying. By the way, searching the net, I found evidence that this has happened more than once with new Android releases.
Good luck and let us know what happens.
I want to be able to push a button in an app running on my Android phone and have a power switch on a real circuit literally attached to the phone be turned on/off. I'm having trouble thinking of a good way to do it. So far I've thought of:
1) Using an Arduino
The biggest problem with this is that the Arduino needs to be loaded with a sketch in order to work, and I can't use a PC to do the job. I've seen Arduino Commander but it's freemium and not open source, and I need to write my own custom app. It seems that I would have to find a way to load sketches and also write my own driver. This is not a pleasing course of action.
2) Playing an audio tone from the earphone jack
The idea is to play a tone that can then be converted into a small DC voltage. That DC voltage will then be used as the gate voltage to a MOSFET, which will act as the switch. The problem with this is that undesired audio can unexpectedly turn on the switch. For my application, even a small chance of this is unacceptable. Even filtering doesn't eliminate interference completely. Can I some how exclude all other sources of sound and only have an audio tone as output? If not over the headphone jack itself, over Bluetooth?
If anyone has any helpful thoughts, please share them.
You could try the second method with a specific audio to be played with some intervals which only triggers the switch instead of any audio being able to change the switch state, It does contain a little latency to be triggered but if its okay then it may work for you.
To clarify some miss information, the Arduino IDE is available at no charge for use on Windows, Mac OS, Linux, Raspberry pi and maybe others. With the IDE you can write, download your code to the Arduino and debut it.
I am running a simple application that receives
and displays the values of Bluetooth Low Energy
advertisement packets in real time.
The Glass heats up in about 5 minutes and touch
commands stop working. The Glass is not super
hot, but warmer than feels comfortable.
Commenting out the Bluetooth stuff reduces the
heating considerably.
How can I make this application workable on the
Glass?
Without seeing the exact code you're using it is difficult to diagnose, but from your description we might be able to make a guess.
It sounds like you're using BluetoothAdapter.startLeScan() without setting up a timeout to stop the scan, and then scanning for an extended period of time. The documentation at http://developer.android.com/guide/topics/connectivity/bluetooth-le.html#find points out:
Because scanning is battery-intensive, you should observe the
following guidelines:
As soon as you find the desired device, stop scanning.
Never scan on a
loop, and set a time limit on your scan. A device that was previously
available may have moved out of range, and continuing to scan drains
the battery.
Battery drains typically correspond to Glass overheating.
There isn't a lot you can do to solve the problem, but it may involve changing how you think about what you're doing.
If you're doing this in immersion mode, you may want to switch it to a live card instead. You may also not really want to scan "forever", but may want to try scanning for a fairly short period of time, then turning it off for a short period of time, and repeating this. Or you may want to turn it off for a period of time once a new packet is received. Your exact needs may dictate this, but given the characteristics of how often advertisement packets are sent out, you may not need to be constantly listening to get all of the packets.
As a current Glass developer myself, I've found that there isn't really any good way around this.
We're all facing this problem. There isn't much room, every is tightly packed, and what Glass is having to do is complicated. It will heat up if you are constantly scanning. Especially when you are taking videos - Glass will become very hot.
I found that lowering the screen brightness helps a bit, at least with the battery life, if nothing else.
This is how you set the screen brightness to its minimum, in case you do want to try it and see if it helps:
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 0f;
getWindow().setAttributes(lp);
I'm currently investigating workarounds for this heat problem as well. Glass overheats quickly when capturing previews and doing heavy calculations or image processing on it.
This paper is very informative:
http://arxiv.org/pdf/1404.1320v1.pdf
Title: "Draining our Glass: An Energy and Heat
Characterization of Google Glass"
How do you fire the iblazr programmatically?
No API I can find, they're not responding to inquiry.
I'm looking for a solution for iPhone and Android.
Since you have to enable the flash device with the media volume at max, I suspected it must have something to do with the volume output that triggers it.
So, I plugged it in, started my music player, and it started flashing to the music for the most part.
Turning down the volume stopped the flashing and turning it back up caused the LED to again start flashing.
Based on that I would assume you simply have to output a loud audio clip to turn it on while the media volume is set to max.
Update:
After experimenting on my theory, the device I have (iblazr compatible 16 LED Chinese version), the frequency of the tone is the key and determines the brightness. Using the Windows API Beep(frequency, duration) function, the light first turns on at a frequency of 6500 and gets brighter as the frequency increases. Seems like it is pretty bright at 7000!
They finally published it here:
https://github.com/ConcepterDev/iblazr-original-protocol
You can control the original iblazr by sending the specified tone for the specified duration to the headphone jack:
function frequency (Hz) duration
----------------------------------------------
wake iblazr 800 200±150ms
flash 15750 300ms (auto)
pre-flash 10000 until focused
constant light 2500-9500 infinite
My quest is if anyone knows how to create an Android app that can send electric charge through the device's headphone jack, like in this video iPocket_LED. The video shows an app for iPhone that controls a LED plugged into the headphone jack.
I want to know how to access the device to send an electric signal.
Sorry about my English, is not my language, I hope some one understand me
Many consumer devices which accept an external microphone will provide "plug-in power". This is a small voltage typically from 1 to 5 volts across two of the contacts in the microphone connection.
Apple and (most) Android devices are no exception. Most use a 4-conductor TRRS connection with the following pin-out:
TIP = left headphone out
RING = right headphone out
RING = ground
SLEEVE = mic in + plug-in power
The plug-in power is usually around 2V on smartphones and is supplied as +2V on the microphone (sleeve) conductor. The phone will only supply it if it detects that a microphone is in place, which it does by testing the resistance across Mic to Ground to see if it's consistent with a microphone's impedance - something like 200 to 5000 ohms impedance, and I hear the iphones can be very fussy with this and need very close to 1600 ohms.
This means the maximum power you could draw from this and still seem like a microphone would be pretty small - around 1.25 milliamps. There are some low powered microcontrollers or other devices you may be able to power with this.
Note that plug-in power may be a similar concept to "phantom power" as used in pro audio gear but it's a different and incompatible standard. "plug-in power" is what causes the tiny electret microphones in smartphone headsets to work without needing their own small battery.
As for how to actually exert control over your attached device from an app, that's getting into much more complicated electronics. Presumably it is possible if you use the left and/or right headphone out lines to send signals to the device.
You'll need to play some audio. A small amount of current flows anytime audio plays, that's what moves the tiny little speakers in your headphones. The voltage will vary with the level of the audio. It is also AC current, such that the frequency of the sound (pitch) affects the frequency of the AC cycle.
It is going to be difficult to integrate with a device using this approach, especially because of the AC current. You can determine the appropriate pitch to send the voltage you want, but most "devices" are probably going to want a +3.3v or +5v DC signal. You'll probably need to do an AC to DC conversion to make that work.
I believe there is a means to integrate with an Android device via the USB interface. That would probably be far better and easier. You could get yourself an Arduino kit with a built-in USB shield/controller, and build your device on top of that.
See External USB devices to Android phones?
Yes using both at the same time is possible as this is how phones are designed to work. In fact depending on which specific device you have, overriding the volume limit will also give you a bit more power.
The best bet as far as lowest possible loss would be active rectification: at the null point have it switch over to +2V and the rest of the time whichever is the highest peak gets rectified. Simple enough to use two dual MOSFETs and this should get you enough power to at least initialize a phone though probably not charge it.