Android - How to maintain 3g connection when wifi available - android

My app connects with a persistent connection to a server. If the device is currently using 3G it will connect over 3g.
The problem is that if it connected using 3G and moved into wifi the connection drops. How do I prevent it from disconnecting?

Sounds like the server is unable to accommodate clients seamlessly switching to a different IP address, or it may be using something like keep-alive packets to maintain connection state, and when the 3G connection drops, it disconnects your session.
This may not be something you have control over. From the Android point of view - the device will prefer WiFi depending on user preferences and you will likely not have any direct control over that either.
In a nutshell - if you can't modify or reconfigure the communications protocol to allow client IP changes on the fly, then there's nothing you can do with Android to mitigate the problem.
All mobile devices, and to a lesser extent, desktops/laptops will at some point change their public facing IP address, so it sounds like a bug or oversight in the server/protocol design to me.
EDIT:
In response to your comment, and in the interests of UX, you should be very careful about finding a way to force your app (possibly even the entire device) to remain on 3G when the user has requested that it use WiFi.
Most people have capped data plans with their device and wouldn't be very pleased if they think they are using WiFi (which is most likely free, or at least no additional cost) when in fact you've forced their device to continue using potentially very expensive 3G data instead.
This is especially important when any method would likely be actively circumventing the reasonable limits the Android environment presents you with, and therefore would probably not be flagged as a "Service that costs you money" when installed.
EDIT 2:
So, there may be a way for you to do it, but it relies on unsupported, private Android APIs which may change at any moment - usual disclaimer applies.
Take a look here where they access the ConnectivityManager object to allow you to enable mobile data.
This method does require you to build against the Android source tree, and use a shared user ID with "system" so may or may not be suitable, but these APIs are private (as apps are not supposed to be able to do this without user action), but it may help you.

This is how Android works. You're app should not maintain a persistent connection, it should only open a connection when needed.

Related

Android VPN, how specify interface which to send through

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 ;)

Why is it not possible to connect Android directly with Oracle [duplicate]

Can someone answer on my dilemma which method to use for connecting Android device to mySQL or Postgresql?
I can do it in both ways without any errors and problems, with no noticeable difference but everyone recommend web service instead of using jdbc driver and direct connection,
Can someone explain why with some facts?
EDIT: I did'n mention that is more simple and needs less time to do it over jdbc. So, why web service, or why not?
You think it's simpler and faster to do it with JDBC because you aren't considering the real world operating environment of phones and portable devices. They often have flakey connectivity through buggy traffic rewriting proxies and insane firewalls. They're typically using a network transport layer that has high and variable packet loss rates and latencies that vary over many orders of magnitude in short spans of time. TCP really isn't great in this environment and particularly struggles with long lived connections.
The key benefit of a web service is that it:
Has short-lived connections with minimal state, so it's easy to get back to where you were when the device switches WiFi networks, to/from cellular, loses connectivity briefly, etc; and
Can pass through all but the most awful and draconian web proxies
You will routinely encounter problems with a direct JDBC connection. One challenge is reliably timing out dead connections, re-establishing sessions and releasing locks held by the old session (as the server may not decide it's dead at the same time the client does). Another is packet loss causing very slow operations, long-running database transactions, and consequent problems with lock durations and transactional cleanup tasks. You'll also meet every variety of insane and broken proxy and firewall under the sun - proxies that support CONNECT but then turn out to assume all traffic is HTTPs and mangle it if it isn't; firewalls with buggy stateful connection tracking that cause connections to fail or go to a half-open zombie state; every NAT problem you can imagine; carriers "helpfully" generating TCP ACKs to reduce latency, never mind the problems that causes with packet loss discovery and window sizing; wacky port blocking; etc.
Because everyone uses HTTP, you can expect that to work - at least, vastly more often than anything else does. This is particularly true now that common websites use REST+JSON communication style even in mobile web apps.
You can also write your web service calls to be idempotent using unique request tokens. That lets your app re-send modification requests without fear that it'll perform an action against the database twice. See idempotence and definining idempotence.
Seriously, JDBC from a mobile device might look like a good idea now - but the only way I'd even consider it would be if the mobile devices were all on a single high-reliably WiFi network under my direct control. Even then I'd avoid it for reasons of database performance management if I possibly could. You can use something like PgBouncer to pool connections among many devices at the server side so connection pooling isn't a big problem, but cleanup of lost and abandoned connections is, as is the tcp keepalive traffic required to make it work and the long stalled transactions from abandoned connections.
I can think of a few reasons
JDBC android driver support for your database.
Connection pooling across various Android devices make it difficult to monitor and cap them.
Result sets sent from the DB to android will consume a lot of bandwidth and battery power.
Proxies usuall allow HTTP access to your device.
Exposing your database directly to the client has security implications.
Web services can provide additional features on top of the JDBC connection like authentication / quality of service / authorization / conditional GET requests / error handling etc. JDBC cannot do any of these.
Besides all things Craig Ringer said, which I completely agree, JDBC has another problem: it will force to expose your database to the world. If you want android devices to access it, you will need to provide your app with database credentials, and the database will have to have public access.
Using a WebService or RESTful API is clearly the way to go to make your application secure.
Another option would be to use a database sync tool like SymmetricDS.
This would let you have say a Postgres database on your server, and a SQLite database on your tablet.
SymmetricDS would synchronize the databases over HTTP, when a connection is available. You don't have to sync the whole db of course, just the relevant parts.
(I am not affiliated with SymmetricDS)
TL;DR: It depends!
(Sorry to all the "never ever ever ever do it, direct conns are always evil"-devs)
When creating a public domain / general app for the playstore kind of thing, I am mainly with my fellow responders. Opening your DB to "everyone" (especially when permissions are badly or not at all configured) is typically not a great idea!!
However(!), the story might be totally different, when you e.g. create something for internal use within the network boundaries of your company, like Android handheld devices for logistics, inventory, etc. In these cases I would even most of the time definately recommend going with JDBC or a similar direct connection. Reaons being:
One less point of failure
One less development (sub-)project
One less thing to maintain and keep up to date with your data-structure
One less thing to keep up and running, CI/CD, test, etc. (you get the draft)
Which - im my humble opinion - is worse than the (implement it once) effort of connection pooling, reestablishment, etc. (if it really becomes necesseary, be careful with premature optimization there).
But for public projects ... well, if they only ever require read access, I could possibly imagine it as well, or if there are only certain tables were you allow adding, but not delete or modifications. There are some tricks you could apply to make it still secure (allowing adds but not reads with id-secrets for a certain table, triggers, and general reads for other tables, etc.), but there is a lot to think and a lot to miss about these. So generally, I would say it is bad practice to allow your public domain client to get hold of your SQL connection. But still, don't let that hinder you to ask yourself (and understand) "why" and look at the specific situation. There might even be good cause/use for that. Especially since it is "less", which is also often better. It definately depends.
Just be careful and aware that (even if permissions are set correctly) a lot can be misused (and only little hindered), with a direct connection at your client. (Plus possible connection issues to be taken care of.)
As a sidenote: A lot of these considerations are relevant again with the use of technologies like GraphQL, which shares some similarities (however without connection issues and with a little bit more secure control).

JDBC vs Web Service for Android

Can someone answer on my dilemma which method to use for connecting Android device to mySQL or Postgresql?
I can do it in both ways without any errors and problems, with no noticeable difference but everyone recommend web service instead of using jdbc driver and direct connection,
Can someone explain why with some facts?
EDIT: I did'n mention that is more simple and needs less time to do it over jdbc. So, why web service, or why not?
You think it's simpler and faster to do it with JDBC because you aren't considering the real world operating environment of phones and portable devices. They often have flakey connectivity through buggy traffic rewriting proxies and insane firewalls. They're typically using a network transport layer that has high and variable packet loss rates and latencies that vary over many orders of magnitude in short spans of time. TCP really isn't great in this environment and particularly struggles with long lived connections.
The key benefit of a web service is that it:
Has short-lived connections with minimal state, so it's easy to get back to where you were when the device switches WiFi networks, to/from cellular, loses connectivity briefly, etc; and
Can pass through all but the most awful and draconian web proxies
You will routinely encounter problems with a direct JDBC connection. One challenge is reliably timing out dead connections, re-establishing sessions and releasing locks held by the old session (as the server may not decide it's dead at the same time the client does). Another is packet loss causing very slow operations, long-running database transactions, and consequent problems with lock durations and transactional cleanup tasks. You'll also meet every variety of insane and broken proxy and firewall under the sun - proxies that support CONNECT but then turn out to assume all traffic is HTTPs and mangle it if it isn't; firewalls with buggy stateful connection tracking that cause connections to fail or go to a half-open zombie state; every NAT problem you can imagine; carriers "helpfully" generating TCP ACKs to reduce latency, never mind the problems that causes with packet loss discovery and window sizing; wacky port blocking; etc.
Because everyone uses HTTP, you can expect that to work - at least, vastly more often than anything else does. This is particularly true now that common websites use REST+JSON communication style even in mobile web apps.
You can also write your web service calls to be idempotent using unique request tokens. That lets your app re-send modification requests without fear that it'll perform an action against the database twice. See idempotence and definining idempotence.
Seriously, JDBC from a mobile device might look like a good idea now - but the only way I'd even consider it would be if the mobile devices were all on a single high-reliably WiFi network under my direct control. Even then I'd avoid it for reasons of database performance management if I possibly could. You can use something like PgBouncer to pool connections among many devices at the server side so connection pooling isn't a big problem, but cleanup of lost and abandoned connections is, as is the tcp keepalive traffic required to make it work and the long stalled transactions from abandoned connections.
I can think of a few reasons
JDBC android driver support for your database.
Connection pooling across various Android devices make it difficult to monitor and cap them.
Result sets sent from the DB to android will consume a lot of bandwidth and battery power.
Proxies usuall allow HTTP access to your device.
Exposing your database directly to the client has security implications.
Web services can provide additional features on top of the JDBC connection like authentication / quality of service / authorization / conditional GET requests / error handling etc. JDBC cannot do any of these.
Besides all things Craig Ringer said, which I completely agree, JDBC has another problem: it will force to expose your database to the world. If you want android devices to access it, you will need to provide your app with database credentials, and the database will have to have public access.
Using a WebService or RESTful API is clearly the way to go to make your application secure.
Another option would be to use a database sync tool like SymmetricDS.
This would let you have say a Postgres database on your server, and a SQLite database on your tablet.
SymmetricDS would synchronize the databases over HTTP, when a connection is available. You don't have to sync the whole db of course, just the relevant parts.
(I am not affiliated with SymmetricDS)
TL;DR: It depends!
(Sorry to all the "never ever ever ever do it, direct conns are always evil"-devs)
When creating a public domain / general app for the playstore kind of thing, I am mainly with my fellow responders. Opening your DB to "everyone" (especially when permissions are badly or not at all configured) is typically not a great idea!!
However(!), the story might be totally different, when you e.g. create something for internal use within the network boundaries of your company, like Android handheld devices for logistics, inventory, etc. In these cases I would even most of the time definately recommend going with JDBC or a similar direct connection. Reaons being:
One less point of failure
One less development (sub-)project
One less thing to maintain and keep up to date with your data-structure
One less thing to keep up and running, CI/CD, test, etc. (you get the draft)
Which - im my humble opinion - is worse than the (implement it once) effort of connection pooling, reestablishment, etc. (if it really becomes necesseary, be careful with premature optimization there).
But for public projects ... well, if they only ever require read access, I could possibly imagine it as well, or if there are only certain tables were you allow adding, but not delete or modifications. There are some tricks you could apply to make it still secure (allowing adds but not reads with id-secrets for a certain table, triggers, and general reads for other tables, etc.), but there is a lot to think and a lot to miss about these. So generally, I would say it is bad practice to allow your public domain client to get hold of your SQL connection. But still, don't let that hinder you to ask yourself (and understand) "why" and look at the specific situation. There might even be good cause/use for that. Especially since it is "less", which is also often better. It definately depends.
Just be careful and aware that (even if permissions are set correctly) a lot can be misused (and only little hindered), with a direct connection at your client. (Plus possible connection issues to be taken care of.)
As a sidenote: A lot of these considerations are relevant again with the use of technologies like GraphQL, which shares some similarities (however without connection issues and with a little bit more secure control).

using android mobile as a server

I am developing a turn based two player android game. Is it possible to use one of the user's mobile as server rather than an external server to coordinate the game ?
I do not need much data storage. only 40 fields(text or numbers) to be stored and transmitted (for transmission , one value at a time) while the game is on. after game is over only user's current score is to be stored.
I guess to do any such thing I need to get ip of the mobile. Is it possible ?
You need more than just the IP since the IP is just an endpoint on the Internet and there is no guarantee that it is your device that answers if you talk to that IP. There is usually a local network behind that IP and you can't access devices in there with just the public IP.
The problematic part is establishing a direct connection which is (usually) not possible on the Internet unless you are in control over the Internet connectivity (router etc) and can setup port forwardings / firewall rules / whatever blocks direct connections. If you have no access - for example because you use 3G where the "router" is at your provider's datacenter - you will need at least a server to do things like hole punching.
Also a server used to find other's games (and IPs) would be a good idea.
You can however do all that if both devices are on the same WiFi and they can see each other directly.
I am from Skiller and I think we have exactly what you need.
#zapl is right, if you want your players to connect to your games using 3G or WIFI connection the best solution will be intermediate server that makes it possible to exchange data between the players. Setting up, hosting and scaling such a server may be very expensive and time consuming thing. We provide FREE SDK tools, using which you will be able to set up your turn based two player game in no time. We are handling all the server side maintenance so you could just implement the game logic and fire your game to the market asap.
Download the SDK from www.skiller-games.com and tell me what you think.
If you have any questions write us here or to developers#skiller-games.com

Android Communication: Phone to Phone Application Control over 3G

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.)

Categories

Resources