Home -> Teaching -> CSAS Android -> iBookmark

CSAS Android Workshop: Criminal Intent Project

This is a continuation of the CriminalIntent activity started as part of our Android workshop. Please check that page for a project description and to download the framework for this project.

Create new CriminalIntent project with a CrimeActivity (remove the menu inflator). That activity will host our fragment(s). The basic framework is as follows:

Next we add “date” and “solved” fields to Crime.java and update fragment_crime.xml to make room for these fields. NEW: We’ll use a theme divider. Also, create an alternate layout where date and the checkbox are in one line. NEW: We’ll use “layout_weight”.

To check your progress so far, download CriminalIntent1.0.zip and compare with your own version.

Next we want to see a list of crimes, each crime consisting of the title, the date, and a checkbox whether it is solved or not. We will not use the standard solution of creating a subclass of BaseAdapter as we have done for iBookmark, we will instead use a more sophisticated approach using a "singleton". Also, for the item view that will serve as template for the Crime items in our list, we will define that as XML and inflate it when necessary. We will also use a “centralized data stash” for our crimes so that anyone updating a crime will impact everyone else, and we will organize our classes somewhat differently than before. We will do the following:

Click here to download our progress so far...

Click here to download our progress so far...

Click here to check the "fragment swapping" app ...

Click here to check the "dual-pane" auto-adjusting app ... currently with a number of problems such as:

Click here for the working dual-pane app (not perfect yet, see HW below)

HW: The biggest problem of our current app is that I can edit crime details in landscape mode  but the list does not get updated accordingly. Actually, the list does get updated but not its view (you can see the list data is updated 'in secret' when you flip orientation - the list in portrait mode will reflect your changes). Your homework is to get the list to redraw itself whenever the crime details are edited. As a hint: you need info to flow from the 'detail' fragment to the 'list' fragment via the hosting activity. We already know how to do that, because our list fragment sent info to the detail fragment to update according to the selected item. We used an interface for that, so that's what you'll have to do to solve this problem as well.

We also need to add 'save and retrieve' features to our app, but that will be pretty straigh-forward. You could try this as homework but we will cover that on Monday anyway.

private static final String JSON_ID = "id";
private static final String JSON_TITLE = "title";
private static final String JSON_SOLVED = "solved";
private static final String JSON_DATE = "date";

...
public Crime(JSONObject json) throws JSONException { id = UUID.fromString( json.getString(JSON_ID)); title = json.getString(JSON_TITLE); solved = json.getBoolean(JSON_SOLVED); date = new Date(json.getLong(JSON_DATE)); }
...
public JSONObject toJSON() throws JSONException { JSONObject json = new JSONObject(); json.put(JSON_ID, id.toString()); json.put(JSON_TITLE, title); json.put(JSON_SOLVED, solved); json.put(JSON_DATE, date.getTime()); return json; }
private CrimeLab(Context context)
{
   super();
   this.context = context;
   this.serializer = new JSONSerializer(context, FILE);
   crimes = new ArrayList<Crime>(); 
   try 
   { 
      crimes = serializer.loadCrimes(); 
   } 
   catch (Exception e) 
   { 
      crimes = new ArrayList<Crime>(); 
      Log.e( TAG, "Error loading crimes: ", e); 
   }
}

...
public void save() { try { serializer.saveCrimes(crimes); Log.d(TAG, "File saved successfully"); } catch(Exception ex) { Log.e(TAG, "Error saving file", ex); } }

That should do the trick and finishes our current project. You could now add menus to delete and add crimes, much as we've done in our iBookmarks, which you could use as a model.  We could also add data fields to get a name from the address book or take a picture via implicit intents. We also looked into implicit intents, so this does not add anything new to our project (the image would be new, especially how to store it) so we'll consider this project done for now.