Skip to content

Instantly share code, notes, and snippets.

@ShreyashPromact
Last active December 16, 2016 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShreyashPromact/15a00e1f3872cc2eaaa50772d99772e4 to your computer and use it in GitHub Desktop.
Save ShreyashPromact/15a00e1f3872cc2eaaa50772d99772e4 to your computer and use it in GitHub Desktop.
Make your Android app to have Offline support with HttpURLConnection
Android - Make application offline
What is offline mode means?
Offline means to make application capable to load the data and resources from server even when internet connectivity is not available. The resources are like server responses, Image loading from the server, etc..
Why is it required?
If you are developing an android application which required an internet connection to load data from the server then this feature really going to help that developer to give support of access data even when the internet is not available. Now a days most of the client requesting about this feature. They want their customer to show data and information when Internet is not available. It might also possible that some of the area may not have proper internet connectivity. At that time, such feature help users to view information without internet.
Let's checkout, how that can be done
Here we are going to make the API call (Server request) in such a way that, it will load the data even when the internet is not available (Basically from catch response).
Here I am using HttpURLConnection to load the data from the server. I am using their properties to save the response in catch then I will going to utilize the same response when Internet is not available.
Check out below method to fetch data from the server using HttpURLConnection:
public static String getAllWall(String token) {
final String[] result = {""};
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(YOUR_URL_TO_FETCH_DATA);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.addRequestProperty("Content-Type","application/json");
urlConnection.addRequestProperty("Authorization", token);
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
int data = isw.read();
StringBuilder sb = new StringBuilder();
while (data != -1) {
char current = (char) data;
sb = sb.append(current);
data = isw.read();
System.out.print(current);
}
in.close();
isw.close();
result[0] = sb.toString();
} catch (Exception e) {
result[0] = e.getMessage();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return result[0];
}
Above example load the data from server when internet is available. Now, we need to store this data to catch of the response. So we can do it like this.
First we need to initiate catch directory in application folder. maximum catch directory size can be 10 MB. We can create the catch directory to hold the response. Just needed to call below code in application class. So it will run on start of the application and create the catch directory to hold response data.
protected void onCreate(Bundle savedInstanceState) {
...
try {
File httpCacheDir = new File(context.getCacheDir(), "http");
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
HttpResponseCache.install(httpCacheDir, httpCacheSize);
catch (IOException e) {
Log.i(TAG, "HTTP response cache installation failed:" + e);
}
}
protected void onStop() {
...
HttpResponseCache cache = HttpResponseCache.getInstalled();
if (cache != null) {
cache.flush();
}
}
}
Now, the application will reserved 10 mb size space in its application directory. Now we just need to update the API call method to enable it to catch the response. Before we add all details in API call, let's understand it one by one.
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
urlConnection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);
With above properties, you can define that, how long your response will be stored in to device.
urlConnection.setUseCaches(true);
With above property, we are informing the request to catched the response.
urlConnection.addRequestProperty("Cache-Control", "no-cache");
Above properties force request to fetch data from server only. It will not look for the response that are stored in catch memory.
urlConnection.addRequestProperty("Cache-Control", "only-if-cached");
Above properties force request to fetch data from the memory only if it is available.
Note: If the response for that particular request is not available in offline mode, then it will return FileNotFoundException with that requested url.
So, Now let's handled the situation in API request method. We need to handled the code as like, If there is active internet available then it will load data from server only. That fetched data should be stored in catch memory. But if internet is not available then it should be fetch from catched response it self.
Let's have a look at below code:
// Here isConnected is identify whether app is connected to internet or not.
// Use your code to check network connectivity
public static String getAllWall(String token, boolean isConnected) {
final String[] result = {""};
URL url;
HttpURLConnection urlConnection = null;
try {
int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
url = new URL(YOUR_URL_TO_FETCH_DATA);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setUseCaches(true);
urlConnection.addRequestProperty("Content-Type","application/json");
urlConnection.addRequestProperty("Authorization", token);
urlConnection.addRequestProperty("Cache-Control", "max-stale=" + maxStale);
urlConnection.addRequestProperty("Cache-Control", isConnected ? "no-cache" :
"only-if-cached");
InputStream in = urlConnection.getInputStream();
InputStreamReader isw = new InputStreamReader(in);
int data = isw.read();
StringBuilder sb = new StringBuilder();
while (data != -1) {
char current = (char) data;
sb = sb.append(current);
data = isw.read();
System.out.print(current);
}
in.close();
isw.close();
result[0] = sb.toString();
} catch (Exception e) {
result[0] = e.getMessage();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return result[0];
}
So, In above method we have add the required properties with the condition. I have added condition field (isConnected), which will tell me whether the Network connection is available or not. If available, it will load data from server but if not then it will return same response from memory (considering it is previously stored when internet is available).
See, its really very easy to make any app offline without much code to update. App will work smooth even without internet connectivity if its get catched before.
Thanks for review this post. Please comment and if you have any doubt regarding this implementation. Please like and also share this with your friends.
Thanks a lot! Enjoy Coding :)
Reference:
https://developer.android.com/reference/java/net/HttpURLConnection.html
https://developer.android.com/training/basics/network-ops/connecting.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment