Overview
As the world adapts to smartphones, no doubt, businesses will want to reach out and stay connected with both consumers and its employees, e.g., executives, sales, IT, engineering, etc… Since enterprise software is in wide-spread, operational use today, one strategy a company can do, is to mobile enable their existing enterprise system.
You might think that another option is to create a mobile compatible website. However, these sites usually provide less functionality than their fully-functioning website counterparts. And, more importantly, they will not take advantage of the plethor of features provided by mobile platforms.
Now you may think mobile enabling an existing enterprise system is hard, or that it won’t work for your company. I ask that you read this post, and then revisit mobile enabling your enterprise.
Four key components that smartphones inherently possess, are
- we take them anywhere,
- they are always powered on (as long as our battery is juiced!),
- they are computers possessing full processing power,
- they run on very capable, modern operating systems.
These components allow full applications to successfully run. And this includes enterprise applications and integrating with enterprise systems. And taking it one step more, this includes integrating with existing enterprise systems.
Let’s think for a moment what this means.
- A CRM can send an alert to a mobile device per a specified enterprise event? YES.
- An executive can monitor real-time sales in any district, any department, even any employee from anywhere, anytime? YES.
- A CRM action taken from a mobile device, can initiate an alert seen by other mobile devices and other platforms, e.g., web and non-web? YES.
- These cool mobile enabled features can be integrated into my existing enterprise system? YES, provided that your system is architecturally ready, or adapted to be architecturally ready (see my post on Supporting the Integration of Enterprise Systems with Popular Mobile Platforms with a Well-Defined Service-Oriented Architecture (SOA).
Alerts – Keeping the Mobile User Informed of Events
Emails and text messages keep us in touch with one another, inform us when a password is changed, and send us friendly reminders from time to time.
The Alert Notification feature inherent in our smartphones provide more flexibility with the following:
- We can identify the specific apps and events we want to be notified,
- We can specify how often we receive alerts, and
- We can control how we are notified, e.g., led blink, sound, and/or phone vibration.
There are some interesting things to keep in mind for the software designer/developer to ensure these alerts are helpful and friendly. Not useless and annoying.
For example, reviewing the alert notification features listed above, it is the responsibility of the app designers/developers to provide configurable preferences for the aforementioned. However, neglecting this will almost assure that users will uninstall the app, simply because they may be annoyed.
Now let’s delve into the main topic of this post. Designing a Mobile Alert System for an Existing Enterprise System.
Review of Android Services, AsyncTasks, Alarms, and Notifications
Our mobile alert system will simply poll a RESTful service residing on a server. Since polling is a periodic task, we will create an Android service to manage this task for us. I will briefly review Services, AsyncTasks, and Alarms, but follow the links if you need more information. Additionally, I created a post regarding Notifications, including an example, found here.
If you are interested in learning Android Application Fundamentals, or need a refresher, great information can be found here.
More coming soon!
Designing and Developing an Android Alert Service
We assume we have a RESTful service running on our server that returns a list of alerts for a specific client id. We will look at the actual service call later, but let’s first define an alert as having several basic attributes as follows:
- the alert type
- the alert message
- the from party who sent the alert
- the date/time the alert was created
- flag indicating if user has been notified of the alert
- flag indicating if user has read the alert
The following code represents the functional entity possessing the attributes listed above.
public class Alert {
public int Id;
public String Type;
public int TypeId;
public String From;
public int FromId;
public String Message;
public String CreatedDate;
public boolean Notified;
public boolean Read;
public Alert(JSONObject obj) throws JSONException {
deserializeFromObj(obj);
}
public Alert(String serializedObj) throws JSONException {
deserialize(serializedObj);
}
public void deserialize(String serializedObj) throws JSONException {
JSONObject obj = new JSONObject(serializedObj);
deserializeFromObj(obj);
}
public void deserializeFromObj(JSONObject obj) throws JSONException {
this.Id = obj.getInt("Id");
this.Type = obj.getString("Type");
this.TypeId = obj.getInt("TypeId");
this.From = obj.getString("From");
this.FromId = obj.getInt("FromId");
this.Message = obj.getString("Message");
this.CreatedDate = obj.getString("CreatedDate");
this.Notified = Boolean.parseBoolean(obj.getString("Notified"));
this.Read = Boolean.parseBoolean(obj.getString("Read"));
}
public String serialize() throws JSONException {
return serializeToObj().toString();
}
public JSONObject serializeToObj() throws JSONException {
JSONObject serializedObj = new JSONObject();
serializedObj.put("Id", this.Id);
serializedObj.put("Type", this.Type);
serializedObj.put("TypeId", this.TypeId);
serializedObj.put("From", this.From);
serializedObj.put("FromId", this.FromId);
serializedObj.put("Message", this.Message);
serializedObj.put("CreatedDate", this.CreatedDate);
serializedObj.put("Notified", this.Notified);
serializedObj.put("Read", this.Read);
return serializedObj;
}
public static ArrayList<Alert> deserializeArray(String serializedArray) throws JSONException {
JSONArray jsonObjs = new JSONArray(serializedArray);
ArrayList<Alert> alerts = new ArrayList<Alert>();
for (int i=0; i<jsonObjs.length(); i++) {
JSONObject alert = jsonObjs.getJSONObject(i);
alerts.add(new Alert(alert));
}
return alerts;
}
}
The following class is used to obtain a string, typically a serialized list of resources, from the specified url:
public class ResourceHelper {
// Request the resource located at url and return
// it as a String.
public String retrieveAsString(String url) {
try {
URL resource = new URL(url);
InputStream inpStream = resource.openStream();
// Convert InputStream to String by using BufferedReader.readLine().
// Iterate until the BufferedReader returns null.  Each line will be
// appended to a StringBuilder, and the result returned as a String.
BufferedReader reader = new BufferedReader(new InputStreamReader(inpStream), 8192);
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
And finally, here is our actual service call used to obtain a serialized list of alerts AND deserialize them into a list of Alert entities as we discussed earlier.
try {
String serializedAlerts = new ResourceHelper().retrieveAsString(OUR_SERVICE_URL);
ArrayList<Alert> alerts = Alert.deserializeArray(serializedAlerts);
}
catch (Exception e) {
e.printStackTrace();
}
Next, we will discuss the specifics required in notifying the user of these alerts.
More coming soon!
public class Employee {
public int Id;
public int DeptId;
public int SalaryGradeId;
public String FirstName;
public String LastName;
public String Email;
public String Phone;
public String Title;
public boolean TakesLongLunches;
public Employee(JSONObject obj) throws JSONException {
deserializeFromObj(obj);
}
public Employee(String serializedObj) throws JSONException {
deserialize(serializedObj);
}
public void deserialize(String serializedObj) throws JSONException {
JSONObject obj = new JSONObject(serializedObj);
deserializeFromObj(obj);
}
public void deserializeFromObj(JSONObject obj) throws JSONException {
this.Id = obj.getInt("Id");
this.DeptId = obj.getInt("DeptId");
this.SalaryGradeId = obj.getInt("SalaryGradeId");
this.FirstName = obj.getString("FirstName");
this.LastName = obj.getString("LastName");
this.Email = obj.getString("Email");
this.Phone = obj.getString("Phone");
this.Title = obj.getString("Title");
this.TakesLongLunches = Boolean.parseBoolean(obj.getString("TakesLongLunches"));
}
public String serialize() throws JSONException {
return serializeToObj().toString();
}
public JSONObject serializeToObj() throws JSONException {
JSONObject serializedObj = new JSONObject();
serializedObj.put("Id", this.Id);
serializedObj.put("DeptId", this.DeptId);
serializedObj.put("SalaryGradeId", this.SalaryGradeId);
serializedObj.put("FirstName", this.FirstName);
serializedObj.put("LastName", this.LastName);
serializedObj.put("Email", this.Email);
serializedObj.put("Phone", this.Phone);
serializedObj.put("Title", this.Title);
serializedObj.put("TakesLongLunches", this.TakesLongLunches);
return serializedObj;
}
public static ArrayList<Employee> deserializeArray(String serializedArray) throws JSONException {
JSONArray jsonObjs = new JSONArray(serializedArray);
ArrayList<Employee> employees = new ArrayList<Employee>();
for (int i=0; i<jsonObjs.length(); i++) {
JSONObject employee = jsonObjs.getJSONObject(i);
employees.add(new Employee(employee));
}
return employees;
}
}
