Rob Heittman — June 25, 2013
I'm beginning a series of posts on how to integrate Appygram into different kinds of apps. Of course, I want to begin at the end, and geek out on the newest, most powerful beta features, like traces and store review tracking, making all my examples in high level languages like Ruby and Javascript.
But, I've been told, it's probably a bad idea to build the top floor of a house first.
So let's start with the native Java-based toolchain on Android, and the most basic thing that Appygram can do: collect and route a feedback message from a user.
Appygram doesn't impose any user interface; that's up to you. You can present any kind of form you like for the user, then submit it using either JSON or regular HTML form submissions.
On the Five Guys native Android app, the UI looks like this:
This app is actually using a lot of advanced Appygram features, and we'll drill into those eventually, but for now, let's focus on the basics of taking those simple fields from the UI and pushing them through to Appygram.
I've posted a complete working example on GitHub that does just that. It's an Android app that consists of nothing but a feedback form; supply your API key and you've got a working mobile Appygram client. (UPDATE: if you want the version specific to this Part 1 article, check out the 101_part_1 branch … otherwise follow along with this blog series using master)
The UI is defined in the usual Android way, via an XML declarative layout, bound to events in the code. Fields look like this.
<EditText
android:id="@+id/editName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name"
android:inputType="textPersonName" >
<requestFocus />
</EditText>
The button to send the appygram looks like this, and its onClick method binds it to a method in the sole Activity of the sample app:
<Button
android:id="@+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Send Appygram"
android:onClick="send" />
I'm sure if you develop for Android, this UI stuff is all old hat to you. The interesting part, where the rubber meets the road, is where the app actually sends something to Appygram. In the Five Guys app, that looks like a lot like this:
URL url = new URL("https://arecibo.appygram.com/appygrams");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
String input = params.toString();
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
The app uses JSON and the GSON library, which is what's going on in that "params.toString()" operation above. "params" is a GSON JsonObject. Whether you use GSON or Jackson or some other library, I definitely recommend that you try to work with JSON if you can -- it will simplify your life when working with other Appygram features, and it's a good tool to have at your disposal for all JSON-based web services.
We'll go back to using JSON/GSON later in this series. For now, let's do away with all dependencies and just submit this using the built-in URL encoding capabilities of Java, like this:
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
String input =
"api_key=" + URLEncoder.encode (api_key) +
"message=" + URLEncoder.encode (message);
Appygram only requires that you submit your API key, but our sample app will at least send a name, email address and message, just to be realistic.
In Android, you need to do your network operations off of the main UI thread. Extending AsyncTask is the recommended way to do this, and in the example app, I've provided a simple AsyncTask subclass that you can modify for your purposes.
private class SendAppygramTask extends AsyncTask<URL, Integer, Long> {
private Map<String,String> params;
private String join(List<String> aArr, String sSep) {
StringBuilder sbStr = new StringBuilder();
for (int i = 0, il = aArr.size(); i < il; i++) {
if (i > 0)
sbStr.append(sSep);
sbStr.append(aArr.get(i));
}
return sbStr.toString();
}
protected SendAppygramTask(Map<String,String> params){
super();
this.params = params;
params.put("api_key", APPYGRAM_API_KEY);
}
protected Long doInBackground(URL... urls) {
Long result = 0L;
try{
URL url = new URL("https://arecibo.appygram.com/appygrams");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
List<String> httpParams = new ArrayList<String>();
for(Map.Entry<String,String> p : params.entrySet()){
try {
httpParams.add(p.getKey() + "=" + URLEncoder.encode(p.getValue(),"UTF-8"));
} catch (UnsupportedEncodingException impossible) {
throw new Error(impossible); // UTF-8 should be present
}
}
String input = join(httpParams,"&");
Log.i("Appygram Example","Sending: "+input);
OutputStream os = conn.getOutputStream();
os.write(input.getBytes());
os.flush();
os.close();
result = (long) conn.getResponseCode();
Log.i("Appygram Example","Appygram sent with result "+result);
} catch (IOException x) {
Log.e("Appygram Example","Error sending appygram", x);
}
return result;
}
protected void onPostExecute(Long result) {
// TODO: show that something happened
}
}
To use this inner class in your Activity, just pass it a Mapexecute()
method.
Map<String, String> params = new HashMap<String, String>();
params.put("name", getUIString(R.id.editName));
params.put("email", getUIString(R.id.editEmail));
params.put("message", getUIString(R.id.editMessage));
// Send them to Appygram
new SendAppygramTask(params).execute();
A more complete implementation would do things like implement onPostExecute to do something useful on the UI thread (e.g. confirm receipt of the message or dismiss the form), handle errors more usefully than just logging them, and potentially retry if it is important the message goes through in the background. We'll go down that path as this series continues.
In the next installment, we'll reintroduce a JSON library and see how to interrogate topic lists and pass contextual information from the app to Appygram -- and how to use that information in Appygram to filter and route messages.
Related tag(s): How to Mobile Apps
Appygram is a web and mobile application communication service.
Plans start at FREE! Sign Up Now!