I have a bit of a unique issue. I'm collaborating with several other Computer Science Majors at my university on an Android Metronome app that allows two users with the app to sync metronomes. Right now, I can send the desired beats per minute of the metronome from one phone to the other and both phones will start to play their respective metronomes. Due to the latency of Bluetooth, the metronomes are only in sync about 20% of the time.
So, here's where the problem is. We're trying to make it so both of the metronomes will start at the exact same time. One way I've thought of doing this is once the first user presses the send button on their phone, a time stamp will be created. This time stamp will be exactly two seconds after the user presses the send button. The time stamp will then be sent to the second phone and the phone will utilize this time stamp to start it's metronome at the same exact time as the first phone. I've tried accomplishing this by putting UTC time in a while loop and then constantly checking the time, to no avail. Does anyone have any ideas as to how we can go about implementing this? I couldn't find any similar problem on StackOverflow, or any other website for that matter.
It's a bit late probably for your project, but if interested. This is a bit long, it's more like a case study.
If your project was about syncing two device clocks remotely, then this won't help you, but if it was about syncing the metronomes, then this may be a start.
First, getting millisecond accurate timings and callbacks in android using java is next to impossible, since android is not a real time system ( All sleep methods and timer might not execute on the exact millisecond you're expecting ). You may want to go with NDK for triggering your beat events, because native threads in android can achieve that, but if you're happy with your single metronome implementation, then that's good enough to read the rest of this .
Full disclosure :
I am the author of JAM the app referenced in the answer I just published a few days ago.
I ran into the same problem when developing the app.
And whether this answer will help you or not, depending on your situation.
and if you're going down the "clock sync" route ( Which I do plan on exploring to improve my app down the road with more features ) but the solution that I found did not involves time sync.
I will mention my approach and then state what I found as advantages/disadvantages for each of the methods .
Instead of syncing clocks ( A very difficult problem, especially for what the app was supposed to do , and that is trigger ticks on multiple devices at the "same" time ) I opted for a subscribe/publish model, where multiple devices can "subscribe" to a host device via bluetooth, and the host device controls and "publishes" the metronome beats.
most times sending a few hundred bytes ( Enough information about each beat ) via bluetooth takes less than 2ms , it could spike up to 10 and sometimes even 30, but that rarely seems to happen .
That approach took care of the syncing problem, now I can send beat events from one device to another in 2ms , and if some sort of delay happened, it will self correct once the interference is gone, because the other event comes in time.
However that approach does require constant connection, you can't start and separate the devices later on, but it's much easier to implement.
Now the interesting part, the problem I never thought of when starting this, and that was the Android 10 millisecond audio path latency problem. I'm not affiliated with superpowered, but I did use their engine in my app to deal with that problem .
To summarize :
Metronome sync over bluetooth in Android has two issues :
1 - triggering beat events simultaneously ( or within acceptable latency )
2 - The beat event should trigger sound events with minimal delay after the beat event is received
#1 is related to the original question, #2 I thought was an important addition to the original problem this question is asking.
I would use (S)NTP to check the clock drift to a public time server. After that I would just send the interval and a start time and let the devices calculate the interval individually. So you just need to sync changes and relay on the clocks of the individual devices. Together with the now known clock drift you can fix this error.
Related
I am using google Nearby connections to create a P2P network using the Star strategy and I was wondering if it is possible to set the advertising device to stop advertising after a 5 minutes.
You could set up a thread, with a timer. If the timer reaches 0, and you are advertising, then call the corresponding stopAdvertising() method.
Besides this, keep in mind that the user should be aware when the device is advertising via an icon or a special screen. This is stated in this video (they talk about nearby messages, rather than connections, but the best practices still apply).
What I mean, is that it would be odd to have the user waiting for 5 minutes in the same screen while advertising. Most likely he quits before the 5 minute window has passed, at which point you must also stop advertising. If you think in your application the user might stay in the advertising screen for over 5 minutes, then use the counter in a thread.
so i guess title is pretty self explanatory, i have an app where i need to make a phone call and after it rings certain amount of times (let's say 2-3), i need to hang up to leave a missed call.
With some help from already created topics, i can make a phone call and hang up, but only after certain amount of seconds, not ring tones. Problem with seconds timer is, you cannot be certain if ringing already started.
Is there even a way in API to let me know when the phone rings?
This SO article deals with the exact same issue.
As of now there is no public API that can detect the ringing on the other side of the call.
I am trying to roll out my own SMS verification system for my app. I don’t want to start paying for a service and then have them jack up the price on me (Urban Airship did that to me for push notification: lesson learned). During development and beta testing I have been using Twilio with a very basic setup: 1 phone number. It worked well for over a year, but right now for whatever reason the messages aren’t always delivered. In any case I need to create a better system for production. So I have the following specs in mind:
600 delivered SMS per minute
zero misses
save money
Right now my Twilio phone number can send one SMS per second; which means the best I can handle is 60 happy users per minute. So how do I get 600 happy users per minute?
So the obvious solution is to use 10 phone numbers. But how would I implement the system? My server is App Engine, DataStore, Java. So say I purchase 10 phone numbers from Twilio (fewer would of course be better). How do I implement the array so that it can handle concurrent calls from users? Will the following be sufficient?
public static final String[] phoneBank = {“1234567890”,”2345678901”,”3456789012”,”4567890123”,…};
public static volatile nextIndex;
public void sendSMSUsingTwilio(String message, String userPhone){
nextIndex = (nextIndex+1)%phoneBank.length;
String toPhone = phoneBank[nextIndex];
// boilerplate for sending sms with twilio goes here
//…
}
Now imagine 1000 users calling this function at the very same time. Would nextIndex run from 0,1,2…9,0,1…9,0,… successively until all requests are sent?
So really this is a concurrency problem. How will this concurrency issue work on Java AppEngine? Will there be interleaving? bottlenecking? I want this to be fast on a low budget: At least 600 per minute. So I definitely don’t want synchronization in the code itself to waste precious time. So how do I best synchronize calls to increment nextIndex so that the phone numbers are each called equally and in a periodic fashion? Again, this is for Google App Engine.
You need to use Task API. Every message is a new task, and you can assign phone numbers using round-robin or random assignments. As a task is completed, App Engine will automatically pull and execute the next task. You can configure the desired throughput rate (for example, 10 per second), and App Engine will manage the required capacity for you.
You can try to implement something similar on your own, but it's much more difficult than you think - you have to handle concurrency, retries, instance shutdowns, memory limits, etc. Task API does all of that for you.
I invest my few days but not getting the correct answer.
I am developing an application in which 12 tracks should executes parallely and they are, but my problem is that the start time is not same.
Actually my question is about to sync my 12 tracks. All the tracks start at one time, there should not be millisecond difference between all tracks. If there any difference occurs then tracks mixing can not be done perfectly.
My code which play all the tracks on button click.
mp1_track_a.start();
mp1_track_b.start();
mp2_track_a.start();
mp2_track_b.start();
mp3_track_a.start();
mp3_track_b.start();
mp4_track_a.start();
mp4_track_b.start();
mp5_track_a.start();
mp5_track_b.start();
mp6_track_a.start();
mp6_track_b.start();
It is not possible to have a prallele work as you ask with a single processor with one core (you must consider the less power android device). Even tough you have multiple thraeds, in the reallity they will work sequencially.
For my application, I want to have a Notification sent to the user at a specified time. To do this, I have set up a Timer and the corresponding TimerTask.
To be sure the Notification will be sent to the user even if the phone is aslept, I have acquired a PARTIAL_WAKE_LOCK. The problem is that this method draws a lot of power from my battery (my application is responsible for more than 50% of all the power consumption at the end of the day).
Is there another way (a more power efficient one of course) to do what I want to do?
Thanks in advance for the time you will spend trying to help me.
> Is there another way (a more power efficient one of course) to
> [have a Notification sent to the user at a specified time]?
You can use an the android AlarmManager for this.
See Using AlarmManager to Schedule Activities on Android as a tutorial and example.