How to respect network use settings in Android - android

My app performs some backgound data collection and I'm adding support for the user network preferences, such as performing background updates and data roaming. I have the following checks already:
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if(cm.getBackgroundDataSetting()) {
...
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()) {
with the required entries in the manifest:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
This all appears to be working fine, but I was wondering if I should be checking anything else? I was worried about checking for data roaming but the docs state that networkInfo.isAvailable() checks this for me. So are there any other checks I need to implement for network settings? Anything else in this area I should be aware of?

The user may change the settings while your background app is running. The API recommends that you listen to the broadcast message:
ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED
Perhaps you are checking cm.getBackgroundDataSetting() prior to sending data, and I suspect this would be sufficient. However, listening to the broadcast message will let you resume sending background data when the settings are changed.
I believe that either listening to the broadcast message or checking the settings before sending data will suffice. Android docs recommends the former.

Additionally to your checks I also do check for roaming state for 3g network:
NetworkInfo info = m_connectivityManager.getActiveNetworkInfo();
int netType = info.getType();
int netSubtype = info.getSubtype();
if (netType == ConnectivityManager.TYPE_WIFI || netType == ConnectivityManager.TYPE_WIMAX)
{
//no restrictions, do some networking
}
else if (netType == ConnectivityManager.TYPE_MOBILE &&
netSubtype == TelephonyManager.NETWORK_TYPE_UMTS)
{
//3G connection
if(!m_telephonyManager.isNetworkRoaming())
{
//do some networking
}
}
My application uses a lot of data, so I do not allow data downloading on non-3g mobile networks.

Like #inazaruk, I a also trying to prevent (for the user possibly expensive) network transfers when roaming or downloading images while on GPRS only. Therefore in Zwitscher I've implemented a NetworkHelper that checks against users preferences on romaing and minimal network state; https://github.com/pilhuhn/ZwitscherA/blob/master/src/de/bsd/zwitscher/helper/NetworkHelper.java
The matching preferences are here: https://github.com/pilhuhn/ZwitscherA/blob/master/res/xml/preferences.xml#L30

Related

How to access Muliple network interface in android (WiFi and mobile data)

Ok, so my question is may be off topic but i really did not found any useful content to use both network interface simulnasily in my application is simple image uplaod to server using both open network for better speed.here can we use both network by programing in java?
i found this code snippet but its return only connection status.
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
Network etherNetwork = null;
for (Network network : connectivityManager.getAllNetworks()) {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
if (networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
etherNetwork = network;
}
}
Network boundNetwork = connectivityManager.getBoundNetworkForProcess();
if (boundNetwork != null) {
NetworkInfo boundNetworkInfo = connectivityManager.getNetworkInfo(boundNetwork);
if (boundNetworkInfo.getType() != ConnectivityManager.TYPE_ETHERNET) {
if (etherNetwork != null) {
connectivityManager.bindProcessToNetwork(etherNetwork);
}
}
}
As far as I know it is not possible.
Nevertheless:
MPTCP exists, and you may find roms that support it, but it is not out of the box.
Speedify claims to be able to do it, but since it doesn't require root, I assume it's just a clever use of a VPN connection and a sort of load balancing trick between connection types.
Basically, in order to really have the 2 connection types active, you would need to modify the kernel so that both network interfaces can be used at the same time.
You can follow the approach I'm using in this app if it helps
https://github.com/yschimke/OkHttpAndroidApp/
You can bind each socket yourself to a specific network interface before you connect. Each individual socket needs to be on a single network, but you can use both.
https://github.com/yschimke/OkHttpAndroidApp/blob/master/android/app/src/main/java/com/okhttpandroidapp/factory/AndroidNetworkManager.kt#L123

Background IntentService Force Closes because device is connected to WiFi but is not authenticated

I am currently using a background IntentService in my Android App to connect to my server to fetch some data and update the App only if connection is available. If the device is connected to mobile network data or a authenticated wifi connection or open wifi connection it works perfectly.
The problem occurs when the device does not have access to Mobile Data Network and is connected to a Wifi source that requires authentication and the connection is not authenticated yet, the service force closes since it is unable to transfer any data through the unauthenticated connection.
My check to the entry point to connect to the server and do the background task is the check below.
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if((conMgr.getActiveNetworkInfo() != null &&
conMgr.getActiveNetworkInfo().isAvailable() &&
conMgr.getActiveNetworkInfo().isConnected()) || WifiConnected() == true){
//do background processing
}
The WifiConnected() method looks like this below.
private boolean WifiConnected() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
SupplicantState supState;
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
supState = wifiInfo.getSupplicantState();
return (networkInfo != null && networkInfo.isConnected() && supState.toString().contentEquals("COMPLETED"));
}
So basically what I am checking before doing the background task is whether the device has active network connectivity and is connected or if the connection is wifi, if that connection is authentication complete so that data transfer is possible.
This doesn't seem to work and fails too making the service still force close.
What is the right way to do this check for network connectivity when wifi authentication is involved and then do the background processing?
Thanks.
A good example of this problem is when you are in any starbucks nationwide your android device will automatically connect to attwifi and the wifi status changes to connected because i check isConnected returns true but you will notice that the attwifi at starbucks will not let you transfer any data until you pseudo sign in by navigating to a browser page and accepting their terms of usage and agreement
Method conMgr.getActiveNetworkInfo() calls into ConnectivityService and the result of this call can be null. In the statement (conMgr.getActiveNetworkInfo() != null && conMgr.getActiveNetworkInfo().isAvailable() && conMgr.getActiveNetworkInfo().isConnected()) you call three times. I suspect there can be NPE here, as one of these calls can return null if network changes from 3g to WiFi at that time. What if you get NetworkInfo instance first, and them call isAvailable() and isConnected() on it (similar to how you did it in WifiConnected())?
You could move the connectivity check in your activity (or wherever else you have the context) and start the service from there.
Thus you won't have the force close constraint of the intentService and it should work fine.
Edit:
Ok got it! Here's what you can do to be sure that the user has access to Internet:
private boolean hasInternetAccess() {
boolean hasInternetAccess = false;
try {
//I set google but you can try anything "reliable"...
//isReachable(1) the timeout in seconds
hasInternetAccess = InetAddress.getByName("www.google.com").isReachable(1);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return hasInternetAccess;
}
So your check becomes:
If(WifiConnected() && hasInternetAccess()){
//Do background Work...
}
This is does some sort of ping to ensure the user has internet.
Don't forget that this method needs to be executed in a separate thread or it'll throw a NetworkOnMainthreadException. Here you're safe since you are in an IntentService that has its own thread. But I precise for the ones that might see this thread. By the way I suggest you to change the title of the this thread since the actual problem is not really related to the service but the access to internet.
Here's the reference: Test Internet Connection Android
I hope this helps.
or you can write a receiver for Connectivity change. It would be the best in your case.
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

check internet activity

I done an app that uses a webview to listen audio from internet. Now, I add a method (isOnline) to check if there's (or not) an internet activity. I've a doubt: I can use this method running always in OnCreate?
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
If you block the execution of the onCreate() aka the UI thread will be blocked and your app will throw ANR (Application Not Responding) exception.
However your method doesn't tell you that you are connected to the interned, it just tell you that your device isConnectedOrConnecting to nearest router. What is after that you don't know.
For check real internet connection you need to make a request to a server, such as www.google.com and if you get the answer then you have the connection live.
And another thing, you don't need to monitor your connection continuously. In the most simple manner you can do this in a background thread from time to time, but only if you cannot get events from your radio player.

Android: How can I determine if Application starts with no signal or no service?

I have a phone state listener. I listen for service state, call state, and signal strength changes. This is all well and good.
BUT...
If my application starts in a condition with no signal strength, there is no "change" and I am not notified. I cannot, therefore, determine if I HAVE NO SIGNAL.
Is there a way to actively request/determine weather or not I have a signal or network service (not internet) on STARTUP??
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null && connectivityManager.getActiveNetworkInfo() != null)
{
// Network is available
}
else
{
// No connection available.
}
update:
You also need the permission:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
update2:
Looks like there are issues with connectivityManager so it's not 100% reliable:
http://code.google.com/p/android/issues/detail?id=11588
http://code.google.com/p/android/issues/detail?id=11891
http://code.google.com/p/android/issues/detail?id=11866

Android Network Information: Displaying type, if connected, speed, signal, etc

I've been search and looking through forums and postings for tutorial(s) on, I think I am looking in the right direction. ConnectivyManager and TelephonyManager. I have tried looking at the Android Documents, yet as self explanatory as they are, I still get lost. Doing the self thought thing, I ry to find tutorials that break it down and show how to use and how things work.
What it is I'm wanting to do, is a full screen app that displays if your on 1x, 3g, 4g etc.. also the data transfer rate sending and receiving. (basically the same stuff in Setting>About Phone>Network) going to have it play a sound with each change in network type and change an image...
copying and pasting code from pages really don't help me learn what I'm doing, or to understand it. If anyone might know of any good tutorials or the direction i need to go in would be awesome, it would get me out of this rut I've been stuck in searching for for a few nights now lol
The ConnectivityManager and NetworkInfo classes are your friend here. Read over the available public methods to get an idea what's possible.
Here's a brief code sample that demonstrates how to determine if there is an active network connection:
/**
* Determine if the device has an active network connection.
* #return true if the network is connected, false if otherwise.
*/
private boolean isConnected() {
final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
if (cm != null) {
final NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) {
return activeNetwork.isConnected();
}
}
return false;
}

Categories

Resources