Reading bundled assets and resources

Almost all apps include some sort of content with the app package; it can be a database, image, or just plain text.

How to do it...

We can only get read-only access to bundled assets and resources but that is often all that is needed, as most app data comes from other sources such as the Internet or device sensors. We will create and add three basic types or resources by performing the following steps:

  1. Starting with assets, create a folder named Assets at the root of the project.
  2. Create a new file in the new Assets folder and save some text into that file, for example, a file named MyAsset.txt with the following contents:
    Hello Asset World!
  3. Now, mark the file as an asset by selecting the file. In the Properties pane, select AndroidAsset from the Build action dropdown.
  4. Next, for raw resources, create a folder named raw in the Resources folder.
  5. In the new raw folder, again create and save any text file, for example, a file named MyRaw.txt with the following contents:
    Hello Raw World!
  6. Similar to marking a file as an asset, we select AndroidResource from the Build action dropdown in the Properties pane.
  7. Finally, for special resources, ensure that there is a folder named values under the Resources folder.
  8. In the values folder, create a new XML file with the Android-style resources, for example, a file named MyResources.xml with the following content:
    <?xml version="1.0" encoding="UTF-8" ?>
    <resources>
      <string name="myString">Hello Resource World!</string>
    </resources>
  9. Again, we mark this file as AndroidResource in the Properties pane.

Once we have the resources created, we can now start writing code to access them:

  1. Starting with resources, we can access string resources using the Resources property:
    string stringValue = Resources.GetString(Resource.String.myString);
  2. Accessing raw files is a little more complicated as we use the Stream element:
    using (Stream raw = Resources.OpenRawResource(Resource.Raw.MyRaw))
    using (StreamReader reader = new StreamReader(raw)) {
      string rawValue = reader.ReadToEnd();
    }
  3. And the same with assets, we use a Stream instance:
    using (Stream asset = Resources.Assets.Open("MyAsset.txt"))
    using (StreamReader reader = new StreamReader(asset)) {
      string assetValue = reader.ReadToEnd();
    }

How it works...

There are three main types of app content: assets, raw resources, and special resources.

Special resources, or resources, are the most common and easiest to use. These resources can be accessed in layout files and in code. There are two main groups of special resources; there are Android-specific resources, such as animations, layouts, and menus, and there are value resources, such as strings, Booleans, and integers.

These value resources are accessed via various getter methods on the Resources property, and they return the value of the resource directly. They are stored in the values resource folder and are structured as basic XML elements with a name attribute.

Each resource folder can have a suffix that is used to determine the resource file that is to be loaded. There are many different suffixes that can be used, and a full list can be found on the Android developer website at http://developer.android.com/guide/topics/resources/providing-resources.html.

If there are two folders with the same name and different suffixes, such as values and values-land, Android will correctly select the appropriate file when the Resources property is used. This feature is especially useful for creating alternative resources, such as layouts, menus, and values based on the device characteristics, such as orientation and screen size, as well as device settings, such as language or culture.

Tip

Android resources can be used to provide alternative resources based on both device configurations and user configurations, and they do not require any special or additional logic in the code.

Another benefit of using resources is the fact that the compiler generates a type that contains all the various resources. For example, if we create a string resource with the name myString, the compiler will generate a field named myString in the String type nested inside the Resource type. This provides compile time checking and resource validation allowing us to write Resource.String.myString when accessing the string resource, instead of having to use string keys.

All resource types, from animations to values, have the benefit of allowing the Android runtime to select a variation of a resource, making resources very useful. The same is true for raw resources, which are just a type of resource. One main difference is that raw resources allow us to specify any resource type as a resource, such as the database files, binary data files, and ZIP files. Although these types aren't used by Android, we can use them in our code.

We access raw resource files through the OpenRawResource() method on the Resources property, passing in the ID of the raw resource. This method returns a stream with which we can work as we would work on any other stream.

Assets, on the other hand, are quite different. They are simply are files that bundled in the app package and stored in the Assets folder. Using assets allows us to dynamically load and list the files at runtime, but we have to do the work ourselves. Assets can also be organized into a folder hierarchy, which is not supported by resources.

Tip

Android assets can be used to hold any file type in a hierarchical structure and can be accessed dynamically.

Also, some features are only available to assets; these features include using a custom typeface or loading cascading style sheets. The reason for this is that assets actually have a URI for accessing any particular file: file:///android_asset/<some-file-name> (note the three slashes). We can load pages into the web browser component using this URI, and the browser can resolve the resource paths automatically.

Tip

The assets folder hierarchy can be multiple levels deep, something that cannot be done when using Android resources.

Accessing assets is done through the AssetManager instance, accessed either through the Assets property or the Resources.Assets property. We use the Open() method and pass in a path relative to the assets folder. Just as we did with raw resources, we obtain a stream that we use to read the contents of a particular asset.

See also

  • The Using files and the filesystem recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset