Friday, November 29, 2013

How to Get the Audio File of the Audio Recorder Intent in Android

When you need to record audio on your android application, you have two options: 1.) To implement your own audio recorder and 2.) To use the default default audio recorder of the android device. For some cases, it is more convenient to use the second option because we would no longer need to do additional coding just to accomplish our goal. So to start the audio recorder, we use an intent:
1:          Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);  
2:          startActivityForResult(intent, RECORD_SOUND);  
Please note that the RECORD_SOUND variable is just any integer that serves as the request code for our Audio Record activity so we would know if the result we receive is from that activity.  We use it on this section of our MainActivity's code:
1:       protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
2:            switch(requestCode) {  
3:                 case RECORD_SOUND:  
4:                      /*  
5:                       * get the recorded file's path if resultCode is ok  
6:                       */  
7:                      break;  
8:                 default:  
9:                      super.onActivityResult(requestCode, resultCode, data);  
10:                      break;  
11:            }  
12:       }  

To get the path of the recorded audio most guides use this code:
1:  data.getData().getPath()  
However, when I tried using the value of the path returned by that method, I noticed that the file cannot be accessed. After a bit of digging around, I saw this method to get the actual path:
1:       private String getAudioFileRealPath(Intent data) {  
2:            String realPath = "";  
3:            String[] filePathColumn = { MediaStore.Images.Media.DATA };  
4:            Cursor cursor = getContentResolver().query(data.getData(), filePathColumn, null, null, null);   
5:            if(cursor.moveToFirst()){  
6:              int columnIndex = cursor.getColumnIndex(filePathColumn[0]);  
7:              realPath = cursor.getString(columnIndex);  
8:            }  
9:            cursor.close();  
10:            return realPath;  
11:       }  
Here is a comparison of the paths obtained:

The full source code for this tutorial can be found here

Thursday, November 28, 2013

Caching Remote Images in Titanium Mobile

Previously, I demonstrated how to use Universal Image Loader for caching remote images on an android application. For Titanium Mobile Applications, I will show a method to achieve the same effect. Please note however that you may need to modify the code to handle the cleanup of any unused downloaded files.

Here is the code for the caching method:
1:  function cacheImageAndLoad(url, imageView){  
2:       var fileName = url.substring(url.lastIndexOf('/') + 1);  
3:       var fileCopy = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, fileName);  
4:       if (!fileCopy.exists()) {  
5:            var xhr = Ti.Network.createHTTPClient({  
6:                 onload : function(e) {  
7:                      fileCopy.write(xhr.responseData);  
8:                      imageView.image = fileCopy.nativePath;  
9:                 },  
10:                 onerror : function(e) {  
11:                      /*  
12:                       * show default image  
13:                       */  
14:                 },  
15:                 timeout : 20000  
16:            });  
17:            xhr.open('GET', url);  
18:            xhr.send();  
19:       }  
20:       else {  
21:            imageView.image = fileCopy.nativePath;  
22:       }  
23:  }  

Check the demo application code here

Tuesday, November 26, 2013

Access Cache file on Universal Image Loader

Sometimes, when using the Universal Image Loader library, there comes a time where the loader takes a while to verify whether the remote image has been already loaded in your cache. To load the cache file directly, you can use the following method to check whether a local copy of the remote file has already been made:

 File file = imageLoader.getDiscCache().get(url);  
 if (!file.exists()) {  
      DisplayImageOptions options = new DisplayImageOptions.Builder()  
      .cacheOnDisc()  
      .build();  
      imageLoader.displayImage(url, imageView, options);  
 }  
 else {  
      imageView.setImageURI(Uri.parse(file.getAbsolutePath()));  
 }  


Universal Image Loader Tutorial

When using images for an android application. You often encounter a situation where you need to display an image located in a remote server. Since displaying images directly on the views would have considerable impact on the application, we need to cache them first before displaying them. To assist me in this scenarios, I use the Universal Image Loader.

To start using this library, you need to include the universal-image-loader-x.y.z.jar file into your project.

Set the permissions on the application manifest:

1:    <uses-permission android:name="android.permission.INTERNET" />  
2:    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  

Create a subclass of the Application class where you will initialize the image loader configuration:
1:  public class UILDemoApplication extends Application {  
2:       @Override  
3:       public void onCreate() {  
4:            super.onCreate();  
5:            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())  
6:            .threadPriority(Thread.NORM_PRIORITY - 2)  
7:            .denyCacheImageMultipleSizesInMemory()  
8:            .discCacheFileNameGenerator(new Md5FileNameGenerator())  
9:            .tasksProcessingOrder(QueueProcessingType.LIFO)  
10:            .enableLogging()   
11:            .build();  
12:            ImageLoader.getInstance().init(config);  
13:       }  
14:  }  

Update your application manifest to set the name of the Application tag into UILDemoApplication the class name:
1:  <application  
2:      android:name=".UILDemoApplication"  
3:      android:allowBackup="true"  
4:      android:icon="@drawable/ic_launcher"  
5:      android:label="@string/app_name"  
6:      android:theme="@style/AppTheme" >  

To use the image loader, first get an instance to the image loader class. In my sample application, it is located on the ImageListAdapter that I created:
1:       private Context context;  
2:       private ImageLoader imageLoader;  
3:       public ImageListAdapter(Context context) {  
4:            this.context = context;  
5:            imageLoader = ImageLoader.getInstance();  
6:       }  

For loading images on your image view, you can use check on the sample code below
1:            DisplayImageOptions options = new DisplayImageOptions.Builder()  
2:            .cacheOnDisc()  
3:            .build();  
4:            imageLoader.displayImage(urls[position], vh.imageView, options);  

As you can see from the code above, I specified some options for displaying the image. I enabled caching the image on the disc so that we won't need to download the image everytime we need to display it. It is also possible to display the image without any options by just calling:
1:  imageLoader.displayImage(urls[position], vh.imageView);  

The full source code for this tutorial can be found here.

RoboSpice Spring

Robospice Spring Android module is a library that you can use when you need to handle restful network communication on your application. Recently, it has been highly advised to use a dependency manager to add this library to your projects. Since the official documentations already contain plenty of guides for that, I will just skip that part. For this tutorial, just make sure that you have the needed jar files. Here are the list of jars:

robospice-cache-x.y.z.jar
robospice-x.y.z.jar
commons-io-x.y.z.jar
commons-lang3-x.y.z.jar
spring-android-core-x.y.z.jar
spring-android-rest-template-x.y.z.jar
robospice-spring-android-x.y.z.jar

These optional libraries are also useful:

jackson-core-asl-x.y.z.jar
jackson-mapper-asl-x.y.z.jar 
jackson-databind-x.y.z.jar
gson-x.y.z.jar
simple-xml-x.y.z.jar

Update the application manifest by adding these permissions:
1:    <uses-permission android:name="android.permission.INTERNET"/>  
2:    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  
3:    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>  

Also add the JacksonSpringAndroidSpiceService within the application section of the manifest:
1:  <service android:name="com.octo.android.robospice.JacksonSpringAndroidSpiceService" android:exported="false" />  

For the WebService, we will use the OpenWeatherMap forecast api samples. To handle the api response data, we need to prepare the necessary classes but first we need to take a look at the json object from the server.


As you can see, each list item consists of several fields. Some fields consist of strings while others are composed of json objects or json array. For the json objects like the temp property, we prepare an object to handle its data:
1:  @JsonIgnoreProperties(ignoreUnknown = true)  
2:  public class Temp {  
3:       private String day;  
4:       private String min;  
5:       private String max;  
6:       private String night;  
7:       private String eve;  
8:       private String morn;  
9:       public String getDay() {  
10:            return day;  
11:       }  
12:       public void setDay(String day) {  
13:            this.day = day;  
14:       }  
15:       public String getMin() {  
16:            return min;  
17:       }  
18:       public void setMin(String min) {  
19:            this.min = min;  
20:       }  
21:       public String getMax() {  
22:            return max;  
23:       }  
24:       public void setMax(String max) {  
25:            this.max = max;  
26:       }  
27:       public String getNight() {  
28:            return night;  
29:       }  
30:       public void setNight(String night) {  
31:            this.night = night;  
32:       }  
33:       public String getEve() {  
34:            return eve;  
35:       }  
36:       public void setEve(String eve) {  
37:            this.eve = eve;  
38:       }  
39:       public String getMorn() {  
40:            return morn;  
41:       }  
42:       public void setMorn(String morn) {  
43:            this.morn = morn;  
44:       }  
45:  }  

For an array type (just like the weather list) we do declare it like this:
1:       private List<Weather> weather;  

For our request to the webservice, we prepare the following request object:
1:  public class ForecastListRequest extends SpringAndroidSpiceRequest<ForecastList> {  
2:       public ForecastListRequest() {  
3:            super(ForecastList.class);  
4:       }  
5:       @Override  
6:       public ForecastList loadDataFromNetwork() throws Exception {  
7:            Uri.Builder builder = Uri.parse("http://api.openweathermap.org/data/2.5/forecast/daily?lat=35&lon=139&cnt=7&mode=json").buildUpon();  
8:            return getRestTemplate().getForObject(builder.build().toString(), ForecastList.class);  
9:       }  
10:  }  

After preparing the objects, we need to instantiate our spiceManager in our activity to be able to use it:

1:  private SpiceManager spiceManager = new SpiceManager(JacksonSpringAndroidSpiceService.class);  

Also we need to start it on the onStart method of the activity before using it:
1:       @Override  
2:       protected void onStart() {  
3:            super.onStart();  
4:            spiceManager.start(this);  
5:       }  

And stop the spiceManager when the activity stops:
1:       @Override  
2:       protected void onStop() {  
3:            spiceManager.shouldStop();  
4:            super.onStop();  
5:       }  

In our onCreate method, we execute the request like this:
1:  ForecastListRequest request = new ForecastListRequest();  
2:            spiceManager.execute(request, new RequestListener<ForecastList>() {  
3:                 @Override  
4:                 public void onRequestFailure(SpiceException arg0) {  
5:                      Log.i("ForecastListRequest", "failed");  
6:                 }  
7:                 @Override  
8:                 public void onRequestSuccess(ForecastList arg0) {  
9:                      Log.i("ForecastListRequest", "success!");  
10:                      List<Forecast> list = arg0.getList();  
11:                      for (Forecast forecast : list) {  
12:                           Log.i("ForecastListRequest", "dt=" + forecast.getDt());  
13:                      }  
14:                 }  
15:            });  

The full source code for this tutorial can be downloaded here

Monday, November 25, 2013

Using Java Enum As An Alternative to Bit Flags

Recently, I needed to use bit flags as parameter to a method to determine its output. I noticed while doing a bit of research online that most people suggest using EnumSet instead of bit flags as a parameter. Normally,  I use the bit flag like this:

1:  public class SampleUtil {  
2:       public static final int FLAG_1 = 1 << 0;  
3:       public static final int FLAG_2 = 1 << 1;  
4:       public static final int FLAG_3 = 1 << 2;  
5:       private static String processString1(String input) {  
6:            return input + "process1";  
7:       }  
8:       private static String processString2(String input) {  
9:            return input + "process2";  
10:      }  
11:      private static String processString3(String input) {  
12:           return input + "process3";  
13:      }  
14:      public static List<String> processInput(String input, int flags){  
15:            List<String> output = new ArrayList<String>();  
16:            if ((flags & FLAG_1) == FLAG_1) {  
17:                 output.add(processString1(input));  
18:            }  
19:            if ((flags & FLAG_2) == FLAG_2) {  
20:                 output.add(processString2(input));  
21:            }  
22:            if ((flags & FLAG_3) == FLAG_3) {  
23:                 output.add(processString3(input));  
24:            }  
25:            return output;  
26:       }  
27:  }  

For every flag set, I perform a method on an input and add it to the results. Works well but maybe things could be better.. so I decided to take a look at using enums. Taking another look at the docs, I remembered that enums are much more powerful and versatile than bit flags.

Since enum is also a class, I decided to exploit this property. One thing I noticed with the methods used for processing the string is that they all have the same input and output type. Another thing is that each one is tied to a certain flag exclusively. Because of this, I made an interface that represents all these methods.
1:  public interface IStringProcessor {  
2:       String processString(String input);  
3:  }  

Then, I modified the constructor to add a parameter for the enum:
1:       private IStringProcessor processor;  
2:       ProcessFlag(IStringProcessor processor) {  
3:            this.processor = processor;  
4:       }  

I also added a method to my enum class so I can use the processor passed on the constructor of the enum.
1:       public String applyMethod(String input) {  
2:            return processor.processString(input);  
3:       }  

Then I initialized the enums:
1:       FLAG_1(new IStringProcessor(){  
2:            @Override  
3:            public String processString(String input) {  
4:                 return input + "process1";  
5:            }  
6:       }),  
7:       FLAG_2(new IStringProcessor(){  
8:            @Override  
9:            public String processString(String input) {  
10:                 return input + "process2";  
11:            }  
12:       }),  
13:       FLAG_3(new IStringProcessor(){  
14:            @Override  
15:            public String processString(String input) {  
16:                 return input + "process3";  
17:            }  
18:       });  

To use enumset as a parameter, I modified my "processInput" method and used the enum type for processing my input string:
1:       public static List<String> processInput(String input, EnumSet<ProcessFlag> flags){  
2:            List<String> output = new ArrayList<String>();  
3:            Iterator<ProcessFlag> iterator = flags.iterator();  
4:            while (iterator.hasNext()) {  
5:                 ProcessFlag pFlag = iterator.next();  
6:                 output.add(pFlag.applyMethod(input));  
7:            }  
8:            return output;  
9:       }  

Here is a short code to demonstrate how to use the "processInput" method:
1:       public static void main(String[] args) {  
2:            EnumSet<ProcessFlag> flags = EnumSet.of(ProcessFlag.FLAG_1, ProcessFlag.FLAG_2);  
3:            List<String> strings = SampleUtil.processInput("Hello", flags);  
4:            for (String s : strings) {  
5:                 System.out.println(s);  
6:            }  
7:       }  

A complete source for this demo can be downloaded from here