UsbSerial now allows using flow control signals RTS/CTS and DTR/DTS!

Finally I’ve managed to get some time to implement hardware flow control in UsbSerial! It is probably the most trickiest part of treating with these chipsets because every single one handles this in a very particular manner.

– CP210x devices check the modem status through a usb control transfer, so I was forced to perform a polling in a new thread every X time to check for changes.
– FTDI devices has a more clever way. Every 40 ms a 2-byte package is sent to the host which contains information about the modem signals and the flag errors.
– PL2303 (not implemented yet) have a USB INT endpoint which it is the obvious candidate where modem status data will be received, no really sure yet though.
– CH340/341 also have a USB INT endpoint but polling is also possible and, because some Android inner bugs, the best way to poll the lines state.

Let’s see how it works with an example

UsbDevice device;
UsbDeviceConnection usbConnection;
...
UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(device, usbConnection);
serial.open();
serial.setBaudRate(115200);
serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
serial.setParity(UsbSerialInterface.PARITY_NONE);
serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_RTS_CTS);

This is basically the same as the previous versions but now the setFlowControl is meaningful. Now that We have our connection configured to pay attention to the RTS and CTS lines let’s define our callback to receive or status changes.

private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() {
        @Override
        public void onCTSChanged(boolean state) {
            //Your code goes here!
        }
    };

And pass the reference to the UsbSerialDevice object

serial.getCTS(ctsCallback);

Now We know when the status of the line change. I will be also executed in the beginning to know what is the status of the line. If you need to raise the RTS or the DST lines jut write these lines.

serial.setRTS(true); // Raised
serial.setRTS(false); // Not Raised
serial.setDTR(true); // Raised
serial.setDTR(false); // Not Raised

PL2303, CH340/341 and CDC still lack of this feature. If you find something wrong just let me know. Happy crafting! πŸ™‚

Advertisements

DroidTerm PRO 1.2: Multi Character Encoding Support

I am happy to announce that DroidTerm PRO finally supports different character encodings which can be useful to connect with some legacy systems that still uses things like the CodePage 437 to extend ASCII. Current character encodings are:

– ASCII
– ISO 8859-1
– UTF-8 (set by default)
– UTF-16
– CP437

To change the character encoding, press the menu button in the upper right corner and select character encoding.
Screenshot_2015-09-24-18-39-35

There are tons of legacy encodings there so I probably will add some of them in next months.

More information about DroidTerm Pro and its free version
Happy crafting!

DroidTerm 7.1 and DroidTerm PRO 1.2: Usb Serial port terminal for Android

Finally new updates on DroidTerm! I managed to fix the first and foremost bug that was present on previous releases of DroidTerm, the unresponsive scroll when data was received. The text renderer is completely new and it offers and smooth scroll and keeps the app responsive.

After much thought I’ve decided to split DroidTerm into two apps, one free (with ads) that contains the same features, plus the scroll fix, than previous versions and other paid version with no ads and more features.

DroidTerm FREE
DroidTerm PRO

My intention is to keep the Free version stable as it is useful for the common user and add more complex features to the PRO version.
Try first the free sure to be sure it fits your needs, if you need the PRO features or you find DroidTerm useful and you want to help in its further development consider buying the PRO version.

If you prefer you can donate via Paypal tu support further improvements

DroidTerm PRO new features: VT100 Terminal emulator
DroidTerm PRO allows to send a subset of the ANSI control escape sequences. Designing a good interface to support this feature has been more complicated than I thought. Instead of relying purely on the Android keyboard the ‘ESC’ and the ‘[‘ button are check buttons that can be set to ON or OFF, the rest of the command must be written in a field. When the command ready, press the ‘Send’ button.

Screenshot_2015-09-10-22-51-07
ESC[2J escape sequence will erase the screen and move the cursor to home

Some systems echo back whatever you send but in some configurations need local echo. Local echo can be ON/OFF easily by the checkboxes below the the ANSI escape sequences.

DroidTerm Pro new Feature: Different character encodings

DroidTerm features explained in previous posts

USB Viewer
Logs and Hex viewer
Log viewer and Bulk transfer
Connection profiles
Profiles automatically create a default log file. LF CR and LF-CR End of line options added
CH340/CH341 supported, those cheap Arduino clones should be working now πŸ™‚

Both versions use UsbSerial to handle serial port which is free, open source and can boost your projects too!

DroidTerm started as a little serial port terminal, it was buggy as hell in the first release with a very slow scroll and a lack of features but now it is unrecognizable! I started this because other options for serial ports were disappointing and I can state that right now is probably the best out there for Android, probably still not the PuTTy replacement for Android but who knows.. πŸ™‚

Happy crafting!

A dirty and quick example of serial port communication in Android

Since I released UsbSerial I have received good feedback about its performance but I also have received messages with some legit doubts about how to use it. I finally overcame laziness and I have publish a little example of how to use UsbSerial correctly in a real app. Here it is the source code, just two java source code files πŸ™‚

Disclaimer: If you are looking for a serial terminal for Android, DroidTerm is what you need, this is just a quick example

An overall description of how it works:
– UsbService.java contains a Service to isolate all Usb operations. Interesting things happens there. If you need to change baud rate, stop bits and son those lines are located there. It is a good pattern to implement open connections in a Service so I encourage you to do it this way.

– When App starts, UsbService is created and will try to connect with an attached usb device. if there is one device compatible it will connect with it and data will be able to be sent and received. If no devices are attached, it will inform the user through a toast. The app will be still listening for new usb attached devices.

– Data received will appear in the white box, Send button will send the data wrote into the EditText.

Screenshot_2015-01-09-17-52-48

Although pretty simple and it does not have any particular goal (besides being an explanatory app), it could have some bugs so If you find something just let me know opening an issue on github.

Happy coding!

UsbSerial: A serial port driver library for Android v4.5

Although I talked some months ago about this library and I even use it for DroidTerm, DroidTerm PRO and other professional projects, the post I wrote no reflects the truly current state of this work. It is fairly stable and has been used So here it is, a more formal and helpful description of UsbSerial for Android.

A brief list of Apps and wrappers using UsbSerial. Contact with me if you have a nice project to show πŸ™‚

UsbSerial repository

If UsbSerial fits your needs and have help you with your project, please consider donating via PayPal to boost further improvements

If you are relatively new using Android, or just Usb Android api just checkout this simple app using UsbSerial with full source code available on Github

Or you can check out this amazing post about using the USB android API by the guys of BLECentral. The previous steps to use UsbSerial are very well explained there.

Another awesome tutorial by Hariharan Mathavan from All About Circuits

How to add UsbSerial to your project
Thanks to StephaneBg UsbSerial can be easily added to your Android Studio project via Jitpack. First add the jitpack repo into your project build.gradle.

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

And then add the dependency to your module’s build.gradle

compile 'com.github.felHR85:UsbSerial:4.5'

Devices supported
Currently UsbSerial supports three of the most used USB to serial chipsets:
FTDI FT232 (I am not going to brick your device, trust me πŸ™‚)
Silicon Labs CP210x
Prolific PL2303HX (at least HX version)
CH340/CH341
A new feature added here is a CDC generic driver, so it should be possible to connect devices which fits into Communications Device Class. I am open to suggestions about new supported chipsets.

UsbSerial internals: A brief description
– Internally UsbSerial works as a Producer-Consumer handler, Β what you write is put into a buffer and it will be consumed by a Consumer thread when previous data is sent.

– Write operations can be queued from multiple threads without problems

– Received data is received through a callback, there is no need to be polling.

– Two 16kb internal buffers for Write and Read operations.

– Android 4.2.1 Β or greater devices rely on Asynchronous USB api for read operations. Prior versions (Android 3.1 oldest version supported) use synchronous api due to some Android bugs. Write operations use always synchronous USB api. UsbSerial handles all of this so there is no need to worry.

– PL2303, FT232 and CP210x drivers use a list of known vid and pids to identify a correct device.

– CDC driver can be loaded automatically for a device if it has a CDC interface.

How to use it
First of all you need both UsbDevice and UsbDeviceConnection objects correctly initialized.

// This snippet will open the first usb device connected, excluding usb root hubs
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbDevice device;
UsbDeviceConnection connection;
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if(!usbDevices.isEmpty())
{
    boolean keep = true;
    for(Map.Entry<String, UsbDevice> entry : usbDevices.entrySet())
    {
        device = entry.getValue()
        int deviceVID = device.getVendorId()
        int devicePID = device.getProductId()
        if(deviceVID != 0x1d6b || (devicePID != 0x0001 || devicePID != 0x0002 || devicePID != 0x0003))
       {
          // We are supposing here there is only one device connected and it is our serial device
          connection = usbManager.openDevice(device);
          keep = false;
       }else
       {
          connection = null;
          device = null;
       }

       if(!keep)
           break;
    }
}

With those objects correctly initialized it is easy to start


// A callback for received data must be defined
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback()
{
    @Override
    public void onReceivedData(byte[] arg0)
    {
        // Code here
    }
};

//...
//...
UsbSerialDevice serialPort = UsbSerialDevice.createUsbSerialDevice(device, mConnection);
if(serialPort != null)
{
    if(serialPort.open())
    {
        // Devices are opened with default values, Usually 9600,8,1,None,OFF
        // CDC driver default values 115200,8,1,None,OFF
        serialPort.setBaudRate(115200);
        serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
        serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
        serialPort.setParity(UsbSerialInterface.PARITY_NONE);
        serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
        serialPort.read(mCallback);
    }else
    {
        // Serial port could not be opened, maybe an I/O error or it CDC driver was chosen it does not really fit
    }
}else
{
    // No driver for given device, even generic CDC driver could not be loaded
}

And write what you want to send through serial port!

serialPort.write("Hola!".getBytes());

If you need to use flow control signals just check out this post

UsbSerial now allows USB to SPI bridges

Download the jar file here Actually it is better to add UsbSerial using gradle as described above!!

Happy coding and reach me if you do something nice with UsbSerial! πŸ™‚

Update (03/07/15):
Thanks to Martin Blom now it is possible to use UsbSerial with multi-interface devices (like this). The best way would be

int iface = 0;
UsbSerialDevice serialPort = UsbSerialDevice.createUsbSerialDevice(device, mConnection, iface);

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!

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!

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