DroidTerm v5.0 USB Serial port for Android

Last information about the current state of DroidTerm. Please check it out

I have released a new version of DroidTerm. It fixes some bugs and I consider it fairly stable right now but besides typical bug fixing I added a new feature some of you considered a nice one and I really agree with you. Now It is possible to save connection profiles in order to allow a faster start. The process is pretty simple.

Start DroidTerm as usually, select your settings and connect. Now in terminal screen click on Preferences button:

Screenshot_2014-10-16-21-29-39

Click on “Save Profile”, Give it a fancy name and save it. Your profile will be stored with your current connection settings and It will available next time.

Screenshot_2014-10-16-21-34-44

This dialog will appear if you try to connect a new device and You have at least one stored profile for that device (profiles are associated with a pair of numbers called VID and PID which identify a given device).

I am open to any suggestions regarding DroidTerm. So let me know if you have some good ideas 🙂

The ethics of programming

Today I am not going to talk about any development I am doing or anything related to my activities. I am going to switch to my philosophical side because I really think We, as programmers, usually code things only because We could or We must to and We really need start to think seriously about “what we should do”.

Here in Spain, my country of origin, A yet another outrageous corruption scandal has emerged this week. A brief description of that scandal would be: More than eighty top directives of a bank entity (bailed out by the government later) besides their amazing salaries, received a near magical credit card called humorously black card which gave them an undeclared to the tax office sum of money ready to use at their will. Of course, following our outstanding picaresque tradition most of them spent their money in things like lingerie, therapeutical asian massages, unspecified night clubs with unspecified reputation and so on.

Obviously their IT systems were prepared to diligently to deal carefully with the narrow range of credit cards numbers owned by these guys. And that’s what involves us here. Somebody (and I can imagine perfectly a young suited corporate guy with a poor salary) coded that system probably without even wondered himself what he was coding.

Those guys are not, by any mean, responsible of this scandal but It is a good example of how we can affect the world with our code. We code complex derivative trading orders, though by really smart mathematicians which barely understand them and They convert them to recipes for people who doesn’t understand them at all. We entirely coded the subprime crisis and only god knows what kind of disaster We are coding now.

In some moment of our lives we gave up our geeky culture which embraces really great values. I perfectly know money is a necessary evil and We can’t avoid paying bills, taxes… But when I see young kinds in college bragging about their commitment with open source, open values, free liberty, new monetary systems like bitcoin and years later They are coding for a horrendous bodyshops I cant avoid to think We are just posing, and no, Sticking cool javascript based technologies decals in your laptop is not going to save us if we keep coding harmful shit.

In the end this is a matter of coherence, coherence is a lost virtue in the 2.0 world. It is necessary for us to keep a minimum of coherence with our values. It is not the easiest path, it is the best path in the long term. And of course We shouldn’t forget our code affects people out there.

I strongly recommend this video, although It is about designing, applies nicely to us

DroidTerm v4.0 USB Serial port for Android

Last information about the current state of DroidTerm. Please check it out

Some weeks ago I uploaded a new version of DroidTerm with some improvements. One of these improvements was a log system to save your session. Well I made some changes that allow view your logs inside your app. Press “Log Viewer” and choose your log.
Screenshot_2014-08-28-21-18-33

I added a new way to send data. In prior versions users had to click on terminal and send one character at a time. This way is not gone but now it is possible to send more data at a time.
Just connect your device, start your session with your settings, press option button and select “Send bulk data”
Screenshot_2014-08-28-21-19-17

DroidTerm is getting more complete each month and I almost lack of missing features. If you are using it and you have a good idea I would love to hear it 🙂

Happy crafting!

Speeding up SQLite insertions for Android developers

SQLite is a very important asset of every Android programmer. It offers a really easy to use solution to cache all your data. As a local database, most of the time, it is not going to suffer of heavy insertions. But sometimes you are going to have to insert a lot of rows and, if you are not very well informed, you are going to discover in a painful way that the common way of insert data using Android api is astoundingly slow. I had to deal with that blow when programming DroidTerm because I needed a local database of USB vids and pids (Naively I started to look for REST api or something like that. Eventually I found something…that was merely a web hosted text file).

These examples are based on code I wrote working on this and code is available here.

Mainstream insertions
This is what you are going to find first time you have to populate a SQLite database in Android.

private SQLiteDatabase db;
/*
...............
*/
public long insertEntryVersion(String version, String date)
{
    ContentValues values = new ContentValues();
    values.put(VERSION_COLUMN, version);
    values.put(DATE_COLUMN, date);
    values.put(ID_VERSION, currentVersion);
    return db.insert(VERSION_TABLE, null, values);
}

It is an easy way using Bundle-like ContentValues class to store data per column and inserting through SQLiteDatabase.insert(String table, String nullHack, ContentValues values) without messing with your own SQL statement, nice huh? Well, most of the times I use this and works fine but if you are going to perform a heavy insertion you are going to discover that inserting…let´s say… thousands of rows can last for more than a minute or even more!

But it is not a big deal when you know what you need to speed up insert operations. Compiled statements, and even more important, SQL transactions are going to save the day.

Not all is lost
Compile your insert instructions as follows:

private SQLiteDatabase db;
/*...*/
private static final String INSERT_VENDOR = "insert into vendorTable(vid,vid_name) values(?,?)";
/*... */
insertVendor = db.compileStatement(INSERT_VENDOR);

Our SQL statement is now compiled so We are going to create a function to handle it.

public void insertEntryVendor(String vid, String vidName)
{
    insertVendor.bindString(1, vid);
    insertVendor.bindString(2, vidName);
    insertVendor.execute();
    insertVendor.clearBindings();
}

And it is all ready to insert all our data much faster!

String[] vidPid = new String[2];
db.beginTransaction();
while(vidPid != null)
{
    vidPid = vidPidGenerator(); // Returns null when no more vid and pids are available
    if(vidPid != null)
    {
        insertEntryVendor(vidPid[0], vidPid[1]);
    }
}
db.setTransactionSuccessful();
db.endTransaction();

It is that simple! I hope you found this little help useful 🙂

Happy crafting!

DroidTerm v3.0 USB Serial Port for Android

Last information about the current state of DroidTerm. Please check it out

I uploaded a new version of DroidTerm some days ago with some changes I would like to share with you. First of all, I decided to drop Bluetooth SPP (Serial Port Profile) support from DroidTerm. I did not consider it my first goal when I started to develop my app. I was struggling to find a great replacement in Android for Putty as a serial terminal so that became my first objective and, eventually, I decided to add support of Bluetooth SPP because it would be a not difficult task. Months later I spent hours refining the USB serial interface of DroidTerm adding devices, fixing bugs… so now It is pretty stable. Unfortunately I almost forgot completely about bluetooth. So it was not so stable at all and I have decide to focus on USB stuff.

Now the good things! You can generate logs of your sessions and keep them for further study. Saving a log of your session is easy:
– Connect your USB-Serial device and configure it as you want.
– Press options button whenever you want.
Screenshot_2014-08-14-17-19-24
– Select “Save Log” and your session will be saved in a folder called DroidTerm in your SD card. Files follow this name convention:

YYYY_MM_DD__HH__MM_SS.txt

The text files generated by DroidTerm save not only raw data (Text or Hex representation as We will see next) but metadata of session too.

#Date: 2014/08/06 13:58:19
#Device Name: FT232 USB-Serial (UART) IC
#Baud rate: 9600
#Data bits: 8
#Stop bits: 1
#Parity: None
#Flow: None

0x6C 0x6B 0x6B 0x6C 0x6B 0x6B 0x6C 0x6A 0x64 0x64 0x61 0x61 0x61 0x61 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x20 0x4D 0x65 0x20 0x6C 0x6C 0x61 0x6D 0x6F 0x20 0x46 0x65 0x6C 0x69 0x70 0x65 0x20 0x79 0x20 0x65 0x6F 0x73 0x20 0x66 0x69 0x66 0x6A 0x64 0x6E 0x20 

The next improvement, as you may noticed before, is a Hexadecimal representation of received data. I missed that really useful feature when you are debugging, or gaining understanding of a protocol and you need the raw data.

Here an example received from a scrollable LED with String representation:

Screenshot_2014-08-14-17-51-36

Obviously except first bytes information is not encoded at all. So Hex mode is necessary to study how this scrollable Led communicates with host:

Screenshot_2014-08-14-17-52-12

I have more improvements in mind but They will have to wait for a next release.

Happy craft!

Hunting down memory leaks in Android

One of the most common myths They told us about programming in a Garbage collector environment is there is no need to worry about memory management. Ok, that is usually right most of the time but it is not complete truth (in fact, memory leaks in GC environments are pretty difficult to spot). There are some potencial sources of memory leaks and some of them are not obvious and they can lead to a huge memory leakage.

A visual representation of an Android app with leaks

There is a well-known potential cause of memory leaks on Android which it is usually called “Leaking the Context” and it is a very problematic source of leaking memory because, as you know, an Activity (inherited from Context) is a potential god-object with a lot of references and it has to be destroyed and re-created every time you change the orientation of the screen.

Although it is a common issue is not usually well explained, or explained at all in Android tutorials or introductory books. There are some good links with amazing information about this issue but they usually lack of examples.

So I am going to take a “learning by example” approach to make you and extraordinary and merciless hunter of memory leaks.

Elmer Fudd, a pioneer of leak hunting and deeply misunderstood as almost all pioneers

The one you are going to see in every Memory leak example out there

This is the most common and easiest example of a memory leak you are going to find. First let´s take a look at this piece of code

public class MainActivity extends Activity
{
    static LeakMeNow leak; // static classes can be GC roots

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(leak == null)
        {
            leak = new LeakMeNow();
            leak.logSomethingLeaky();
        }
    }

    @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;
    }

    private class LeakMeNow
    {
        // This class holds a reference of Activity
        public void logSomethingLeaky()
        {
            Log.i("LeakExamples", "I know you are going to leak something here, just shake   your phone");
        }
   }
}

It looks pretty simple and unoffensive isn’t it? It is not so innocent, it hides a memory leak. LeakMeNow class is an inner class and all inner classes keep a reference of their enclosing classes. This leads to a memory leak if, as it is happening in this example, a static reference of this inner class has been declared. Fortunately this example is really simple to solve. We have two options.

Make the reference non-static:

LeakMeNow leak; // Non static class, safe now

If you really need a static reference and need access to variables from Activity, you have to make your inner class static and pass a WeakReference to your activity.

private static class LeakMeNow
{
    // It is not going to leak now
    private WeakReference upperClassReference;

    private LeakMeNow(MainActivity activity)
    {
        upperClassReference = new WeakReference(activity);
    }

    // This class holds a reference of Activity
    public void logSomethingLeaky()
    {
        Log.i("LeakExamples", "I know you are going to leak something here, just shake your  phone");
    }
}

Threads are dangerous too!

Threads are a potential cause of leaks too. Let’s see this code:

public class MainActivity extends Activity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new LeakyThread().start();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public class LeakyThread extends Thread
    {
        public void run()
        {
            synchronized(this)
            {
                try
                {
                    wait();
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }
}

Every time onCreate is called a new thread is going to be created and started. When orientation is changed those threads will remain and, consequently the Activity is not available for collection.

Best solution is being careful with your thread lifecycle and stop them when necessary. In this particular example is really easy:

public class MainActivity extends Activity
{
    private LeakyThread thread;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       thread = new LeakyThread();
       thread.start();

    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        thread.stopThread();
    }

    @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;
    }

    public class LeakyThread extends Thread
    {
        public void run()
        {
            synchronized(this)
            {
                try
                {
                    wait();
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }

    public void stopThread()
    {
        synchronized(this)
        {
            notify();
        }
    }
  }
}

Basically you don’t have to create threads as anonymous classes and it is imperative to stop them before the destruction of the Activity.

A really subtle one (based on real events)

The third leak is going to be more difficult to spot. Although it involves a thread and We already know they are prone to problems, the thread involved here is not a subclass or an anonymous class of the Activity, it is completely separated of it. It means this thread should not be a GC root of the Activity (threads are potential candidates to be roots) but IT IS THE GC ROOT!!! Some code:

public class SemperVigilans 
{
	// This class, as techie new form of inquisition, it is going to check the incoming arrival of the end
	
	private ViewGroup viewGroup;
	private SemperVigilansThread thread;
	
	public SemperVigilans(ViewGroup viewGroup)
	{
		this.viewGroup = viewGroup;
		this.thread = new SemperVigilansThread();
		this.thread.start();
	}
	
	
	private class SemperVigilansThread extends Thread
	{
		
		public void run()
		{
			while(viewGroup.getWidth() != 666 && viewGroup.getHeight() != 666)
			{
				// World is save...at least for now
			}
			
			// Here a callback to warn the world about incoming apocalypse would be awesome
		}
	}

}

Our Activity:

public class MainActivity extends Activity
{
	private RelativeLayout layout;
	private SemperVigilans semperVigilans;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		LayoutInflater inflater = getLayoutInflater();
		layout = (RelativeLayout) inflater.inflate(R.layout.activity_main, null);
		semperVigilans = new SemperVigilans(layout);
	}
	
	@Override
	public void onDestroy()
	{
		super.onDestroy();
	}
 
	@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;
	}
	
}

When this code is executed and orientation is changed you leak all the Activity but..Why? Well it is happening the same problem as before, but in a more subtle way. SemperVigilansThread is getting a reference from Activity through the Layout reference passed when SemperVigilans is created. Because Views objects have always a reference to the Context and in this case this reference reaches this thread. The solution is the same, control the lifecycle of your thread. If you remove all references to the Context but still your lifecycle is not controlled, you are still leaking but not the entire Activity.
View objects and Drawables objects are dangerous objects because both of them hold references to the Context. Drawables are even more dangerous because their references to their context are even less obvious Be careful with them.

Memory leaks are not exclusive of Activities

Leaking the context is probably the worse of all memory leaks you can get in Android but it is worth to mention that is not the only kind of leak you can get. As seen before, inner classes and anonymous classes are going to be naughty here:

public class LeakGenerator 
{
	// A leak generator
	
	public LeakGenerator()
	{
		
	}
	
	public Leak generateLeak()
	{
		return new Leak();
	}
	
	
	public class Leak
	{
		public Leak()
		{
			
		}
		
	}
}

MainActivity:

public class MainActivity extends Activity
{
	private Button firstTimeButton, everyTimeButton;
	private List<Leak> listOfLeaks;
	private LeakGenerator generator;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		firstTimeButton = (Button) findViewById(R.id.buttonfirsttime);
		everyTimeButton = (Button) findViewById(R.id.buttoneverytime);
		
		listOfLeaks = new ArrayList<Leak>();
		
		
		
		firstTimeButton.setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				if(generator == null)
				{
				    generator = new LeakGenerator();
				}
				    
				listOfLeaks.add(generator.generateLeak());
			}
			
		});
		
		everyTimeButton.setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				listOfLeaks.add(new LeakGenerator().generateLeak());
			}
			
		});
		
		
	}
	
	@Override
	public void onDestroy()
	{
		super.onDestroy();
	}
 
	@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;
	}
	
}

This example is really easy, two buttons, one of them leaks one LeakGenerator() the first time you pressed and the other leaks a new LeakFactory() when pressed.

The first button only leaks the reference to LeakGenerator(). Even if the generator is not going to be use anymore it is going to live because every single leak reference has a reference to the generator. We can infer from this example that Objects from inner classes can’t outlive the outer class object which they hold a reference

The second button is a worse thing because every Leak object has a reference to a different generator.

That is all I have to say about this ugly issue I know you will face as an Android developer, it is better to be prepared before hunt them down.

Here some great essential links about Memory leaks:
Google I/O 2011: Memory management for Android Apps

Activities, Threads, & Memory Leaks

I hope you find useful this post. If you have some suggestions or you found some bugs just let me now 🙂

Happy Craft!

DroidTerm v2.0

Last information about the current state of DroidTerm. Please check it out

A month ago I released an Android app called DroidTerm to fulfill my needs of a simple serial terminal application. It worked pretty well but I started to want more features.
So I just released a new version of DroidTerm with a feature I really missed a lot. An Usb viewer to read Usb parameters in a meaningful way. Let me show you an example:

usbviewer1

In order to get a meaningful representation of vendor and product data DroidTerm fetches data from The USB ID Repository

I fixed some bugs too. So DroidTerm should be working better now If you have some problems using it just post a comment or email me.

Happy craft!

Get vendor and product name from VID and PID in Android

Usb devices are identified by two 16-bit numbers known as VID and PID (Vendor id and Product Id). These keys are, among a lot of other things, an advantage of Usb over other vintage ports as serial ports. Unfortunately if you are developing an application which needs to show a readable information about devices attached to usb root hubs these keys are pretty cryptic and need to be decoded into human readable information.
During the development of DroidTerm I reach this problem because I am working on a Usb viewer of what is attached to Usb port. First I was looking for a beautiful REST API with its fancy methods and its json responses but I only could find The Usb Id repository which is a text file and nothing more. But It seems very complete and reasonably updated so there is no reason to moan.
I defined this features:
– Data should be stored locally using SQLite to avoid dependency on network.
– Local database should be updated when new devices were added to Usb Id Repository.
– All database operations should be encapsulated.
So I released this piece of code to fill my own requirements.
An example of how it works:

/*
* Example of use
* @author: felhr (felhr85@gmail.com)
*

// Clone all the files needed: git clone https://gist.github.com/afe18397dc2441862337.git
// Permissions needed: <uses-permission android:name="android.permission.INTERNET" /> 

// There are some callbacks related with created, opened and updated database events. It is not necessary to use them.
private UsbDataProvider.UsbDbCallback mCallback = new UsbDataProvider.UsbDbCallback()
{
	@Override
	public void onDbOpenedFirstTime(boolean status)
	{
	// status == false means database could not be created due to an error fetching data from source
	// status == true means database was successfully created

	// Code here
    }

	@Override
	public void onDbOpened()
	{
	// Database opened
	// Code here
	}

	@Override
	public void onDbUpdated(String newVersion)
	{
	// Database updated with newVersion
	// Code here
	}
};

UsbDataProvider dataProvider;
dataProvider = new UsbDataProvider(context, mCallback); // Create and open, open or update and open database if necessary. Notifications on callback
//dataProvider = new UsbDataProvider(context)

String vid = "03f0"; // Must be an hex representation of 16 bit number (0000-FFFF). Don't worry about uppercase or lowercase
String pid= "010C"; // Must be an hex representation of 16 bit number (0000-FFFF). Don't worry about uppercase or lowercase

UsbData data = dataProvider.lookup(vid, pid); // Returns null if vid or pid are not valid inputs or database could not be created
if(data != null)
{
	String vendorName = data.getVendorName(); // Vendor name
	String productName = data.getProductName(); // Product name
}

I hope you find this piece of code useful. Happy craft!

DroidTerm: A serial port terminal emulator for Android

Last information about the current state of DroidTerm. Please check it out

During my most recent work I had to deal a lot with serial ports and Usb to serial converters. Most of the work used an Android device as a host of a usb-serial converter to send commands through a serial connection to a custom hardware we developed. I certainly missed a good replacement of PuTTY for Android. Some apps I encountered are faulty or does not support the converters I am using for. That is the reason because I started to develop my own replacement.
Finally I shipped the first version of this app that I called DroidTerm.
Here it is the link if you are interested

Features:
– Allows serial connections over Bluetooth Serial Port Profile and Usb.
– It supports FTDI chipsets (nice for Arduino stuff), CP210x family of chipsets and soon Prolific pl2303 chipsets. Not only defaults VID and PID, it supports custom VID and PIDS of other manufacturers too.
– In Usb serial connection, baud rate, data bits, stop bits, parity can be configurable before connection. Flow control is still not supported.

There is plenty of room for new features and improvements:
– Flow control and almost more importantly, a interface to handle it manually.
– Send through serial port a selected filed from a file explorer.
– Macros (Implement a simple BASIC-like language and a simple interface to code on mobile devices would be awesome).
– Add more not supported devices, although that must be done on Usb Serial android library
– Design improvement, that is not my best area so do not expect something much better than the retro style it has now.

If you use it, you find it useful and you have some new ideas or improvements I would love to hear them.

Happy craft!

UPDATE: Devices with PL2303 chipsets are now supported. I would like some feedback about this new feature 🙂
https://lh3.ggpht.com/Ms-VlbxWea5n3yUDqsx1ZZcjswxA-cpR4xC35XcYOszlszUUfXvDq8tkozQ9vKihXvOt=h900-rw

https://lh5.ggpht.com/RSMTKtvYHBNPkMuwiGlRju8iCjq8JW8VQvOVphDYf0gsa-nu7Vk8RNCbXaMqhDGkfA-J=h900-rw

Catch soft keyboard show/hidden events in Android

Android offers you an overwhelming api loaded with tons of overridable functions representing typical events you may face as a mobile developer. That is the reason because you are not usually worry about catching and handling a new event that you have never meet before, you guess, normally right, those smart kids from Mountain View implemented an event handler sometime ago. Well, this is not the case of soft keyboard. It can be easily show and hide with convenient methods but there is not an implemented way of catching when user choose to hide it. Due to this limitations I coded a simple snippet that I hope it will be useful. It is available here. It is pretty easy to use.

/*
Somewhere else in your code
*/
RelativeLayout mainLayout = findViewById(R.layout.main_layout); // You must use your root layout
InputMethodManager im = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
	
/*
Instantiate and pass a callback
*/
SoftKeyboard softKeyboard;
softKeyboard = new SoftKeyboard(mainLayout, im);
softKeyboard.setSoftKeyboardCallback(new SoftKeyboard.SoftKeyboardChanged()
{
 
	@Override
	public void onSoftKeyboardHide() 
	{
		// Code here
	}
 
	@Override
	public void onSoftKeyboardShow() 
	{
		// Code here
	}	
});
	
/*
Open or close the soft keyboard programatically
*/
softKeyboard.openSoftKeyboard();
softKeyboard.closeSoftKeyboard();

/*
SoftKeyboard can catch keyboard events when an EditText gains focus and keyboard appears
*/

/* Prevent memory leaks:
*/
@Override
public void onDestroy()
{
    super.onDestroy();
    softKeyboard.unRegisterSoftKeyboardCallback();
}

Besides this, you must add this line to your activity reference in your manifest.xml.

android:windowSoftInputMode="adjustResize"

While I were coding this snippet I encountered with another snipper which is pretty awesome. It is basically the same, involves subclassing your main layout but I think is a very elegant solution. Use which solution fits better with your needs. Happy coding!

UPDATE (06/15/14): This snippet has been updated with some improvements but It can be used in the same straightforward way and it handles keyboard events from EditText too
This snippet was too specific and it could not catch open keyboard events from EditText, it only worked if you opened and closed keyboard with provided functions and EditText opens keyboard as default behavior. Obviously this was a heavy shortcoming I did not notice before. So here it is my fix: The constructor of SoftKeyboard has been changed from:

public SoftKeyboard(View layout, InputMethodManager im)

to:

public SoftKeyboard(ViewGroup layout, InputMethodManager im)

This means it is necessary to pass a reference of main layout now. Maybe it is more strict now but it is necessary for something we are going to see next and, really, it was not working with whatever view.

SoftKeyboard class, when instantiated, it is going to try to get a reference, if possible, of every EditText available. This will allow it to handle focus changes when a EditText is selected and keyboard appears.

private void initEditTexts()
{
    editTextList = new ArrayList<EditText>();
    int childCount = layout.getChildCount();
    for(int i=0;i<=childCount -1;i++)
    {
        View v = layout.getChildAt(i);
        if(v instanceof EditText)
	    {
	       EditText editText = (EditText) v;
	       editText.setOnFocusChangeListener(this);
	       editText.setCursorVisible(false);
	       editTextList.add(editText);
	    }
    }
}

SoftKeyboard implements the interface View.OnFocusChangeListener to handle properly focus changes on our EditTexts.

@Override
public void onFocusChange(View v, boolean hasFocus) 
{   
    if(hasFocus && !isKeyboardShow)
    {
        layoutBottom = getLayoutCoordinates();
        softKeyboardThread.keyboardOpened();
        isKeyboardShow = true;
        tempView = v;
    }
}

I noticed the resize process when keyboard appears through an EditText gaining focus has some differences and it was breaking the logic of the thread which is checking the bottom position of the layout. So i added this silly loop to handle it.

// When keyboard is opened from EditText, initial bottom location is greater than layoutBottom
// and at some moment equals layoutBottom.
// That broke the previous logic, so I added this new loop to handle this.
while(currentBottomLocation >= layoutBottom)
{
    currentBottomLocation = getLayoutCoordinates();
}

There are some minor changes too but I think these are the most important changes. I have tested it but nothing is 100% bugs-free. I would love read your feedback about this modification.

UPDATE (10/07/14): Thanks to Francesco Verheye(verheye.francesco@gmail.com) this snippet can handle EditTexts attached to nested subViews. initEditText modifications:

private void initEditTexts(ViewGroup viewgroup) 
{
    if(editTextList == null)
        editTextList = new ArrayList<EditText>();
		
    int childCount = viewgroup.getChildCount();
    for(int i=0; i<= childCount-1;i++) 
    {
        View v = viewgroup.getChildAt(i);

        if(v instanceof ViewGroup) 
        {
	    initEditTexts((ViewGroup) v);
	}

        if(v instanceof EditText) 
        {
            EditText editText = (EditText) v;
            editText.setOnFocusChangeListener(this);
            //editText.setCursorVisible(false);
            editTextList.add(editText);
        }
    }
}