Android, Talking to the internet

Android talking to server

Getting your Android application to correctly communicate with a server can prove to be a difficult task. This task is then made more difficult by Android not allowing backways compatibility for networking on the main thread.

Setup

You will need to create, or have an existing, Android package ready to use. Once you’ve created a package the first thing to do is to create a functions file. This can be done by right clicking on your package, going to new on the context menu, then clicking Java. Name the file Functions and leave the kind set to class. Once this is done you can start to create the function and class for communicating with a server.


Create Android Class File

Add The Code

The Next bit we need to do is create the function and class. The following bit of code is the functions.

public static InternetObject DownloadFile(String url, List POSTData) {
String result = "";
String error = "";
int ResponseCode = 0;
try {
String userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0.1)";
DefaultHttpClient httpclient = new DefaultHttpClient ();
httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, userAgent);
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(POSTData));
HttpResponse response = httpclient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = r.readLine()) != null) {
result = result + line + "\n";
}
ResponseCode = response.getStatusLine().getStatusCode();
} catch (Exception e) {
error = e.getMessage();
}
InternetObject IO = new InternetObject();
IO.setContent(result.replace("\n", "").replace("\r", ""));
IO.setError(error);
IO.setResponseCode(ResponseCode);
return IO;
}

The next bit to add is the code for the internet object, this can be added at the end of the functions file. It will work the same if it is in another file but references to the object will need to be changed. The internet object is capable or returning 3 different variables. The first one is the content of the file you downloaded. This is used by calling InObj.getContent(). The second piece of data it can return is any error create at run time by Android. This allows you to debug your application with ease. This is used by calling InObj.getError(). The final piece of data that it will return is your webpage’s response code. This will tell you if you are looking at a missing page, or if a website has gone down if used correctly. This is used by calling InObj.getResponseCode().

public static class InternetObject {
String Content = "";
public void setContent(String str) {
Content = str;
}
public String getContent() {
return Content;
}
String Error = "";
public void setError(String str) {
Error = str;
}
public String getError() {
return Error;
}
int ResponseCode = 0;
public void setResponseCode(int i) {
ResponseCode = i;
}
public int getResponseCode() {
return ResponseCode;
}
}


The Last bit of code to add tell Android what packages need to be included when building and running the applicaiton. These need to be added directly inside of the class declairation.


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;


Depending on what version of Android you are building for depends on if you still have an error at this point. The DefaultHttpClient is no longer supported in new builds of Java. This means that we need to tell gradle to include legacy files. This can be done be adding the following to your build.gradle (Module: app) file, as a child property of ‘android’.


useLibrary 'org.apache.http.legacy'


Final build.gradle file should look similar to the following


apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "freespiritdevelopment.libraries"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
useLibrary 'org.apache.http.legacy'
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}


The final step is calling the code. This can be done from any file in you Android Application.


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
new DownloadExample().execute();
}
}).start();
}
private class DownloadExample extends AsyncTask {
@Override
protected Functions.InternetObject doInBackground(String... params) {
List POSTData = new ArrayList<>(2);
POSTData.add(new BasicNameValuePair("name", "value"));
return Functions.DownloadFile("url of api/file", POSTData);
}
@Override
protected void onPostExecute(Functions.InternetObject result) {
}