The Android for .NET Developers Series
Part 1 Starting with this article, I'll discuss what you need to know to approach Android programming without any aid from your .NET expertise.
Part 2 In this article, we'll go through an Android application that accepts input from the user and handles user's clicking.
Part 3 In this article, you will learn how to build the user interface.
Part 4 In this article, I'll be delving deep into menus and dialog boxes in Android for .NET, and discuss a few very common (and frequently used) types of menus and dialogs.
Part 5 In this article, Dino Esposito focuses on the options that the Android SDK offers for local storage.
Part 6 In this article, Dino Esposito shows how to build settings dialog boxes using a built-in feature of Android for .NET.
Part 7 In this article, I'll dissect the code of a realistic application - a waterpolo score manager - to show how to save and resume the status of a game using both the internal storage and SD card.
Part 8 In this article, I'll focus on the execution of common tasks from within an Android application. I'll build the skeleton of an application that takes a photo and emails to the specified address. For both tasks I'll use native Android components.
Part 9 In this article, I'll discuss how to arrange an Android view where the dominant element is the list. I'll start with a plain list of strings and then improve up to populating a listview with downloaded content arranged using a custom layout.
Part 10 In this article, I'll discuss the features and capabilities required by an Android application to talk with Twitter. In particular, I'll focus on authentication and updates.
Introduction
Any serious mobile application will use the local storage to persist as much data as possible thus enabling offline working and occasionally
connected scenarios. The extent at which this is really possible varies with the goals of the application. Nearly any application, however, can
take some advantage of some working data saved locally. In general, an Android mobile device offers two options for storage - phone internal
storage and external SD cards. The internal phone storage is limited and not expandable; an SD card can be replaced as needed. This is the common
scenario you face with Android; in the iPhone space, for example, external cards are not supported. In Windows Phone 7, only a few devices allow
you to add an external card which can't be ported to other types of phone after use.
This distinction between internal and external
storage is important because in Android you need to use a slightly different API to read and write files in both locations. More, the internal
storage that is left to user applications is tiny space in the order of 100MB for most devices. (I have an HTC Desire, but I've heard similar
stories for devices of the same class.) In this article, I'll dissect the code of a realistic application - a waterpolo score manager - to show
how to save and resume the status of a game using both the internal storage and SD card.
Creating Files in the Internal Storage
Each Android application gains access to the internal storage through a bunch of functions exposed as part of the application context. The
storage is generally considered private of the application and will be removed when you uninstall the application or when you choose to clear the
data of the application through the interface of the phone's maintenance application. The Android API for preferences saves data to the internal
storage and this data is removed when you clean/uninstall the application.
The simplest way to create a file in the private area is shown
below:
The openFileOutput function is exposed out of the Context class. If you're calling this code from within an activity
object then you're OK as the Activity class inherits from Context. More likely, instead, you want to move this code to a distinct helper class. In
this case, the method that creates the file must receive a Context argument:
The code creates a new file with the specified name under a specific path. The usual path is:
As you can see, the files are grouped under an application specific folder - in this case, the folder com.expoware.waterpolo
as the application's namespace. In your code, however, you're not expected to know the details of the path. Calling the built-in
openFileOutput function does the trick for you.
In the example above, the content of the file is given by an array of bytes.
This may or may not be a format easy to work with. In the sample application that inspired this article I use a class to store the details of the
game and use Java serialization to persist an instance of the class. In this case, having a byte oriented programming interface is more than
acceptable. The same can be said if your application deals with audio or image files to be created from native streams.
Java (and Android
as well) supports writer and readers classes that you may know already very well from .NET. If you want to write (or read) bits and pieces of the
file content through primitive types you do as follows:
It should be noted that Java forces you to try/catch calls that explicitly declare exceptions. This is not the case in .NET, but may
be surprising at first. If you get a run time error that complains about not handling an exception, well, that's just the rule.
Creating Files on a Different Directory
The openFileOutput function is limited to the root directory of the space reserved to your application. What if you want to save
a file to a specific folder? In this case, you use an API that's similar to the one you need to use to write to the SD card. Here's the full
code.
The first thing to do is arranging the full path name you want to address. This is necessary as you want to take control over the
path. The function getFilesDir returns the root directory of the application's storage space: the /data/data/[app]/files
folder we met earlier transparently managed by the openFileOutput function. The File class wraps a file or a directory; the
following code creates a wrapper for the matches directory under the root:
You might want to ensure that the full directory path exists - that's the purpose of calling mkdirs. If something went wrong,
the can canWrite function on the File class returns false. If not, you can proceed with actual writing. You create a new File object
to represent the file you intend to create and just write it. You can use the FileWriter class as an alternate approach to streams. Like in .NET,
if your data doesn't come in the bytearray form there's no need to deal with cumbersome streams - a reader/writer API is easier and more
effective.
So in the end, the openFileOutput function is a shortcut that's easy to use, but a bit limited functionally
speaking. If that doesn't work your intended purposes, use FileWriter and use the File class to find the target location on the phone
storage.
Reading File Content
The API for reading some file content is specular. You can use readers or input streams, and you use the same API to locate source files.
Here's how to read a serialized class from a binary file.
Once you know the location of the file you want to read, you get its length and allocate a large enough array of bytes. Next, you
open the file (in the code snippet I'm using openFileInput) and fill the bytearray with content. Let's find out more object
serialization.
Serializing Objects
When you need to save a collection of data, the best option is stuffing data into a class and serialize the class using the ObjectOutputStream
class. For my convenience, I created an ObjectFormatter class with two façade methods - Serialize and Deserialize.
Here's the code.
As you can see, the Serialize method gets an object and returns an array of bytes; the Deserialize method does the
reverse. The return value of Deserialize must be cast to the correct type in order to be really usable.
Getting a List of Existing Files
My sample waterpolo application offers a Save Match menu item (see Figure 1) through which users save the current score to a file. At
some point, they might want to reload that content to resume the match after an interval or to share the score with friends once the game is
finished. (This is just what most parents love to do when their kids win the game.)
Figure 1: Saving a match

The idea is getting the list of files from storage, populate a pick list and let users choose the match they want to load to
perform further operations. Here's the only code you need to get the list of files in the internal storage:
The fileList function is defined on the activity and comes with a bunch of companion functions that also allow a
filtered search. Once you have the list of files creating a popup pick list is a child's game:
OK, I'll be honest. This is not exactly what I'd a child's game. It's rather ugly code; yet the code to write. The good news is that
you can reuse it over and over again without much extra thinking. In this regard, it is simple code.
The setItems method loads
the elements of the list and the event handler to invoke when one is clicked. Figure 2 shows the final results.
Figure 2: Picking a match from the list of saved matches

The Device SD Card
When the amount of data to save grows big, you might want to consider saving data to the SD card to preserve primary storage for applications.
On some devices, however, you're allowed to move applications to the SD at any time; and you just do so when you run short of space. Writing to
the SD card requires a special permission. You declare your intention about the SD card in the application's manifest file:
The key line is the <uses-permission> element: everything else is just the default content of any manifest file.
To create a file, you use an API nearly identical to the one discussed for custom folders:
The key difference is in the function you use to retrieve the root path of the SD. You use the following expression:
This returns a path similar to /mnt/sdcard. Starting from here you can create your custom folders and fill them up. None of
this content will be removed when you uninstall the application. Clearing your stuff is your responsibility.
Writing to the SD card is not
possible all the time. For example, when the device is connected to a PC the content of the SD card is hidden. For this reason, it is recommended
that you always call getExternalStorageState before you perform any operation on the external storage. The function will check
whether the media is available. Check http://goo.gl/lVuk for the details of the various states in
which the card can be.
Finally, how to work with the SD card within the emulator? It requires a few tricks. First off, you create an ISO
image simulating the card. The Android SDK provides an apt tool you command as below:
You can specify the size and the file name. The file can be moved around and can be viewed through Winzip or any other tool that
handles ISO files. If you use IntelliJ or Eclipse, you have a visual guide to mapping the fake SD card to the emulator. You must create the ISO
image yourself.
The Android for .NET Developers Series
Part 1 Starting with this article, I'll discuss what you need to know to approach Android programming without any aid from your .NET expertise.
Part 2 In this article, we'll go through an Android application that accepts input from the user and handles user's clicking.
Part 3 In this article, you will learn how to build the user interface.
Part 4 In this article, I'll be delving deep into menus and dialog boxes in Android for .NET, and discuss a few very common (and frequently used) types of menus and dialogs.
Part 5 In this article, Dino Esposito focuses on the options that the Android SDK offers for local storage.
Part 6 In this article, Dino Esposito shows how to build settings dialog boxes using a built-in feature of Android for .NET.
Part 7 In this article, I'll dissect the code of a realistic application - a waterpolo score manager - to show how to save and resume the status of a game using both the internal storage and SD card.
Part 8 In this article, I'll focus on the execution of common tasks from within an Android application. I'll build the skeleton of an application that takes a photo and emails to the specified address. For both tasks I'll use native Android components.
Part 9 In this article, I'll discuss how to arrange an Android view where the dominant element is the list. I'll start with a plain list of strings and then improve up to populating a listview with downloaded content arranged using a custom layout.
Part 10 In this article, I'll discuss the features and capabilities required by an Android application to talk with Twitter. In particular, I'll focus on authentication and updates.
About Dino Esposito
 |
Dino Esposito is one of the world's authorities on Web technology and software architecture. Dino published an array of books, most of which are considered state-of-the-art in their respective areas. His most recent books are “Microsoft ® .NET: Architecting Applications for the Enterprise” and “...
This author has published 53 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
Announcing Microsoft Ajax Library (Preview 6) and the Microsoft Ajax Minifier
read more
Hey, nice package!
read more
Extending SharePoint Site Provisioning using Site Definition ProvisionData
read more
FileSystemWatcher Events and incomplete file errors
read more
Team Foundation Server and the missing file sharing (Part 2)
read more
Adding Breadcrumb Navigation for SharePoint Application Pages
read more
Tool of the Day: WSPBuilder for SharePoint
read more
Retrieve File Contents using SQL Server 2005 SQL CLR
read more
Sharing Entity Framwork models between projects (or teams) when developing
read more
Where did my MSDN go?
read more
|
|
Please login to rate or to leave a comment.