I'm trying to trigger an action inside my Android app on multiple devices at the exact same time (or with the lowest delay/shift possible).
The devices are strictly similar (brand, model, version), plugged via USB to a Macbook Pro. I have 4 devices so far but the final solution will include many more so I need a solution that works with a lot of devices.
I have tried using sockets (Socket.io and regular WS) over Wifi and USB, but the delay slightly increases for each device so the action is not triggered in sync.
I also tried sending a broadcast UDP packet over USB, this gives way better results but seems very inconsistent: the max delay goes from 10 to a 100ms.
Syncing clocks was another option I was considering but not sure how accurate can it get across many devices (and NTP seems tricky on Android)
Any idea or pattern to address this kind of requirements? Thanks!
EDIT
So after doing some tests, the most accurate option was to sync the devices clocks using NTP as suggested by Sam Mason (I'm using this library). I managed to get an average 5ms shift between my 4 devices.
first some observations:
mobile devices tend to power down NICs aggressively to conserve power (I'm not sure how much this is affected by whether they are currently charging)
they also throttle their CPU frequency if they're not being used and it can take a while (i.e. milliseconds) to get them back up to speed. given that your devices are all the "same" the variance in your measurements would probably be dominated by other apps also running
measuring the delay in apps responding seems non-trivial, doing this via a network might increase variance because all devices are contesting each other (note that USB is a "serial bus" so this applies here as well). depending on how much this matters it might be worth setting up a video camera and watch their screens
that said, I'd be tempted to rely on their clocks to do this. NTP sync can be great (e.g. sub-millisecond precision is pretty easy) but probably not for mobile devices (I'd assume Android NTP clients care more about power and anything less than a few seconds is fine for humans). that said, their clocks should be pretty stable, so have your clients check in (randomly so there's less network contention, and do it a few times so the NIC is properly powered up). the clients can use this to figure out how long until the "event", then sleep until a few milliseconds before this. they can then wake up and do a busy loop checking the time (to make sure the CPU is powered up) and then continue at the appropriate time
Related
I am working for a android BLE library for our team, the library is developed with 4.3 native framework, I try to keep a table of the found BLE device, and send a notification when I find a new BLE device who is not in my found device table, instead of informing each time when the device is found (default behaviors by android BLE framework), the problem is I can't detect the device is gone, in consideration of that I don't want to establish the BLE connection with it.
Anyone can help me out? I suppose that there is some way to do this, like the iOS framework, u can be informed when the device is gone without connecting to it.
The basic strategy to "undiscover" a device is to keep track of the last time a device was discovered and once every second or so iterate through your list of devices. If the current time minus the last time the device was discovered is greater than some time delta (I use 12.5 seconds) then you consider the device undiscovered and remove it from your list.
Some gotchas with this:
The minimum time it takes to undiscover a device is 12.5 seconds, which is pretty long if you sit down and count it out. You can try to use lower time delta thresholds but I've found that with some phones this results in a lot of false undiscoveries, because legitimate time in between discoveries can take a while.
You should not scan continuously, but rather at most do it in pulses of 5-10 seconds with small breaks in between.
I've also heard of people using RSSI. Low RSSI means you undiscover it, but I experienced a lot of false positives with this approach as well.
I've written a simple application that displays some text and a little bit of graphics on screen. I'm using a Nexus 7, this is for an installation, and as such needs to be on continuously as much as 12 hours a day. However, despite being plugged in and charging, my application drains the battery completely in about 8 hours (10-15% / hour).
Apart from the infrequently-changing text and graphics, my application does two things:
It keeps the screen on, at full brightness (via WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); and
It opens two DatagramSockets, one to act as a UDP client, and one to act as a UDP server. These sockets are both opened automatically and managed by the library I'm using, OSCP5. It's open source, so I can hack it as needed, though the less the better. (KISS.)
I've tested the Nexus 7 battery life with no apps running, screen at full brightness, with a tickle every 29 minutes to keep it from sleeping, for a few hours with no battery drain at all. So, signs seem to point to the sockets. I don't have frequent communication on those sockets, they receive approximately a few KB every minute (based on user interaction with another part of the installation).
Is there anything I can do, specifically with the sockets, or any other general testing, to minimize or eliminate the battery drain? I only need to get through 12 hours, but keeping full charge while plugged in doesn't seem like it should be such a tall order...
However, despite being plugged in and charging, my application drains the battery completely in about 8 hours (10-15% / hour).
What do you have the Nexus 7 plugged into? I think it can take advantage of a high-speed charging USB port, the kind you need for most tablets (Android + iPad). I could see your results being more likely if you have this plugged into a garden-variety USB port.
So, signs seem to point to the sockets.
They're certainly a candidate, though since the WiFi radio would probably say on while the device is charging anyway, I'd be a bit surprised. To me, this feels like a CPU issue, where you're busy-waiting or something rather than blocking.
Is there anything I can do, specifically with the sockets, or any other general testing, to minimize or eliminate the battery drain?
I'd see if Traceview points out where you're consuming lots of CPU time. I'd investigate the charging port issue. I'd modify your app to mock the socket work and try to see if your problem persists -- if it does, then the issue isn't the sockets.
Well, keeping the screen on full brightness will really suck down the power. The GPS will do it too; I think those are the two biggest power sinks.
Keeping the network radios busy and keeping the cpu busy will also suck down the power. I hope you're not busy-waiting in any of your software.
Other than that, all I can suggest is that you use the high-power charger that likely came with the tablet. USB data ports are limited to 500mA current, and I've worked with more than one device that can require more than that to keep the battery alive.
Three months and endless head-desk-banging later, it turns out the culprit was my USB run. The total length is around 20'-25', and the length is attenuating the power that gets all the way through the line. Solution: powered USB hub.
So, the answer ended up having nothing to do with Android or programming at all. Sorry, SO.
I'm contemplating the development of an Android app that detects all or most nearby mobile devices (iPhone, Android, etc) in the immediate neighborhood that are turned on. I don't need to interact with these devices, just detect them, and a requirement is that the detected devices can't need to have any special / unusual apps installed on them. The app only needs to work for typical U.S. devices and networks.
I've thought about a few ways to do this (somehow detecting bluetooth, wifi, or cellular transmissions / identifiers), but I'm looking for specific implementation methods for a way to detect a relatively large proportion of nearby devices. I'm not sure which of these methods is possible / feasible or how to put them into practice...
Perhaps using Bluetooth: Is there a way using the Android SDK to detect non-discoverable Bluetooth devices (not in discoverable mode)? The Nokia Developer site seems to suggest this is possible using Service Discovery Protocol (SDP), but I'm not sure if this is possible more generally in Android.
Perhaps using cell tower mast switching simulation? Ok, this is almost certainly beyond the reach of Android, but this article suggests that there may be a way to "mimic cell mast switching process to trigger quiescent phones into transmitting. Phones respond with their ID and authentication signals...".
I think you should see this, it is a paper, and you cannot view it for free, but in the summary, it clearly states:
Concerns about Bluetooth device security have led the specification of the “non-discoverable” mode, which prevents devices from being listed during a Bluetooth device search process. However, a nondiscoverable Bluetooth device is visible to devices that know its address or can discover its address. This paper discusses the detection of non-discoverable Bluetooth devices using an enhanced brute force search attack. Our results indicate that the average time to attack a non-discoverable Bluetooth device using multiple search devices and condensed packet timing can be reduced to well under 24 hours.
But for an android application, you need the detection time to be well under a few seconds instead of less than 24 hours, so a practical solution may not yet be available.
Is there an Android API for stop charging even though physically the charging is on?
Reading previous answers, it looks like there's no way to do this exclusively in software. However, it should be relatively easy to do it with a little hardware help - i.e. by using any Bluetooth- or WiFi-enabled smart electrical switch with open API. The phone could then switch the charger on or off programmatically whenever it feels like it.
Is there an Android API for stop charging even though physically the charging is on?
AFAIK no.
Justification:
android.intent.action.BATTERY_CHANGED is a protected intent that can only be sent by the system. Therefore you cannot duplicate or override the functionality.
You guys are all missing the point - the purpose of limiting charging is to increase battery lifespan by keeping it away from fully charged conditions (and near empty but that's a different issue). If you anticipate needing a full charge then tell it to charge to 100.
If you can't set a charge limit then the battery would rarely be idle and ideally charged when on the charger. It probably requires device level support though.
https://play.google.com/store/apps/details?id=es.guille.stopcharge uses echo "0" > /sys/class/power_supply/battery/device/charge. It works for me on a nexus 4 (rooted), as long as the device isn't fully charged (in a charging state).
Also relevant: https://android.stackexchange.com/questions/15001/how-can-i-avoid-the-battery-charging-when-connected-via-usb
Contrary to some answers indicating it's not possible, it is, indeed possible with ROOT. You can find some apps on the Play Store that will allow you to do this (with root permission, of course).
The best app that works on every phone I've tried it on is Battery Charge Limit. You can download it from the Play Store or the XDA discussion thread. The app is under active development so, if you find that your phone isn't supported, just submit an issue on its GitHub page.
NB: I am not the developer of this application.
This is unfortunately not possible. Android only have read APIs for battery data.
Battery charging control is internal to the Android kernel and battery IC modules. Manufacturers do change it from time to time, like HTC is having small cycles from 95-100% (a bad idea IMO), Samsung does stop charges as soon as it reaches 100%, but I've never seen a device able to stop charging before 100% to reduce battery aging :(.
At best if we're lucky, a sysfs interface might help do that, but it requires root and will differ from device to device.
Just to add to this. Samsung phones do not stop charging after 100%. As far as I'm aware they "trickle" charge past this point however they recommend you do not charge your phone past 100% for over 1 hour. Battery manufacturers like Anker also state the same so the idea of stopping the charge at 100% would be really useful. The risks of leaving the phone on charge are battery bloat and eventually cell rupture. I wasn't aware of this to start off with an killed my samsung battery within 3 months of owning the phone.
To expand on the original question. I've noticed some kernels allow fast charging. If they are able to alter the charge rate up could we alter the charge rate down (trickle) to meet a desired finish time (when your morning alarm goes off)??
I have installed a timer on the AC receptacle where I plug my Moto E's charger into. After guestimating how much time the battery needs to charge to about 85%, I set the timer. This is not my idea of a solution, but at least it keeps my phone from being charged to 100%, as I usually err on the short side when setting the timer.
I dont think there would be such an api. If it does exist it needs to be supported by the device manufacture as its not a pure OS lever feature. The same reason would make it a bad idea to use it as not all devices will support it.
That being said it would be a bad idea to use/implement it , mobile devices are not built to directly run from the power supply and a user will not plug in the cable if he/she did not want to actually charge the device.
I want to facilitate video-calling from the android device to another android device. My question is that can i connect the android WiFi device with the android WiFi device without any use of internet connection. I want to use it just like the Skype. is this possible or not? if it is possible then how can i implement it...can i get some code snippets as well???? Please give me link to download that app
First, your idea works completely different from Skype, which is completely dependent on a functional Internet connection for its core functionality.
Second, while you could create an ad-hoc WiFi network betweeen two Android devices, their range will be the limiting factor:
WiFi is intended as a short-range wireless medium. There's a reason nobody wanted the 2.4 GHz band (and therefore it is unlicensed): there's a significant noise and signal loss on these frequencies, noticeable even at short range.
Moreover, wireless equipment in mobile devices is engineered for power efficiency - which translates to lower broadcast power when compared to on-the-grid devices.
Also, the antennae in such devices are omnidirectional - this is rather useful for normal use, but again lowers your available broadcast power
Even if you had huge, high-quality directional external antennae connected to each device, pointing very precisely at each other (btw that also means each of them is stuck in one place; see e.g. this for a dish size calculator), you'd need to make some pretty drastic changes to their networking stack, as the latency inherent in long-distance comms will screw up TCP/IP pretty badly.
Even so, the setup would be very brittle, dependent even on the weather (water vapour absorbs significant amount of power in that part of the spectrum).