Advertisement

Sri Lanka's First and Only Platform for Luxury Houses and Apartment for Sale, Rent

Thursday, March 14, 2013

Fixing "name" is not translated in locales in Android

If you develop Android applications which has multiple locales, you might face an error similar to the below one

"<Value Name>" is not translated in <Locales> ...

This is because some names which you don't want to be translated are also taken as translatable names. The easiest fix for this is to mark the error cause name tag as

<string name="myname" translatable="false">

<string-array name="myname" translatable="false">

in string, string-array element. Or you can define all your non-translatable strings in a resource file called donottranslate.xml. Or, you can ignore the issue with a tools:ignore="MissingTranslation" attribute.

Monday, March 4, 2013

My First Android Jelly Bean App

I have been wanting to learn Android App development for sometime now and I wanted to start from the basics and progress. So I read the documentations and some tutorials and wrote my first app using Eclipse Helios with ADT Plugin.

I must tell Eclipse ADT Plugin 20.x has come a long way from its predecessors and now has the capability to perform many tasks directly from the plugin from development to signed package deployment.

The App I wrote is named Color Changer and as the name suggests it just changes color of the App based on some user input. This is really basic but enabled me to understand a lot about Android App structure.



There is a main AndroidManifest.xml where the Application is defined.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.shazin.colorchanger"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.shazin.colorchanger.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

And one Activity named MainActivity

package com.shazin.colorchanger;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.view.Menu;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class MainActivity extends Activity implements OnSeekBarChangeListener {

    private TextView textViewColor;
    
    private SeekBar seekBarRed;
    
    private SeekBar seekBarGreen;
    
    private SeekBar seekBarBlue;
    
    private int red, green, blue;
    
    private LinearLayout linearLayout;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        linearLayout = (LinearLayout) findViewById(R.id.linearLayout1);
        
        textViewColor = (TextView) findViewById(R.id.textViewColor);
                
        seekBarRed = (SeekBar) findViewById(R.id.seekBarRed);
        seekBarGreen = (SeekBar) findViewById(R.id.seekBarGreen);
        seekBarBlue = (SeekBar) findViewById(R.id.seekBarBlue);
        
        seekBarBlue.setOnSeekBarChangeListener(this);
        seekBarGreen.setOnSeekBarChangeListener(this);
        seekBarRed.setOnSeekBarChangeListener(this);
        
        textViewColor.setText(String.format("(%d, %d, %d)", red, green, blue));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int value, boolean flag) {
        if(seekBar == seekBarRed) {
            red = value;
        } else if(seekBar == seekBarGreen) {
            green = value;
        } else if(seekBar == seekBarBlue) {
            blue = value;
        }
        linearLayout.setBackgroundColor(Color.rgb(red, green, blue));
        textViewColor.setText(String.format("(%d, %d, %d)", red, green, blue));
    }

    @Override
    public void onStartTrackingTouch(SeekBar arg0) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void onStopTrackingTouch(SeekBar arg0) {
        // TODO Auto-generated method stub
        
    }

}


And an Activity can have a Layout which defines the User Interface components

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="0dp"
        android:layout_marginTop="0dp"
        android:orientation="vertical" >

        <SeekBar
            android:id="@+id/seekBarRed"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            android:max="255"/>

        <SeekBar
            android:id="@+id/seekBarGreen"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            android:max="255"/>

        <SeekBar
            android:id="@+id/seekBarBlue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
            android:max="255"/>
            
        <TextView
            android:id="@+id/textViewColor"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"            
            android:textAppearance="?android:attr/textAppearanceLarge" />

    </LinearLayout>

</RelativeLayout>

And all the Strings used in the Application can be defined in strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Color Changer</string>
    <string name="action_settings">Settings</string>

</resources>


Source Code can be obtained from here.

Thursday, February 28, 2013

Android Jelly Bean and Arduino Uno Communication with USB Shield

It has been sometime since I wrote my last post. In between I bought a Samsung Galaxy Note 2 phone with Android Jelly Bean 4.1.1 Version and a USB Host Shield for Arduino. I have read that the  Arduino can be used as an ADK (Android Development Kit) alternative when it is plugged to a USB Shield.

There is a post in Circuits at Home web site which shows how to connect Android phone and Arduino with USB Shield. I followed the link but ran into problems while using the Sample program with Jelly Bean.

After hours and hours of googling I found the following needs to be done to enable Jelly Bean to communicate with Arduino Uno with USB Host Shield.

  1. You need Arduino IDE 1.0 or higher, can download it from this link
  2. You need the latest release of ADK which was released in 2012, can download it from this link
  3. Put the libraries available in above ADK into your Arduino IDE libraries directory.
Now you should be able to compile the code above shown in the Circuits at Home web site. If you get the errors similar to the following.


C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp: In static member function 'static void MAX3421E::setRST(uint8_t)':
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:58: error: 'PORTJ' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:58: error: 'PJ2' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:60: error: 'PORTJ' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:60: error: 'PJ2' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp: In static member function 'static uint8_t MAX3421E::readINT()':
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:65: error: 'PINE' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:65: error: 'PE6' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp: In static member function 'static void MAX3421E::pinInit()':
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:77: error: 'DDRE' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:77: error: 'PE6' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:78: error: 'DDRJ' was not declared in this scope
C:\Program Files\arduino-1.5.2\libraries\USB_Host_Shield\Max3421e.cpp:78: error: 'PJ2' was not declared in this scope

Then you need to have the following in your Max3421e_constants.h instead of the existing

#if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__)
  #define SCK_PIN   52
  #define MISO_PIN  50
  #define MOSI_PIN  51
  #define SS_PIN    53
#define MAX_SS    53
#define MAX_INT   9
#define MAX_GPX   8
#define MAX_RESET 7
#endif
#if  defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
  #define SCK_PIN   13
  #define MISO_PIN  12
  #define MOSI_PIN  11
  #define SS_PIN    10
#define MAX_SS    10
#define MAX_INT   9
#define MAX_GPX   8
#define MAX_RESET 7
#endif

Monday, December 17, 2012

SpringObjectFactory Error in creating application in Struts 2.3.7

Recently I tried to work with Struts 2 (2.3.7) Version and it gives the impression that all the Jars available in lib directory of the distribution are required to run. But seems that is not the case because it causes the following exception in Spring.
org.apache.catalina.core.StandardContext filterStart
SEVERE: Exception starting filter struts2
Class: com.opensymphony.xwork2.spring.SpringObjectFactory
File: SpringObjectFactory.java
Method: getClassInstance
Line: 230 - com/opensymphony/xwork2/spring/SpringObjectFactory.java:230:-1
    at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:483)
    at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:295)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:115)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4072)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4726)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    :754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Caused by: java.lang.NullPointerException
    at com.opensymphony.xwork2.spring.SpringObjectFactory.getClassInstance(SpringObjectFactory.java:230)
    at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:429)
    at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:471)
    ... 20 more
This Exception puzzles many people because it is related to Spring. To solve this you should just use the below mentioned Jars in the WEB-INF/lib directory only,
asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
commons-fileupload-1.2.2.jar
commons-io-2.0.1.jar
commons-lang3-3.1.jar
freemarker-2.3.19.jar
javaassist-3.11.0.GA.jar
ognl-3.0.5.jar
struts2-core-2.3.7.jar
xwork-core-2.3.7.jar

Tuesday, November 13, 2012

Storing Apache Hadoop WordCount Example Output to Database

Apache Hadoop WordCount example is the HelloWorld of Hadoop. Using this to Database Sinking of Hadoop output makes it easy to understand. Database I used is MySQL and the DDL for table used is as following;

CREATE TABLE word_count(word VARCHAR(254), count INT);
After creating the following Apache Hadoop Job along with Mapper and Reducer to Sink the output to Database. For this I use DBOutputFormat as the OutputFormat and DBConfiguration to specify DB configuration parameters.
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.StringTokenizer;

import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.lib.db.DBConfiguration;
import org.apache.hadoop.mapred.lib.db.DBOutputFormat;
import org.apache.hadoop.mapred.lib.db.DBWritable;

public class WordCount {
    public static class WordCountMapper extends MapReduceBase implements Mapper<LongWritable, Text, DBOutput, IntWritable> {
        private static IntWritable one = new IntWritable(1);
        private static DBOutput text = new DBOutput();
        @Override
        public void map(LongWritable key, Text value,
                OutputCollector<DBOutput, IntWritable> collect, Reporter arg3)
                throws IOException {
            StringTokenizer token = new StringTokenizer(value.toString());
            while(token.hasMoreTokens()) {
                text.setText(token.nextToken());
                collect.collect(text, one);
            }            
                        
        }
        
    }
    
    public static class WordCountReducer extends MapReduceBase implements Reducer<DBOutput, IntWritable, DBOutput, IntWritable> {

        
        @Override
        public void reduce(DBOutput key, Iterator<IntWritable> values,
                OutputCollector<DBOutput, IntWritable> collect, Reporter arg3)
                throws IOException {
            int sum = 0;
            IntWritable no = null;
            DBOutput dbKey = new DBOutput();
            
            while(values.hasNext()) {
                no = values.next();
                sum += no.get();
            }
            dbKey.setText(key.getText());
            dbKey.setNo(sum);
            collect.collect(dbKey, new IntWritable(sum));
            
        }
        
    }
    
    public void run(String inputPath, String outputPath) throws Exception {
        JobConf conf = new JobConf(WordCount.class);
        conf.setJobName("wordcount");
        DistributedCache.addFileToClassPath(new Path("<Absolute Path>/mysql-connector-java-5.1.7-bin.jar"), conf);

        // the keys are DBOutput
        conf.setOutputKeyClass(DBOutput.class);
        // the values are counts (ints)
        conf.setOutputValueClass(IntWritable.class);

        conf.setMapperClass(WordCountMapper.class);
        conf.setReducerClass(WordCountReducer.class);        
        
        conf.setOutputFormat(DBOutputFormat.class);

        FileInputFormat.addInputPath(conf, new Path(inputPath));
        DBOutputFormat.setOutput(conf, "word_count", "word", "count");
        
        DBConfiguration.configureDB(conf, "com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/sample", "root", "root");
        
        //FileOutputFormat.setOutputPath(conf, new Path(outputPath));

        JobClient.runJob(conf);
      }
    
    public static void main(String[] args) throws Exception {
        WordCount wordCount = new WordCount();
        wordCount.run(args[0], args[1]);
    }
    
    private static class DBOutput implements DBWritable, WritableComparable<DBOutput> {
        
        private String text;
        
        private int no;

        @Override
        public void readFields(ResultSet rs) throws SQLException {
            text = rs.getString("word");
            no = rs.getInt("count");
        }

        @Override
        public void write(PreparedStatement ps) throws SQLException {
            ps.setString(1, text);
            ps.setInt(2, no);
        }
        
        public void setText(String text) {
            this.text = text;
        }
        
        public String getText() {
            return text;
        }
        
        public void setNo(int no) {
            this.no = no;
        }
        
        public int getNo() {
            return no;
        }

        @Override
        public void readFields(DataInput input) throws IOException {
            text = input.readUTF();    
            no = input.readInt();
        }

        @Override
        public void write(DataOutput output) throws IOException {
            output.writeUTF(text);
            output.writeInt(no);
        }

        @Override
        public int compareTo(DBOutput o) {
            return text.compareTo(o.getText());
        }
        
    }
}
Furthermore I have written a custom Hadoop type for key which implements DBWritable and WritableComparable. I have used this as the Output Key Class. Command to run this is as following;
./bin/hadoop jar <Path to Jar>/HadoopTest.jar WordCount <Input Folder> <Dummy Output Folder>

Monday, November 12, 2012

Hadoop Vs Cassandra and HBase

The Vanilla hadoop consists of a Distributed File System (DFS) at the core and libraries to support Map Reduce model to write programs to do analysis. DFS is what enables Hadoop to be scalable. It takes care of chunking data into multiple nodes in a multi node cluster so that Map Reduce can work on individual chunks of data available nodes thus enabling parallelism.
The paper for Google File System which was the basis for Hadoop Distributed File System (HDFS) can be found here
The paper for Map Reduce model can be found here

For a detailed explanation on Map Reduce read this post
Cassandra is a highly scalable, eventually consistent, distributed, structured key-value store. It is not a conventional database but is more like Hashtable or HashMap which stores a key/value pair. Both Cassandra and HBase are implementations of Google's BigTable. Paper for Google BigTable can be found here.
BigTable makes use of a String Sorted Table (SSTable) to store key/value pairs. SSTable is just a File in HDFS which stores key followed by value. Furthermore BigTable maintains a index which has key and offset in the File for that key which enables reading of value for that key using only a seek to the offset location. SSTable is effectively immutable which means after creating the File there is no modifications can be done to existing key/value pairs. New key/value pairs are appended to the file. Update and Delete of records are appended to the file, update with a newer key/value and deletion with a key and tombstone value. Duplicate keys are allowed in this file for SSTable.  The index is also modified with whenever update or delete take place so that offset for that key points to the latest value or tombstone value.

Thus you can see Cassandra's/HBase's internals allow fast read/write which is crucial for real time data handling. Whereas Vanilla Hadoop with Map Reduce can be used to process batch oriented passive data.

Saturday, November 3, 2012

Distance Scanner - Low Cost Walking Aid for the Blind

I got the time to work on arduino and put up a small project to aid Blind people navigate through obstacles. There are many attempts made by the arduino community to accomplish this but most of them used motors, servo motors to give feedback. But Blind people have to get used to different inputs they get from these devices and driving motor requires a lot of battery power, thus users might have to end up changing batteries frequently.

Furthermore many Blind use sound which comes from tapping the White cane to navigate through obstacles so sound is something that they are already familiar with.

My approach uses a Ultrasonic Ping Sensor and a Buzzer to notify the Blind person who wears it with a Buzzing sound. Items required are;

  1. Arduino (Any Model)
  2. Ultrasonic Ping Sensor
  3. Buzzer or Piezo Speaker
  4. Jumper Cables

Arduino Sketch Source code is below 

/* 
  Distance Scanner 
  By Shazin Sadakath
*/

#define BUZZER 10

int URPWM = 3; 
int URTRIG=5; 

int minDistanceCm = 50;

unsigned int Distance=0;
uint8_t EnPwmCmd[4]={0x44,0x02,0xbb,0x01};    
 
void setup(){                                 
 
    pinMode(URTRIG,OUTPUT);                   
  digitalWrite(URTRIG,HIGH);                  
  
  pinMode(URPWM, INPUT);                      
    
  pinMode(BUZZER, OUTPUT);
}
 
void loop()
{
 digitalWrite(URTRIG, LOW);
 digitalWrite(URTRIG, HIGH);               
     
 unsigned long DistanceMeasured=pulseIn(URPWM,LOW);
     
 if(DistanceMeasured==50000){              
     // Invalid    
 }else{
     Distance=DistanceMeasured/50;           
 }
 delay(20);
 buzzBasedOnDistance();
}                      

void buzzBasedOnDistance() {
  int far = Distance - minDistanceCm;
  if(far <= 0) {
    digitalWrite(BUZZER, 200); 
  } else {
    digitalWrite(BUZZER, 0);
  }
}

There is a configurable minimum distance threshold and when objects get closer than that the buzzer makes the noise so that obstacle can be avoided. Check the video below for a small demonstration.




The USB cable is only used for Power. It can be replaced with a battery pack powering the arduino.

Constructive criticism is always welcome!