Sunday, June 22, 2014

Tizen SDK HelloAccessoryConsumer Sample Application Error

When using the guideline for testing the gear applications on emulator, there is a part where you have to install the HelloAccessoryConsumer app on the galaxy gear simulator and the HelloAccessoryProvider app on the host application. While following the guide for the first time, it is possible that you will encounter the following error message:

 js/main.js (44) :err [undefined] msg[undefined  

To get around this error, open the HelloAccessoryConsumer project on your Tizen IDE and look for the accessoryservices.xml file inside the: res/xml folder.

Look for this section
 <supportedTransports>  
      <transport type="TRANSPORT_BT” />  
 </supportedTransports>  

Change the value for the transport type into:
 <supportedTransports>  
      <transport type="TRANSPORT_WIFI" />  
 </supportedTransports>  

After modifying this on the consumer project, open the HelloAccessoryProvider android project. Look for the accessoryservices.xml file inside the: res/xml folder.

Look for this section:

And change the transport like below:

Redeploy both the consumer and the provider application on their corresponding devices.

Original post for this solution can be found in the Samsung Developer Forum.

Tuesday, January 7, 2014

Step by Step Setup of eBay Java SDK on Maven

This guide assumes that you are using Eclipse ide with the maven plugin properly configured.

Download the eBay SDK java from their site

Create a new maven project using the maven quickstart archetype


Set the archetype parameters

You should now have a basic maven project. Go to package explorer and delete the App.java file.

Since the basic project does not have a resource folder, we should add one. It should be located on src->main->resources folder:

Highlight the resources folder and add it to the build path as a source folder.


Open the folder where you extracted the contents of your eBay java sdk. For my guide, I used eBaySDKJava849.zip and the folder contents are as follows:

Go to the source/core/ebay/sdk of the extracted sdk folder and copy its contents to the src/main/java/com/ebay/sdk folder of the maven project we made earlier:

Go to the source/wsdl of the extracted sdk folder and copy its contents to the src/main/resources folder of the maven project.
 Go to the build folder of the extracted sdk and copy custom-binding.xml and jaxb-binding.xjb to the root directory of the maven project:

Modify the wsdl location in the custom-binding.xml file. Since the name of the project in this example is ebaysdkcore, our configuration is as follows:
1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <jaxws:bindings wsdlLocation="../ebaysdkcore/src/main/resources/eBaySvc.wsdl"  
3:       xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"  
4:       jaxb:version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">  
5:       <jaxws:bindings  
6:            node="//xs:complexType[@name='ReviseInventoryStatusRequestType']">  
7:            <jaxws:bindings node=".//xs:any">  
8:                 <jaxb:property name="reviseInventoryStatusRequestTypeAny" />  
9:            </jaxws:bindings>  
10:       </jaxws:bindings>  
11:  </jaxws:bindings>  


Go to the build/maven_build of the extracted sdk and copy the pom.xml and place it on the root directory of the maven project.

Modify the pom.xml file to add this missing dependency:
1:  <dependency>  
2:       <groupId>org.slf4j</groupId>  
3:       <artifactId>slf4j-api</artifactId>  
4:       <version>1.7.5</version>  
5:  </dependency>  

Also modify this section of the pom.xml file:
1:  <binding dir="${basedir}" includes="custom-binding.xml"/>  

and change it into this to include the jaxb-binding.xjb file:
1:  <binding dir="${basedir}" includes="custom-binding.xml,jaxb-binding.xjb"/>  

Open the command window and run the following command:
 set MAVEN_OPTS=-Xmx512m  

This ensures that maven has enough memory to run the build.

Again on the command window, go to the root folder of the maven project and run the command to build the project:
 mvn -e clean package  


Credits to this solution from the eBay developer forum.

Complete source can be view from this repo

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