Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Windows Phone 7, Android and iOS with Mono V: Content and Resource Files

Previous posts in this series:

- Mono I: Getting Started
- Mono II: Basic Navigation
- Mono III: Shared Libraries
- Mono IV: Webservices

Quite often you’ll want to include files within your application as resources or assets that can be loaded at runtime. For example images, fonts, strings or text files. In this post we’ll cover some of the ways that you can do this across the three platforms.

Windows Phone 7

There are two main ways to include files with your Windows Phone 7 application, as resources or as content. The primary difference is that files included as resources are compiled into the assembly, where as content files are packaged into the xap and deployed alongside your application on the device. Upshot is that resources load slightly quicker, because they’re already in memory, but that they can adversely affect the load time of your application. General rule of thumb on the .NET Compact Framework (which SL for WP7 sits over) is that the larger the assemblies, the longer it takes for the application to load.

Resource files

- Right-click on the wp7 application project (ie NicksNetTravels) in Solution Explorer. Select Add > Existing Item.

- Locate the file you want to add as a resource (in this case SimpleTextFile.txt located in the root folder of the application) and click Add

- Press F4 or open the Properties window and make sure the Build Action is set to Resource (some files default to Content, whilst others will default to Resource).

- In the MainPage.xaml.cs add the following code to read out the contents of the resource file:

using (var strm = App.GetResourceStream(
   new Uri("/NicksNetTravels;component/simpletextfile.txt",UriKind.RelativeOrAbsolute)).Stream)
using(var reader = new StreamReader(strm)) {
var txt = reader.ReadToEnd();
}
 

Note the format of the Uri: The first bit is the assembly name (ie NicksNetTravels) and then the second bit, after component,  is the path to the resource file (ie /simpletextfile.txt”). If you can’t work out the path to the resource I’d suggest using Reflector to open the application assembly and check to make sure your resource is there.

image

Open the .g.resources node and view the resources. Double-click to open them in notepad and view their contents.

image

Content files

- Right-click on the wp7 application project in Solution Explorer. Select Add > Existing item.

- Locate the file you want to add as content (in this case SecondTextFile.txt again located in the root folder of the application) and click Add

- This time make sure the Build Action is set to Content.

In a lot of cases you can reference content files directly by name (for example you can set the Source property of an Image control to “new Uri(“SecondTextFile.txt”, UriKind.Relative)” and it will be able to locate the file. However, if you want to read directly from the file you’ll need to reference the Microsoft.Xna.Framework assembly so that you can make use of the TitleContainer class.

- Right-Click on the WP7 application project, select Add Reference. Find and select Microsoft.Xna.Framework and click Add.

- In the MainPage.xaml.cs add the following code to read out the contents of the file:

using(var strm = TitleContainer.OpenStream("SecondTextFile.txt"))
using (var reader = new StreamReader(strm)) {
    var txt = reader.ReadToEnd();
}
 

You will probably need to add “using Microsoft.Xna.Framework;” to the top of this file too in order to get it to compile.

 

iOS

I’m sure there are probably other alternative ways to package files with your iOS application but this is the way that I’ve found/used so far (please add a comment if you know of another way):

- Right-click the iOS application project in the Solution window of MonoDevelop. Select Add > Add Files. Locate and select the file you want to include and click Open (SimpleTextFile.txt).

- Right-click the newly added file and make sure the Build Action is set to content.

Screen shot 2011-04-09 at 10.03.26 AM

- Now, in your code you can access this file as follows:

var name = Environment.CurrentDirectory + "/SimpleTextFile.txt";
using(var file = System.IO.File.Open(name,System.IO.FileMode.Open,System.IO.FileAccess.Read))
using(var reader = new System.IO.StreamReader(file)) {
    var txt = reader.ReadToEnd();
}

Note that we’re just opening a file using standard file IO commands. The file we added as content gets placed into the CurrentDirectory of the application.

 

Android

In your Android application there is quite a nice model for accessing resources. By default when you create a new project with MonoDroid you will see a Resources folder with a number of sub-folders. Each of these sub folders represents a different type of resource. For example the Drawable folder is used for images – when you access them you will use a Drawable object so that the image can be rendered to the screen. Similarly the Layout folder is used to store your Views for your application. One sub-folder that appears to be missing from the default project structure was the Raw folder. This is particularly useful as it is used for any files that you want to be able to access as a raw stream.

image

- If the Raw sub-folder does exist under the Resources node, right-click the Resources node and select Add > New Folder and call it Raw.

- Right-click the Raw sub-folder and select Add > Existing Item. Find and select the file you wish to add and click the Add button.

If you look at the Properties window for the newly added item you should see that the Build Action is set to AndroidResource. Build your solution – this is required to generate the designer wrapper for accessing the resource from code.

- Add the following code to your application to read the contents of this file

using (var strm= Resources.OpenRawResource(Resource.Raw.SimpleTextFile))
using (var reader = new StreamReader(strm)) {
    var content = reader.ReadToEnd();
}
 

Note that the reference to Resource.Raw.SimpleTextFile is checked at compile time to ensure the resource exists (rather than having to specify a string literal and hope you’ve got the name right).

And there you have it, content/resource file access across the three platforms.

Pingbacks and trackbacks (1)+

Comments are closed