Detect offline error in Retrofit 2

Displaying ‘no internet connection’ error is quite a common requirement. The sample below demonstrates how to make Retrofit 2 throw ‘no internet connection’ exception.

Essentially, you’ll create a class that implements Interceptor so that you can perform a network connectivity check before executing the request.

ConnectivityInterceptor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ConnectivityInterceptor implements Interceptor {
 
    private Context mContext;
 
    public ConnectivityInterceptor(Context context) {
        mContext = context;
    }
 
    @Override
    public Response intercept(Chain chain) throws IOException {
        if (!NetworkUtil.isOnline(mContext)) {
            throw new NoConnectivityException();
        }
 
        Request.Builder builder = chain.request().newBuilder();
        return chain.proceed(builder.build());
    }
 
}

If the app knows there is no connectivity, stop and throw exception there. We will need a reference to Context object in order to check connectivity.




NetworkUtil.java

1
2
3
4
5
public static boolean isOnline(Context context) {
		ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
		return (netInfo != null && netInfo.isConnected());
	}

NoConnectivityException.java

1
2
3
4
5
6
7
8
public class NoConnectivityException extends IOException {
 
    @Override
    public String getMessage() {
        return "No connectivity exception";
    }
 
}

Creating a custom Exception class allows us to catch it by Exception class type for error handling.

When instantiating a Retrofit service,

1
2
3
4
5
6
7
8
9
10
OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(new ConnectivityInterceptor(context))
        .build();
 
MyRetrofitService service = new Retrofit.Builder()
        .baseUrl("https://example.com)
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(MyRetrofitService.class);

In try-catch block for Retrofit web service failure,

1
2
3
if (exception instanceof NoConnectivityException) {
    // No internet connection
}

Include library based on product flavor

Ex) I want to use debugging tool libraries such as Stetho only in dev product flavor.

You can write a simple wrapper for each product flavor. This way, you can avoid including an unnecessary dependency to your Android apk.

build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
android {
    ...
    productFlavors {
        dev {
        }
        prod {
        }
    }
}
 
dependencies {
    ...
    devCompile 'com.facebook.stetho:stetho:1.4.1'
}

/app/src/dev/java/com/example/StethoWrapper.java:

1
2
3
4
5
6
7
public class StethoWrapper {
 
    public static void initializeWithDefaults(Application application) {
        Stetho.initializeWithDefaults(application);
    }
 
}

/app/src/prod/java/com/example/StethoWrapper.java:

1
2
3
4
5
6
7
public class StethoWrapper {
 
    public static void initializeWithDefaults(Application application) {
        // Not using Stetho for this product flavor
    }
 
}

/app/src/main/java/com/example/MyApplication.java

1
2
3
4
5
6
7
8
public class MyApplication extends Application {
 
    public void onCreate() {
        super.onCreate();
        StethoWrapper.initializeWithDefaults(this);
    }
 
}

Although debugging tools like LeakCanary provide a disabled version of library to be used for release apk, I prefer to use the approach above to completely exclude the dependency from my apk.

ViewPager with fixed background image

Problem

I want to have an image(such as a phone frame) fixed in its position while I swipe through contents in fragments on ViewPager. An example is “What’s New” or “Features” screen like gif animation below. Or maybe something fancier with your creativity.

viewpager_gif

Approach

It’s simpler than it looks. On top of a regular implementation of fragments ViewPager in an Activity,

  • Make your Fragment layout background transparent
  • Wrap ViewPager and ImageView in FrameLayout within your Activity layout so that you can center the image underneath ViewPager
Code Sample


[Continue reading…]

Implement your own keyboard for Android Wear app

Problem – Key Input in Android Wear

The question is, “how do you take key inputs on Android Wear app?”. I worked on a Wear app that needs to take number inputs. I needed a calculator-like number keyboard with keys for 0-9, -(negative sign), .(decimal), x(backspace), and C(clear).

If you encounter a similar need, this article might help you get an idea for your solution.

Approach – DialogFragment as Keyboard

We can make use of a DialogFragment to represent a keyboard.

keyboard_wear


[Continue reading…]

Spinner-like TextView: A Dialog Spinner that displays default “Select” text

Problem – Setting default text to a Spinner

Spinner out of the box does not allow you to set a value that displays by default and not appear in the list of options.

Approach – Custom view

We can imitate the behavior of Spinner with the following ideas:

  • Have a TextView that visually looks like a Spinner
  • Display a default text(e.g. “Select”) at first initialization.
  • When it is pressed, display a AlertDialog.
  • When an option is selected, update the text on the TextView.

default_text
dialog


[Continue reading…]

Pages:12>

Categories