Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Android Shared Preferences: Managing Files using Internal & External Storage

See in this article how to manage files using internal and external storage in Android with Shared Preferences

Mobile apps need to store and retrieve small amount of data in files. On the Android platform, these files can be saved either on the device’s internal memory or on an external storage media, such as a Secure Device (SD) card. By default, all files stored in the internal storage are private to the app whereas files stored in the external storage are accessible to all apps/users.

Using Internal Data Storage

Consider the scenario of a gaming app where the app needs to maintain the highest score. This means that the app has to store the data in the persistent storage and retrieve the same data when the user accesses the app again. In such a situation, the data to be stored is very small and can be stored in files instead of a database. To write and read data from files, Android provides access to the local file system through various classes provided by the java.io package. In other words, Android uses the same file construct found in a typical Java application. Files that are stored in the device’s memory are saved in the /data/data/<package name>/files folder and are grouped with other app resources, such as, images, music, and icons.

Storing Data in Files

On the Android platform, you can save files directly on the device’s internal storage. By default, files saved on the internal storage are private to an app and neither other apps nor the user can access them. When the user uninstalls the app, these files are automatically removed from the device’s internal storage. To create a file on the internal storage for writing data, you need to perform the following steps:

  1. Open or create the file by using the openFileOutput()method of the android.content.Context class.
  2. Write data to the file by using the write() method of the java.io.FileOutputStream class.
  3. Close the file by using the close()method of the java.io.FileOutputStream class.

In addition to storing data, files can be used to store your app settings such that when you restart your app, your previous settings are automatically restored. The following code snippet shows how to write data to a file in the internal memory:

String FILENAME = “Mydata.txt”; 
  String myData = “My name is Sam”;
   try { 
  // Open the file in private mode 
  FileOutputStream fos = openFileOutput (FILENAME, Context.MODE_PRIVATE); 
  // Write data to the file 
  fos.write(myData.getBytes()); 
  // close the stream 
  fos.close(); 
  }
   catch(Exception ex) { 
  Log.e("Exception", ex.toString()); 
  }

In the preceding code snippet, the openFileOutput() method opens or creates a file inside the current app package. This method takes two parameters, the first parameter, FILENAME, refers to the name of the file on the internal storage and the second parameter, Context.MODE_PRIVATE, refers to the mode in which the file needs to be opened. The fos.write()method writes the provided data onto the output stream object. The fos.close()method closes the stream.

Retrieving Data from Files

Files written to the internal memory can be accessed by apps having appropriate permissions. A file written to the / data/data/<package name>/files folder is accessible to the app having writable access to this folder. To open a file from the internal storage for reading data, you need to perform the following steps:

  1. Open the file by using the openFileInput()method of the android.content.Context class.
  2. Read data from the file by using the read()method of the java.io.FileInputStream class.
  3. Close the file by using the close()method of the java.io.FileInputStream class.

The following code snippet shows how to read data from a file and store the read data into a String variable myData:

String FILENAME = “MyData.txt” ;
  try{ 
  FileInputStream fis = openFileInput (FILENAME); 
  byte[] reader = new byte[fis.available ()]; 
  if (fis.read(reader)!=-1) 
  {     String myData = new String(reader);
   }
   fis.close(); 
  }
  catch(Exception ex)
   {
   Log.e(“Exception”, ex.toString()); 
  }

In the preceding code snippet, bytes are read from the MyData.txt file. The fis.available()method returns the number of bytes available in the file. The fis.read()method reads bytes from the stream and stores these in a byte array. The fis.close()method closes the stream.

Using External Data Storage

The Android platform also provides the user the choice to store large files, such as images and media files, on an external storage. Since the internal storage of a mobile device comes with limited capacity, it is advised to store all large and infrequently used files in the external storage. Suppose the user of a smartphone needs to download a heavy video from the Internet and before downloading the video, the user finds that the internal storage space of the device is low. In such a situation, the user can choose to store the video on the external storage, called an SD card. An SD card acts as an external storage for most of the Android mobile devices. The storage capacity of an SD card is much more than that of the internal storage and is also removable. Almost, all mobile devices provide support for expandable SD cards.

All files stored on the SD card are public and accessible to the user and all other apps. These files are visible through the Android system through the /mnt/sdcard folder. The following figure shows an sdcard folder available in the File Explorer tab of the DDMS perspective.

To check whether the external media is available or not, you need to use the getExternalStorageState() method. This method detects the state of the media, such as whether the media is mounted, missing, read-only, or in some different state. The following code snippet shows how to check the availability of the media:

boolean media_available = false; 
  boolean media_writeable = false;
  // Retrieve the state of the SD card.
  String State = Environment.getExternalStorageState();
  // Check if the SD card is mounted .
  if(Environment.MEDIA_MOUNTED.equals (State)) {
  // We can read and write data on the media.
   media_available = media_writeable = true;
   } 
  // Check if the SD card is mounted but in read-only mode .
  else if (Environment.MEDIA_MOUNTED_READ_ONLY.e quals(State)) 
  {
  // We can only read data from the media.
   media_available = true; media_writeable = false;
   }
   else 
  { 
  /* Something else is wrong. It may be one of the other states, you can neither read nor write on the media.*/ 
  media_available = media_writeable = false; 
  }

Reading/Writing Data to an External Storage

To read and write data to an SD card, you need to obtain the path of the external storage using the getExternalStorageDirectory()method of the Environment class. The process for reading and writing data after obtaining the path of external storage is same as reading and writing files from the internal storage.

Before your app reads or writes data to an external storage, you need to specify the required permission in the AndroidManifest.xml file. The following markup shows how to specify the permission for writing data to an external storage:

<uses-permission android:name=“android.permission.WRITE _EXTERNAL_STORAGE”>  </uses-permission>
   To write data to an external storage, in our case an SD card, you need to use the following code snippet: 
  String MYFILE = “MyData.txt”;
   String myData = “My name is Sam”;
   // Open the file. 
  FileOutputStream fos = new FileOutputStream (Environment.getExternalStorageDirecto ry()+ “//” + MYFILE);
   // Write data to the file .
  fos.write(myData.getBytes()); 
  fos.close(); 

To read data from an SD card, you need to use the following code snippet:

FileInputStream fis = new FileInputStream (Environment.getExternalStorageDirecto ry()+ “//” + MYFILE); 
  byte[] reader = new byte[fis.available ()];
   while(fis.read(reader)!=-1){} String mData = (new String(reader)); 
  Log.i(“Data”, mData); 
  fis.close();

In the preceding code snippet, the available()method of the FileInputStream class returns the number of bytes that can be read from this file input stream.

Using Shared Preferences

Android enables users to customize apps according to their needs. For example, a user can choose the background image for an app. This background remains unchanged while the app is running. However when the app is closed, the background changes back to the previous image. Shared preferences help you make persistent changes in apps. Preferences allow users to personalize and specify settings for apps, such as font size, colors, and background images.

The Android platform provides two types of preferences: activity-level preferences and app-level preferences. Activity-level preferences are associated with a specific activity and only one preference for an activity is allowed. App-level preferences are associated with an entire app. An app can have any number of app-level preferences. These preferences are visible in the app’s context and are stored using primitive data types in the form of key-value pairs. This data persists across user sessions even if the app is killed.

Creating Shared Preferences

Android provides the android.content.SharedPreferences interface, which provides a framework that allows you to save and retrieve persistent key-value pairs of built-in data types. The data types supported by the SharedPreferences interface are:

  • boolean
  • float
  • int
  • long
  • String

Shared preferences can be retrieved by using any of the following methods:

  • getSharedPreferences(): This method is used for app-level preferences. It is used if your app uses multiple preferences files identified by their name. This method takes two parameters, the first parameter refers to the file name and the second parameter refers to the operating mode. The operating mode, MODE_PRIVATE, MODE_WORLD_READABLE, or MODE_WORLD_WRITEABLE, specifies the access permission for the preferences. For example:
SharedPreferences pref = getSharedPreferences (PREF_FILENAME, MODE_WORLD_READABLE); 
  • getPreferences(): This method is used for activity-level preferences. It is used when only one preferences file is required for your activity. Because this would be the only preferences file for the activity, you do not supply a file name. If the specified shared preferences file exists, then it is opened; otherwise, it is created. For example:
SharedPreferences pref = getPreferences(MODE_PRIVATE); 

Shared preferences store the information in an XML file in the Android device’s data folder with the app’s package name as the sub-folder. For example, if the app with package name, com.storingdata.demo, uses shared preferences, the Android system creates a new XML file under the folder, /data/data/com.storingdata.demo/shared_prefs/, with the following content:

<?xml version=“1.0” encoding=“utf-8” standalone=“yes” ?> 
  <map> <string name="prefrence1">Hi</string> 
  <string name="prefrence2">Hello</ string> 
  </map>

To modify a shared preference, you need to use the SharedPreferences.Editor interface, as shown in the following figure.

Figure 1 : Using Shared Preferences

The following code snippet illustrates how to write data to shared preferences:

  public static final String MYPREFS = “mySharedPreferences”;
   // Method to save preferences.
   protected void savePref()
  {
   // Create or retrieve the shared preference object. 
  int mode = Activity.MODE_PRIVATE;
   SharedPreferences mySharedPreferences = getSharedPreferences(MYPREFS, mode);
   // Use an editor to modify the shared preferences. 
  SharedPreferences.Editor edit = mySharedPreferences.edit(); 
  // Store primitive types in the shared preferences object. 
  edit.putBoolean(“Flag”, true);
   edit.putFloat(“Float”, 3f);
   edit.putInt(“wholeNum”, 2);
   edit.putLong(“aNum”, 29);
   edit.putString(“Value”, “Hello”);
   // Commits the changes. 
  edit.commit(); 
  }

In the preceding code snippet, the SharedPreferences.Editor interface creates a new editor for the shared preferences. This editor allows modifications of the data available in the preferences and saves the modified data. To save the modified data in the SharedPreferences object, the commit()method is called.

Retrieving Shared Preferences

To retrieve the stored values using shared preferences, you need to use the methods provided by the SharedPreferences interface.

The following code snippet explains how to retrieve shared preferences:

// Create a method to retrieve preferences.
   protected void loadPref() 
  { 
  int mode = Activity.MODE_PRIVATE;
   SharedPreferences mySharedPreferences = getSharedPreferences(MYPREFS, mode);
   // To retrieve the saved values.
   boolean mFlag = mySharedPreferences.getBoolean(“Flag”, false);
   float mFloat = mySharedPreferences.getFloat(“Float”, 0f);
   int wholeNum = mySharedPreferences.getInt(“wholeNum”, 1);
   long mNum = mySharedPreferences.getLong(“aNum”, 0); 
  String mPreference; 
  mPreference = mySharedPreferences.getString (“Value”,“Hello”);
   }

Accessing Data from Remote Locations

These days, mobile devices have built-in capability to access the Internet. Through Internet connectivity, a mobile app offers mobile users a wide range of options, allowing them to access data stored on the Web.

Let us consider the scenario of a Currency Converter app that accepts data, such as amount, the base currency, and the target currency from the user. Because the global currency rates are updated frequently, these rates are not preferably stored in an app’s private database. Instead, you can develop your app such that it uses a predefined component available over the Web that services currency conversion requests from other app components. This Web component extracts current data from the Web and sends it to the app that requests the data.

In this case, the Currency Converter app would access the data stored on the Web. Therefore, it requires the appropriate permission to be specified in the AndroidManifest.xml file, as shown in the following code snippet:

<uses-permission android:name=“android.permission.INTER NET”> 
  </uses-permission> 

On the Android platform, you can access a resource available on the Internet by using the java.net.URL class. To read data from a resource specified by the URL class, you need to create a reference to the URLConnection class. The rest of the process of reading data from the object of the URLConnection class is the same for other input streams.

Let us consider the example of an xurrency.com Web component, which services requests for the current currency rates. The URL for this component is http://xurrency.com/api. The component requires three parameters that need to be appended to its URL: the base currency format, the target currency format, and the amount to be converted. The following code snippet illustrates how to access the currency rates from this Web component:

// Define a method for accessing the Web component. 
  public String server_data(String base, String target, String cur_value) { String value = null; 
  String myString = null; 
  try { 
  // Defines the URL for the component. 
  // These parameters vary depending upon the Web component/service being used. 
  URL myURL = new URL("http:// xurrency.com/api/"+base+"/"+target +"/"+cur_value); 
  // Open a connection to that URL for reading data. 
  URLConnection ucon = myURL.openConnection(); 
  // Defines input streams to read from the URLConnection. 
  InputStream is = ucon.getInputStream (); 
  BufferedInputStream bis = new BufferedInputStream(is); 
  ByteArrayBuffer baf = new ByteArrayBuffer(50); 
  int current = 0; 
  // Read bytes to the buffer until there is nothing more to read (-1). 
  while((current = bis.read()) != -1) 
  { 
  baf.append((byte)current); 
  } 
  // Convert the bytes read to a String.
   myString = new String(baf.toByteArray ());
  }
   catch (Exception e) 
  {
  // Display if an error occurs. 
  myString = e.getMessage(); Log.e("Error", myString);
  } 
  /* Check if the component returned a positive value, which is specified by "status = ok" */ 
  if(myString.contains("\"status\":\"ok \"")) 
  {
  // Extract the converted value from the returned string. 
  value=myString.substring (myString.indexOf("value\":")+7, myString.indexOf(",\"target")); 
  }
   else if(myString.contains("\"status\": \"fail\"")) 
  {
   value=“Error retrieving data from server” 
  } 
  /* Send the converted value to the main (calling) activity */ 
  return value; 
  } 

Let us take another example. Suppose you want to read a text file stored at a given URL and store its contents in a text file on the external storage of your device. The following code snippet illustrates how to access the text file from the given URL and store it in a text file on the external storage:

/* Create a URL object */ 
  URL url =new URL(“http:// www.somedomain.com/readme.txt”); 
  /* Open a URL connection */ 
  URLConnection conn; conn=url.openConnection(); 
  HttpURLConnection httpconn = (HttpURLConnection) conn; 
  /* Check whether the connection has been successfully established */ 
  int rescode=httpconn.getResponseCode (); 
  if(rescode==HttpURLConnection.HTTP_OK) 
  { 
  try 
  {
  /* Create an InputStream object to read from the URL */ 
  InputStream in = httpconn.getInputStream(); 
  /* Obtain the length of the file */ 
  int length = Integer.parseInt(httpconn.getHeaderField(“Content-Length”)); 
  /* Createa a byte array with size length */ 
  byte[] bs= new byte[length];
  /* Read the data */
  in.read(bs, 0, length);
  /* Store the data in a String variable */
   String str = new String(bs);
  /* Create a file external storage */ 
  File file= new File (Environment.getExternalStorageDirecto ry(), “//MyFile.txt”);
  file.createNewFile();
  /* Write the contents of the String variable to the file */ 
  FileWriter fos= new FileWriter (file); 
  BufferedWriter outf= new BufferedWriter(fos); 
  outf.write(str);
  outf.close();
  } 
  catch (Exception e) {
  Log.e(“ERROR”, e.toString());
  } 
  }

Conclusion

In addition to files, the Android platform provides a mechanism to store primitive data, such as string, boolean, and float in key-value pairs by using shared preferences. This data can be shared across app sessions and between activities of an app. The Android platform also allows you to access data stored in remote locations.



Certified Trainer for Windows 8 Mobile App Development, IBM CE Project Trainer With IBM DB2, RAD, RSA, Certified Trainer for ZEND (PHP), Certified PHP and MySql trainer, Certified trainer of Diploma in Oracle 10g (DBA) as per Orac...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login