I'm currently working on an android project and I am trying to find the best way to go about setting up communication between two android phones.
One android phone will be docked on a mobile platform e.g. an R/C car. I want this phone to receive simple control signals ("forward", "backward", "left", "right", "gotoCoordinate") sent from another android phone. I also want the docked phone to be able to return status signals.
Preferably I want the communication to happen via GPRS. I'm aware of the difficulties concerning P2P-communications and I'm currently looking into "Android Cloud To Device Messaging." (http://code.google.com/android/c2dm/index.html)
I'd like to hear about your experience with Android C2DM (glad to hear about delay from transmit to receive) and your thoughts on utilizing it in my project. I'd appreciate other suggestions on how to go about this. I'm expecting to have to deal with relatively high latency using this method, but of course preferably lowest possible.
C2DM makes no guarantee about the "delivery or order" of the messages, and it is limited in the number of messages you can send (a high limit, but still a limit). It's not really for low-latency stuff like controlling an RC car. It's better for non-realtime events.
http://code.google.com/android/c2dm/
For lower latency stuff using GPRS you can setup a third party server on your own and have both phones communicate through it. I've done that for several Android apps using straight up TCP sockets and it works reasonably well (and it would be even faster/better if you went UDP). Using GPRS may still have too much latency, depending on your needs, but it's a tradeoff (it's very convenient, almost always there, other methods are not).
The ideal way to do this would be to combine whatever is available and fallback gracefully, and test the latency once connected to make sure the network is up to par, or bail out. For example, use the local WiFi network if it's available. That is to say, have both devices "register" with a third party server as they startup, then if they're both on the same WiFi just have them communicate directly (run a server on or both, and clients on one or both, get information about discovery and such from the registration). If they are not on WiFi then fall back to GPRS, but realize there will be more latency, of course. Finally, once any method has been established send some test messages to check latency.
I know this isn't really an "answer," it's more of a stream of consciousness about this, but it wouldn't fit in a comment, and I thought it might help ;).
(Full disclosure: I've worked on Android apps that connect multiple mobile devices and multiple TVs, some over GPRS, some Wifi, some directly. I work for a company (MOVL) that makes a platform for stuff like that, it's more focused on mobile-TV-mobile, but it supports mobile-mobile also. In all it's not too hard to do yourself with regular networking, the tricky part is getting the latency down and picking the correct method for each device.)
Related
I'm developing a mobile app that uses WiFi without internet connection (in order to communicate to an IOT device) and it uses cellular data as well (see TL;DR section for more).
The problem -> some devices don't automatically switch their default route to cellular (rmnet interface) while others are capable.
The workaround -> create a *"local" VPN in order to manage and re-routing network traffic via cellular interface (there are apps like Speedify that can do this by assigning priority to interfaces)
The question -> there is a simple way to accomplish this or it's pretty tricky? When I say "simple" I mean the calls of several well documented API and when I say "tricky" I mean to starting read and parse routing table with customized rules depending on every vendors?
"*local" = a VPN without web server or VPN gateway because I'm not actually interested to do the VPN's job (I seem to have understood that I need a VPN level to manage network traffic of others app but I'm pretty newbie of VPN topic)
TL;DR
My goal is to remaining connected to my access point (in order to call its APIs) AND use cellular data for all others requests I.e: login via my backend, use Google Maps and so on.
Handle this scenario it's quite easy because combining network objects, socketFactory and bindProcessToNetwork I'm able to do this.
Troubles come for others app like YouTube, WhatsApp that stop working because as default network they are using my access point without internet (Android doesn't switch default interface to a cellular)
I'm going crazy because seems that each vendor (or Android OS version?) handles "WiFi without connectivity" with cellular active in a different way.
There are certain devices that all work fine (similar to iOS) but there are others that it's a nightmare.
See this question for further details
Thanks for reading, I really love Android but those issues make me sadder every day more and I'm thinking to pass to the Dark Side of mobile development (iOS).
You've the chance to change my mind ;)
Let's say I have an Android device which supports GSM 800/900Mhz bands and I want to use it as a transmitter to remotely control a car or anything else.
Is it possible to program such a thing on Android ? Maybe using NDK ?
The purpose would be to send custom packets on these frequencies.
Thanks.
There are a lot of misunderstandings in this concept, however what you're thinking of quite nice, assuming it would be possible (which isn't :( ).
RF communication is handled EXCLUSIVELY by the modem software, which is included in the baseband binaries.
You cannot simply tap into it, and send whatever you like, since the protocol and its transport layer are very strict to comply with the GSM rules.
Also - since baseband binaries are under strict control there are very few, to none custom ones.
There are also WAY many other reasons why this is not actually possible, without lots of hackish work. Those devices are made strictly to perform on the GSM network. You could use another reciver to for example send WAP push messages (in raw form) as commands, however expect the delays to be HUMONGOUS (ie. 1second - 20 seconds) which is not viable for any kind of remote control. Same results as SMS communcation, just in an unrestricted form.
CAUTION: Using telecom broadband channel is BANNED for public use in most countries, so even if you get an external GSM bands transmitter (which actually can be done), you still would need to comply to your countries regulations.
Possibly related thread: https://electronics.stackexchange.com/questions/94668/longest-range-remote-control
I'm developing an none market appliction which run on 20-30 android devices (target specific to tablets with android honeycomb / ICS OS) maintaining connection over local WIFI network for a 1-2 hours period of time, and need to exchange data (simple objects representing commands) between them.
most of the time one specific tablet behave like a server which sending the commands, and the other devices like clients which receives the commands, but the "clients" also sending commands to the "server" sometimes.
as solution to this communication demand - I'm using for a while an open source
library which encapsulates TCP client/server protocol, called - Kryonet.
I found it very easy to use, and basically doing the job, although it sometimes "unstable" - a lot of disconnections accrues. I can't afford this disconnections, it's dammege the whole flow and use-case, causing the client's to lose commands.
I'm doing some recovery logic which re-connect the clients and send them what they have missed, but it's not good enough for the use-case.
recently I've heard about multicast broadcast protocol, and found even an open source library calls - JGroups which implement this protocol optimally, and expose easy and simple to use interface. still didn't tried it, but got advice from someone who knows, saying it should be better the the TCP client/server for my purpose.
what is the best approach I should use for implement the behavior I described ? (not necessarily one of the two I suggested)
TIA
Although JGroups has promise as a better solution for your situation, you may want to experiment a bit more to determine why the disconnects are happening. Since your clients and server are all tablets, there are a few other causes that are unrelated:
1) If the connections are not being maintained in a Service then they will be extremely unreliable by default. (See this question about singletons being destroyed in Android)
2) If the sockets have not been set to 'keepalive' then they will time out after an arbitrary number of seconds.
3) The devices you are using may shut down some persistent connections when they go to sleep.
4) The tablets may be exiting WiFi range, and switching over to a mobile network.
Try the network portion of your code on a number of desktop machines to determine if the problem is with Kryonet or your code, or if the problem is in running it on Android.
Is it possible to set up the Android Bluetooth Chat sample app to connect more than one person at a time, and have a mini chat room? What would that entail?
tl;dr version: Bluetooth sucks for this, don't use it, use wifi instead, probably backed by a web backend.
I have investigated this issue thoroughly throughout the years in the interests of a social wireless network research project. My general advice is: it doesn't work with more than two / three people. Bluetooth just isn't designed with wireless peer to peer networks in mind.
In general, it seems that the cheap Bluetooth controllers included on Android devices (especially HTC's devices, iirc) don't really handle any more than two or three connections at a time. I'm unsure if this is a hardware or firmware problem, but I can recount some basic anecdotes. I was working to implement this idea at the SDK level (i.e., without firmware modifications) around the beginning of 2011, and was able to get a peer to get two additional connections (i.e., three devices, each connecting to the other two) to work for a period of a few minutes to an hour before the connections would suddenly die and the socket would become unusable, requiring reconnection. Unfortunately, 20 minutes was an upper bound, and generally it was impossible to get connections to more than one other device at all reliably.
The goal of the project was to support multiple people interacting with each other silently in the background, but this never materialized, instead we ditched Bluetooth and went with wifi instead, which worked much much better. In the abstract, I think people view Bluetooth as a possible medium for reliable peer to peer communication, but it wasn't really designed that way: it's more of a medium used for short range communication between small devices (think headsets).
Be aware that if you want to do this, the maximum number of devices to which you can connect is fixed, because as per the Bluetooth spec, a piconet supports a maximum of seven devices. (See the wikipedia article.)
The required change is simple: you use a different UUID for each device. This can be implemented a number of ways, using an out of band exchange mechanism, or simple scheme where you assign UUIDs in an increasing fashion and when connecting to the network, try each in succession.
Here are some relevant Google groups threads:
Bluetooth peer to peer networks
Multiple connections on Android Bluetooth
I remember posting a more elaborate one detailing how to do this (with code) that I might dig up as well.., if I can find it. It should be from late 2010 or early 2011.
So the answer is, in the abstract, yes, you can try to do this, by using multiple UUIDs (after you use one, that's it, and you have to try another using some assignment protocol). However, in practice, after a lot of trial and error, this doesn't really work for what you probably want to use it for, and it's a lot better to go with an internet backend instead. By the way, this is also good for another reason, most users don't really like to turn on their Bluetooth for fear of their battery being drained..
Leaving this here, in case it helps someone else.
I was able to make my custom chat room following official bluetooth tutorial and modifying it a little.
Unfortunately, I cannot provide most of my code, but main idea is:
Every device is acts both as server and as a client. When Chat is started, device starts its server thread. Server thread is the same as official but doesn't ends when accept connection. It just keep listening.
Client thread is identical as in tutorial.
Both server and client thread manages connection same. I created separated threads for accepting messages following this tutorial and one for sending them.
private void manageConnectedSocket(BluetoothSocket socket) {
//create thread responsible for sending messages.
SendingThread w = new SendingThread(socket);
MainActivity.addSendingThread(w);
//Creates listener for messages to accept.
MainActivity.addListener(socket);
}
Now in main activity always when user click send button, for each worker (sending thread) send message to remote device. Listening is running asynchronously.
IMPORTANT:
You need to handle exceptions when message send fails and remove sending and recieving thread for device when you detect it is disconected. In my case I used well known UUID "00001101-0000-1000-8000-00805f9b34fb". For every device.
You need to wait 3 second between atempts to connect as client because some devices has weak bluetooth hardware and it is refusing connect as client.
Bt connection is supporting up to 7 -10 connections. So you will be limited in that range. I think it is designed for extensions of main device and not for random comunication
Source: search "bluetooth programming" on google
can anybody confirm what are the currently allowed methods for peer-to-peer communications within the Android framework? I need to transfer json strings and I'm currently using SMS which works ok but the problem is that the data also ends up as lots of text messages. I've read Reto Meier's first edition of Professional Android Application Development where he says that the data transfer options were not implemented due to security concerns.
Has this changed at all and how would you do peer-to-peer transfer of data?
Have you looked at Qualcomm's AllJoyn library? It is designed to work over Bluetooth or wifi, so may fit, though if you're connecting over 3G or wider range networks it won't work.
Given the variation and reliability of networks between two remote devices not on the same network, I'd question whether peer-to-peer is the best solution, and would venture to suggest considering using an application server in between, so you could then use Cloud to Device Messaging [deprecated] (perhaps in tandem with Google App Engine). i.e. to send a message the sender passes it to the server, and the server then passes it on to the recipient.
In theory all devices on the net have a unique IP address and can talk to each other, but it's rarely that simple as routers/firewalls are configured differently so you'd need to pay great attention to the ports you use, especially considering many inbound ports are blocked by default for security reasons.
You can simply use UDP/TCP sockets. In a separate thread you set up the server-side listener socket and that's it. Of course your application has to be started first (or should run in the background all the time). Here's an example:
http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/
If you also need peer discovery that will make the thing more difficult.
You should also take a look at peerdroid, an open source project available here. I've been looking in to peer communication options from the point of view of having a collection of federated devices (pre-paired, if you like, similar to Bluetooth pairing); this library looks like it may give you the foundation for what you are trying to do.
If you are on your own network (for example a home or office WiFi) then you should be able to query for other connected devices. If the network you are on is not under your control (the mobile network or a public wifi) then the network will have been configured to isolate each device from everything else. In this case you will have no choice but to put a server up to act as the man in the middle. That brings its own architectural compromises - every device has to regularly poll the server or keep a connection open - unless you use Google App Engine which supports push notifications over Google's own infrastructure.
Thanks for your answer ldx but I would need peer discovery as you indicated. Some further research appears to indicate XMPP as a suitable technology and there are now some services on offer, although these appear to be aimed at 'server' to client notifications. There is a good discussion here on XMPP and some more here although it would appear that there are still some issues to deal with such as polling v push, long-running open http connections and battery life. Xtify looks promising, especially their web service. I hope this provides suitable information to others looking at the topic of peer-to-peer data communication.