Our team does alot of application demos, and a vast majority of them require an internet connection. My challenge is that most of my development droid phones only have wireless (e.g. 802.11g), and I need a graceful way to detect if an internet connection exists. Without some sort of connection-based error detection, my mapping app would simply have a few buttons and a grey screen with no clue as to what the problem might be. So, here’s one way to to alert your users that the network connection is down. This was built using Android 2.2 on Eclipse 3.5.
Step 1 – Create a new Class that takes advantages of the capabilities in the ConnectivityManager class. That way you can reuse this across multiple projects. Be sure to import the appropriate references, and change the package name to the correct path in your project:
package com.esri.arcgis.android.samples;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class CheckConnectivity{
ConnectivityManager connectivityManager;
NetworkInfo wifiInfo, mobileInfo;
/**
* Check for <code>TYPE_WIFI</code> and <code>TYPE_MOBILE</code> connection using <code>isConnected()</code>
* Checks for generic Exceptions and writes them to logcat as <code>CheckConnectivity Exception</code>.
* Make sure AndroidManifest.xml has appropriate permissions.
* @param con Application context
* @return Boolean
*/
public Boolean checkNow(Context con){
try{
connectivityManager = (ConnectivityManager) con.getSystemService(Context.CONNECTIVITY_SERVICE);
wifiInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
mobileInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(wifiInfo.isConnected() || mobileInfo.isConnected())
{
return true;
}
}
catch(Exception e){
System.out.println("CheckConnectivity Exception: " + e.getMessage());
}
return false;
}
}
Step 2 – Create an instance of that Class, and import the new Class you just created. Be sure to place your check for connectivity before any code that requires an internet connection. You can now use the Boolean result to decide what actions you want to take. I added the System.out.println to print the results into the logcat file. You can access logcat by installing Android Debug Bridge (ADB) and then typing “adb logcat” at a DOS command prompt. On a related note, you should also install Android Debug Tools (ADT) Eclipse Plug-in.
@SuppressWarnings("serial")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CheckConnectivity check = new CheckConnectivity();
Boolean conn = check.checkNow(this.getApplicationContext());
if(conn == true){
//run your normal code path here
}
else{
//Send a warning message to the user
connectivityMessage("Check Network Connection."); }
}
public void connectivityMessage(String msg){
Context context = getApplicationContext();
Toast toast = Toast.makeText(context, "", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.setText(msg);
toast.show();
}
Step 3 – I did initially run into a problem where the application threw a strange “Source not found” error on a system thread. It say strange because there was absolutely no useful information. I knew the application ran just fine without my ConnectionCheck Class, so I used the step-thru debugger to narrow things down to my checkNow() method. I placed that in a basic try/catch block and walla there was the error with the solution:
I/System.out( 269): CheckConnectivity: ConnectivityService: Neither user 10032 nor current process has
android.permission.ACCESS_NETWORK_STATE.
I/System.out( 269): CONNECTION CHECK: false
So, I went and added that permission line into the AndroidManifest.xml file and my app worked:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0" package="com.esri.arcgis.android.samples">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable ="true">
<activity android:name=".DrawGraphicElements"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
Here’s what the warning message will look like if you don’t have an internet connection: