Saturday, February 11, 2017

Effective Way to Create and Save File In Android Application

Hello, in this blog post I am going to explain effective way of creating and saving file in android application. Also will explain what are the general mistakes developer make in creating and saving file and how to prevent it.

Why it is important to have strategy for File create and Save in Android?



Because android file system is very similar to disk based file system and when there is a problem in creating or saving file it throws IOException so your application may crash while it's running and it's not good for professional or business application. So you need a proper strategy to create and save file and you have to add all kind of checks and exception handling for this.


Common mistake by developers on Creating and Save file in Android


Any new developer who is working first time on the file make this mistake. They don't know how to create a file and they do not refer to android developer site and android SDK document. They just search on web and find answers on site like StackOverFlow and copy paste the code. But sometime what happens is the code which they have used was about saving file in SD card and it may be possible that some phones do not have SD card so when the application is running in these phones, it crashes.

Another mistake is, in the code they hard code the path of saving file. Each android version and phone has different way of handling SD card so if you hard code the path it may work in your phone but it does not work in other phone. So here you need some strategy for this and make sure that your code works in all scenarios.  Here are some common things you should consider while creating and saving file.


  1. Decide where you want to store file, in external storage or internal storage.
  2. If storing in internal storage make sure there is space available.
  3. If storing in external storage, first check if there is external storage is available and there is a space.
  4. Make sure you have permission to store files in external storage. 

If you have requirement that file created should only be accessed by your app, you should create it in internal storage in app directory or else you should create it in external storage. Here is the code I have used in one of my app to create file in external storage.

For this you should also have permission mentioned in your android manifest file.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;

private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.

File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
 Environment.DIRECTORY_PICTURES), "YOURAPP");

// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("YOURAPP", "failed to create directory");
return null;
}
}

// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".3gp");
} else {
return null;
}
return mediaFile;
}

As you see in above code, we are first checking if external storage is available or not. If it's not available, you just return null and if it's available, depending on file you want to create, create unique file name with current time stamp. Do not use hard coded file name like myVideo.3gp and it will always overwrite the previously created file.

Now we will use above function to check if we have file created or not in external storage and if not created we will create it in internal storage.

try{
File outputFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);

if(outputFile == null){
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
outputFile = new File(getFilesDir() + "/"  + File.separator +
"VID_"+ timeStamp + ".3gp");
}
} catch (IOException e) {
Log.d(TAG, "IOException creating file : " + e.getMessage());
}

As you see in above code we are calling this function to create file of type video and check if it returns null. If it returns null then we are creating file in internal storage. Following line creates file in internal directory.

outputFile = new File(getFilesDir() + "/"  + File.separator +
"VID_"+ timeStamp + ".3gp");

And we have enclosed code try catch block to catch any possible IOException. In case of exception, you should properly display a message to user.