In extending an application to multiple Activities, one realizes that the Android environment is like a mini-MOM (Message Oriented Middleware) setup. Activities can message and transport data (explicitly or implicitly) between each other by the use of Intent functions.
The simplest example of data passing is one where data is returned from a sub-activity to its caller. To return data from a sub-activity to it's caller, on finishing it can do something like:
Intent i = new Intent(this, Caller.class); // note the use of Caller.class
i.putExtra("returnKey","Sub-Activity Data"); // a named piece of data
setResult(RESULT_OK, i);
finish();
The caller then get's the data (in a loosely coupled way) with:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
Bundle extras = intent.getExtras();
System.out.println(extras != null ? extras.getString("returnKey"):"nothing returned");
}
What's interesting and unintuitive about this is the sub-activity's instantiation of a new Intent with the caller's class to set the data. Would have assumed instead that the caller's Intent object be somehow retrieved from it's sub-activity. Of course in other cases the messaging is between activities that do not have a calling rapport.
The official Intent examples are here.
Saturday, August 14, 2010
Thursday, July 22, 2010
Journal entries
Updated Android Keas app to handle journals (a.k.a. Observations of Daily Living, or "ODLs"), Meals, Exercise, Mood.
To do this added machinery to process 2D dataTable data from Keas API, and evolved ExpandableListView to show 2nd row for journal data, sorted chronologically starting with most recent entry.
The displayed columns and 'Name' column are specified in the loadData method, example:
loadAPIdata(username,password,"keas.apitest",
"odl_exercise.*","Exercise", true, "odl_exercise.name",
"odl_exercise.date,odl_exercise.intensityname,...");

Download signed apk here (try test user name:jim pw:jim)
Download Eclipse project here. Enjoy.
To do this added machinery to process 2D dataTable data from Keas API, and evolved ExpandableListView to show 2nd row for journal data, sorted chronologically starting with most recent entry.
The displayed columns and 'Name' column are specified in the loadData method, example:
loadAPIdata(username,password,"keas.apitest",
"odl_exercise.*","Exercise", true, "odl_exercise.name",
"odl_exercise.date,odl_exercise.intensityname,...");
Download signed apk here (try test user name:jim pw:jim)
Download Eclipse project here. Enjoy.
Friday, July 9, 2010
Porting Android code to Google App Engine /J
One of the advantages of working in Java on Android is much of the back-end code can be transported to Google App Engine/Java (GAE/J) without much effort. This is quite nice as one can rev/iterate/test backend code quickly on GAE/J and then move it to Android once solid. It's also nice as one can remain in the same frame of mind while coding front and backend.
In the case of Keas API code for Android, the backend is comprised mostly for API calls and XML processing. Most of the code remains consistent between Android and GAE/J, with some subtle differences in 'framing' and underlying class assumptions.
You can see the Keas API application on GAE/J here: http://keasapi.appspot.com
The Elipse project files can be found here.


Here is one example, establishing an http connection, note the differences in http class interfaces and the details of setting header data.
Http connection from within Android:
public void getData(String username, String password, String partnerId,
String namespace) {
try {
HttpGet get = new HttpGet("https://preview.keas.com/rest/api/getdata?query="+namespace);
get.setHeader(new BasicHeader("username", username));
get.setHeader(new BasicHeader("password", password));
get.setHeader(new BasicHeader("partnerId", partnerId));
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 1024);
XmlPullParserFactory xppFact = XmlPullParserFactory.newInstance();
xppFact.setNamespaceAware(true);
XmlPullParser xpp = xppFact.newPullParser();
...
Http connection from GAE/J servlet:
private void getData(HttpServletResponse resp, String uid, String pw, String query) {
try {
URL url = new URL("https://preview.keas.com/rest/api/getdata?query="+query);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("username", uid);
connection.setRequestProperty("password", pw);
connection.setRequestProperty("partnerId", "keas.apitest");
connection.connect();
Object content=connection.getContent();
if (content instanceof InputStream || content instanceof Reader) {
XmlPullParserFactory xppFact = XmlPullParserFactory.newInstance();
xppFact.setNamespaceAware(true);
XmlPullParser xpp = xppFact.newPullParser();
...
In the case of Keas API code for Android, the backend is comprised mostly for API calls and XML processing. Most of the code remains consistent between Android and GAE/J, with some subtle differences in 'framing' and underlying class assumptions.
You can see the Keas API application on GAE/J here: http://keasapi.appspot.com
The Elipse project files can be found here.
Here is one example, establishing an http connection, note the differences in http class interfaces and the details of setting header data.
Http connection from within Android:
public void getData(String username, String password, String partnerId,
String namespace) {
try {
HttpGet get = new HttpGet("https://preview.keas.com/rest/api/getdata?query="+namespace);
get.setHeader(new BasicHeader("username", username));
get.setHeader(new BasicHeader("password", password));
get.setHeader(new BasicHeader("partnerId", partnerId));
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 1024);
XmlPullParserFactory xppFact = XmlPullParserFactory.newInstance();
xppFact.setNamespaceAware(true);
XmlPullParser xpp = xppFact.newPullParser();
...
Http connection from GAE/J servlet:
private void getData(HttpServletResponse resp, String uid, String pw, String query) {
try {
URL url = new URL("https://preview.keas.com/rest/api/getdata?query="+query);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("username", uid);
connection.setRequestProperty("password", pw);
connection.setRequestProperty("partnerId", "keas.apitest");
connection.connect();
Object content=connection.getContent();
if (content instanceof InputStream || content instanceof Reader) {
XmlPullParserFactory xppFact = XmlPullParserFactory.newInstance();
xppFact.setNamespaceAware(true);
XmlPullParser xpp = xppFact.newPullParser();
...
Monday, June 21, 2010
Keas Droid v0.9
v0.9 KeasDroid project, an Android app using the Keas API to show Health Profile data and color indicators.
Features:




Download signed apk here (try test user name:jim pw:jim)
Download Eclipse project here. Enjoy.
Features:
- Username/password stores as Android preferences
- Color coded indicators for Health profile attributes
- Progress bar during data load
- Direct to Keas API, on-board XML parsing, no additional middleware
Download signed apk here (try test user name:jim pw:jim)
Download Eclipse project here. Enjoy.
Saturday, June 19, 2010
Toast
Toast is quite a useful and compact widget class to provide a temporal notification for the user.
Toast.makeText(KeasDroid.this,
"Here you can maintain your user credentials.", Toast.LENGTH_LONG).show();

This is the equivalent of a modal dialog box, a timer and a dismiss of the dialog. There doesn't appear to be a reasonable way of prolonging the length of display beyond a few secs.
To notify on the status bar requires more work, here's a simple example:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager)
getSystemService(ns);
int icon = R.drawable.icon;
CharSequence tickerText = "Click Menu to set username";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "Keas notification";
CharSequence contentText = "Please click Menu to set username";
Intent notificationIntent = new Intent(this, KeasDroid.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
final int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);
Toast.makeText(KeasDroid.this,
"Here you can maintain your user credentials.", Toast.LENGTH_LONG).show();
This is the equivalent of a modal dialog box, a timer and a dismiss of the dialog. There doesn't appear to be a reasonable way of prolonging the length of display beyond a few secs.
To notify on the status bar requires more work, here's a simple example:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager)
getSystemService(ns);
int icon = R.drawable.icon;
CharSequence tickerText = "Click Menu to set username";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Context context = getApplicationContext();
CharSequence contentTitle = "Keas notification";
CharSequence contentText = "Please click Menu to set username";
Intent notificationIntent = new Intent(this, KeasDroid.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
final int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);
Wednesday, June 16, 2010
ExpandableListView with dynamic images
ExpandableListViews are great, but less great without images within them, particularly dynamic images (set at the time of creation for the list). The examples (here's one that was a reasonable starting point) and snippets on the Web left a lot to be desired, but what I was aiming for was this:

Note the color 'indicator' (in this case) changes based on variables for the child row. Very useful. This is a key feature of a health attribute (eg. weight) and a color indicator (eg. red for overweight).
To accomplish such a thing one needs to do a number of things in concert within the project, the instantiation of the ExpandableListView and the project's resources, hence the difficulties of trying to grok this solely from one code snippet or another. As an added bonus my example includes a ClickListener to detect clicks within the list.
The sample Eclipse project can be downloaded here. Enjoy.
Note the color 'indicator' (in this case) changes based on variables for the child row. Very useful. This is a key feature of a health attribute (eg. weight) and a color indicator (eg. red for overweight).
To accomplish such a thing one needs to do a number of things in concert within the project, the instantiation of the ExpandableListView and the project's resources, hence the difficulties of trying to grok this solely from one code snippet or another. As an added bonus my example includes a ClickListener to detect clicks within the list.
The sample Eclipse project can be downloaded here. Enjoy.
Thursday, June 10, 2010
Rendering an ExpandableListActivity
Most Android code snippets are about one Activity class or other derivative, like ExpandableListActivity. But what if you have multiple classes that you want to render in some orchestrated fashion?
If you have an ExpandableListActivity called healthProfile, and you need to render it from a main class called KeasDroid, this will get it done:
Intent myIntent = new Intent(KeasDroid.this, healthProfile.class); KeasDroid.this.startActivity(myIntent);
But remember you have to add the activity in the manifest file, as shown below:
If you have an ExpandableListActivity called healthProfile, and you need to render it from a main class called KeasDroid, this will get it done:
Intent myIntent = new Intent(KeasDroid.this, healthProfile.class); KeasDroid.this.startActivity(myIntent);
But remember you have to add the activity in the manifest file, as shown below:
Subscribe to:
Posts (Atom)