Want to send text from your Android phone to your Arduino? Here's how!


  • Android Phone which supports USB Host Mode (i.e OTG Support) - Most devices running Android 3.1+ support this. Check if your phone does using the USB Host Diagnostics App from the Play Store.
  • Arduino - Any version will do. I will be using an Uno R3 . 
  • Arduino USB Cable
  • USB OTG Cable - You will need this to connect the USB cable of the Arduino to the micro-USB port of the Smartphone. It costs about $5 on Amazon.
  • Android Studio - You will need to have this installed and setup. It is pretty easy to do that.  Android Studio makes app development easier with its predictions and code generation. It's one of the best IDEs out there. You could also follow this article to set up Android Studio on your computer.


Main Components of an Android App

There are 3 major files in an Android app:

  • MainActivity.java
    This is where the Java code goes. It controls the way the app will function. 
  • activity_main.xml
    This contains the layout of the app, i.e. the components or the widget-like buttons, TextViews etc.
  • AndroidManifest.xml
    This is where you define when the app must start, which permissions it needs, and which hardware it needs to access.  

There are a host of other files too but they are all linked together with the help of these three. 

An activity can be described as a screen where the user interacts with the phone. Activities contain widgets like buttons, text fields, images, etc., which help in the transfer of information. This tutorial will use one activity, the Main Activity, which will take the user's input to send to the Arduino and also display the received text. 

The Layout


We will be using the same layout for both the USB App and the Bluetooth App. It's a simple one with the minimum required widgets to test the connection between the devices.

As you can see, it has an EditText widget for getting input from the user, buttons to start the connection, transmit the data, end the connection and clear the TextView. The recieved data is displayed in the TextView (the empty part below the buttons).

Here's a part of the XML. Since the code for buttons is similar I've left them out here. Get the complete code at the end of this article.


                    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"




    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">









        android:layout_alignParentStart="true" />



















        android:layout_alignParentBottom="true" />


​I have used a RelativeLayout here, meaning that every widget is arranged with respect to the widgets around it. The layout can be easily recreated using the Design Tab where you can drag-and-drop the widgets wherever you want. When a button is clicked, we will have to describe what needs to happen. For this, an OnClick method is used. Specify the name of the method in the XML of the button. To do this add the line: 


Now hover on this line and an alert will pop up on the left like this:

Click Create 'OnClick...'. This will automatically inject code for the onClick method in MainActivity.java. You will have to do this for each button.

The USB Serial Library

​Setting up a serial connection in Android is quite a hassle because it will require you to manually configure a lot of stuff, so I had been looking at some libraries which do all this automatically. I tested out a few of them and finally settled on the UsbSerial library by Github user felHR85. Among all the relevant libraries I had found, this was the only one which is still being updated. It is pretty easy to set up and use. To add this library to your project, download the latest JAR file from Github. Move it to the 'libs' folder in your project's directory. Then, in the file explorer of Android Studio, right-click the JAR and select "Add as Library". That's it!


The Program Flow

This is the brief outline of how we will proceed. Every activity has a onCreate() method which is the run when the activity is created. Whatever code you want to run at the start must be placed inside it. Do notice that reading from the device is asynchronous, meaning it will keep running in the background. This is done so that the data is received as soon as possible . 

Opening a Connection

First off, let us define the onClick method for the Begin button. When clicked, it should search for all connected devices and then check if the vendor ID of the Arduino matches that of a connected device. If found, permission must be requested from the user. Each USB slave device has a vendor and product ID which can be used to identify what drivers should be used for it. The vendor ID for any Arduino is 0x2341 or 9025.

                    public void onClickStart(View view) {

        HashMap usbDevices = usbManager.getDeviceList();
        if (!usbDevices.isEmpty()) {
            boolean keep = true;
            for (Map.Entry entry : usbDevices.entrySet()) {
                device = entry.getValue();
                int deviceVID = device.getVendorId();
                if (deviceVID == 0x2341)//Arduino Vendor ID
                    PendingIntent pi = PendingIntent.getBroadcast(this, 0, 
                     new Intent(ACTION_USB_PERMISSION), 0);
                    usbManager.requestPermission(device, pi);
                    keep = false;
                } else {
                    connection = null;
                    device = null;

                if (!keep)

​Now let us define the BroadcastReceiver to receive the broadcast to ask for user permission and also to start the connection automatically when a device is connected and to close the connection when it is disconnected. 

                    private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { //Broadcast Receiver to automatically start and stop the Serial connection.
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
                boolean granted = 
                if (granted) {
                    connection = usbManager.openDevice(device);
                    serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
                    if (serialPort != null) {
                        if (serialPort.open()) { //Set Serial Connection Parameters.
                            setUiEnabled(true); //Enable Buttons in UI
                            serialPort.read(mCallback); //
                            tvAppend(textView,"Serial Connection Opened!\n");

                        } else {
                            Log.d("SERIAL", "PORT NOT OPEN");
                    } else {
                        Log.d("SERIAL", "PORT IS NULL");
                } else {
                    Log.d("SERIAL", "PERM NOT GRANTED");
            } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
            } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {

If the first IF condition is satisfied, and if the user has granted permission, initiate a connection for the device whose vendor ID matched our required vendor ID. Also, if a broadcast for a device attach or detach is received, manually call the onClick methods for the Start and Stop buttons. A SerialPort is defined using the device as the connection as the arguments. If this is successful, open the SerialPort and set the parameters accordingly. For an Uno, the default parameters are 8 Data bits, 1 Stop bit, no parity bit and Flow Control is Off. The baud rate can be 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200, but let us go with the standard 9600.  


Receiving Data from the Device

In the code fragment above, notice the line that says serialPort.read(mCallback). Here a reference of a Callback is passed to the read function so that it will automatically trigger when any incoming data is detected. 

                    UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { 
     //Defining a Callback which triggers whenever data is read.
        public void onReceivedData(byte[] arg0) {
            String data = null;
            try {
                data = new String(arg0, "UTF-8");
                tvAppend(textView, data);
            } catch (UnsupportedEncodingException e) {

The data received will be in the form of raw bytes. We will have to re-encode it into a readable format like UTF-8. Then it is appended to the TextView using a custom method named tvAppend(). This is done because any change to the UI can only happen on the UI thread. Since this Callback will be running as a background thread, it can't affect the UI directly. 

 private void tvAppend(TextView tv, CharSequence text) { final TextView ftv = tv; final CharSequence ftext = text; runOnUiThread(new Runnable() { @Override public void run() { ftv.append(ftext); } }); }  

Sending Data to the Device

Sending data is relatively easy when compared to reading data from the device. It is a simple function call with bytes of data which needs to be sent as the argument. This will be defined in the OnClick method of the Send Button.


Closing the Connection

To close the connection, just close the SerialPort.


The Application Manifest

​In the manifest, state what extra permissions the app might require. The only one needed is the permission to make the phone a USB host. Add the following to the manifest:

<uses-feature android:name="android.hardware.usb.host" />

The app can be made to start automatically by adding an IntentFilter to the MainActivity. This IntentFilter will be triggered when any new device is attached. The kind of device can be explicitly specified by providing the vendor ID and/or product ID in an XML file.

                    <?xml version="1.0" encoding="utf-8"?> 
            android:label="@string/app_name" >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />

                android:resource="@xml/device_filter" />

Notice the line "android:resource="@xml/device_filter". This tells the compiler that it can find the device properties in a file named device_filter in src/main/res/xml, so make a folder named "xml" in src/main/res and put the following in it:


    <usb-device vendor-id="9025" />
    <!-- Vendor ID of Arduino -->

Testing the App

Build and run the app on your smartphone. Now fire up the Arduino IDE and set up the Arduino to simply echo whatever it receives on the serial port. Here's a very simple code to do that.


                    void setup()  
 void loop()  
  char c;
   c = Serial.read();  

​Now connect the Arduino to the microUSB port using the OTG Cable. The app must auto-start. Try sending some text and the same data will be echoed back!



This article has helped to show how an Arduino can talk to your smartphone. The uses for this are endless! In case data from any sensor is needed and if that isn't available on board a smartphone, any microcontroller can be used to read from that sensor and transmit the data to the phone. The next part of the article will show how to connect using the popular Bluetooth HC05 Module.

Next Article in the Series: Control an Arduino with Bluetooth


  Download Code  



  • gianpiero gaeta 2015-11-19

    How can I change the code to manipulate and use data data received from arduino on my phone?

  • Dmitry Bershadsky 2015-11-29

    Thanks for the information!

    I’m trying to run this code and am having an issue.  I’m using a Samsung S3 with Android 4.0.4 connected via OTG to an Arduino Duemilanove.  When I run the app, it reads the Arduino as 1027 instead of 9025.  So, I added the following to device_filter.xml:

    <usb-device vendor-id=“1027” >

    Now, the app opens when I plug in the Arduino.  I’m not sure if this is the source of the main issue below…

    When I attempt to open the serial line, the app crashes and I get the following error in Arduino Studio.  Any idea what it means?  Thanks!

    Errors: https://gist.github.com/anonymous/af2d2ec9cf0e4cf9b67b

    • aymenj 2016-04-18

      i have exactly the same problem

    • Jace J McPherson 2016-05-07

      So you need to “Unregister” the receiver we added in the “onCreate” method because of how Android deals with that sort of thing. I won’t get into it, but basically you need to add the following method to your code:

      protected void onDestroy() {

      This makes sure that when your activity gets destroyed, the receiver gets removed, which is what Android requires you to do (without causing errors)

  • seanwlk 2016-01-25

    i rly don tundestand what to open with andorid studio… tellls me error every folder i try… that is not the exported project to edit

  • Dnk savaliya 2016-01-25

    Do we need to connect the arduino to a separate power supply??
    I have installed .ino in Arduino & .apk in mobile.

  • allenbt 2016-02-22

    I don’t have an android phone but am considering buying a cheap Android tablet - will that work as well?

  • Frank Herbert 2016-03-06

    Thank you, Hariharan, this is an outstanding tutorial!  I need to read some switch inputs and use them in an Android app. I’ve fiddled with Arduino, but never with building an Android app.  I got through with no major troubles, and it’s working perfectly.

  • Serj BGV 2016-03-07

    can you help me with your program - i not very familiar with android. I need to write ansvers from arduino to file and i done that but with troubles - i want to write each new answer to new line in text file. But if use append function its add all previous text, but when i work with String data it’s save something strange and how to convert that to normal text? As i anderstand its must converting automatically here: “data = new String(arg0, “UTF-8”);” Or not?

  • 19brian16 2016-03-20

    I can’t open the project, it still in a window that says “building gradle project” and do nothing, can you help me?

  • murat9700 2016-03-29

    I have a question about serialPort.write. What if it fails? How do we know? There is no error message for it.

  • kyvacipes 2016-03-31

    Vendor ID 5401 worked for me.

  • Aankur 2016-04-01

    I have been able to do a serial transfer of file byte by byte from HC-05 to my mobile phone using
    arduino. But it is a slow process. Is it possible to transfer a block of data (say 100-200 bytes) at once from arduino BLE to mobile phone to increase the transfer rate?
    Let me know if you have any other suggestion to increase the data transfer rate.

    One more question : is it possible to transfer the video or audio from memory card to phone or computer

  • Brian Fu 2016-04-28

    I’m relatively new to Android and am slightly confused about adding the JAR file to the library. I clicked the github link and downloaded the entire repository, and I found a JAR file under gradle >> wrapper >> gradle-wrapper.JAR. Do I simply copy and paste that into the libraries folder?

    • Jace J McPherson 2016-05-07

      You shouldn’t have to do anything with JAR files. If you look at the instructions for installation on the GitHub page, it tells you exactly what to do to install without having to mess with JARs. Specifically, he mentions opening the “build.gradle (Module: app)” file, and adding the following lines of code:

      repositories {
      maven {url "https://jitpack.io" }

      Then, under dependencies:
      dependencies {


      compile 'com.github.felHR85:UsbSerial:4.3"

  • Mohammad Aljammali 2016-05-08

    i changed the vendor ID and the app start but when i push the begin button nothing happens and the send and stop button are gray

    • mulMillen 2016-06-20

      I get the exact same problem. has anyone found a solution?

  • Hamulus 2016-05-11

    When I am trying to click on “Begin”, I get app crash. I see:

    05-11 22:34:12.283 25875-25970/com.hariharan.arduinousb E/AndroidRuntime: FATAL EXCEPTION: Thread-441
                                                        at android.hardware.usb.UsbDeviceConnection.bulkTransfer(UsbDeviceConnection.java:140)
                                                        at com.felhr.usbserial.UsbSerialDevice$ReadThread.run

    What may it be?

  • Pavel Palei 2016-05-13

    I want on onRecive method to use Double instead of string, how can i do this?

    • Pavel Palei 2016-05-13

      all work, but something with the encoding , i send hello and recive ,he"ll,o, why?

  • Bansheemanson 2016-05-17

    Hello everybody,
    I’m trying to test this code on my phone, a Galaxy Pocket Neo on android 4.1.2 with an arduino uno. I’ve got the following issue: the app doesn’t recognize my arduino. It doesn’t found any device connected to the phone. I found that the vendor id is “2341” for the arduino so I doesn’t know what to do to make the app works.
    Can someone help me ?

    • mulMillen 2016-06-20

      in the mainactivity, within the onCreate method make sure this line is included
      if (deviceVID == 0x2341)//Arduino Vendor ID
      Also make a folder \app\src\main\res\xml
      and within this place the device_filter.xml file
      make sure it contains the line
        <usb-device vendor-id=“0x2341” >

  • racarrasco 2016-06-07

    This is a great thread! The possibilities here are endless!..Sadly I can’t get this to work. So I have an arduino uno and When I connect the device, the app does not auto-start and when I try to press the begin button nothing really happens.The app is able to run fine, but there is only one error that comes up when running from android studio and it is:
    ” E/Typeface: SANS_LOC file not found”

    But that shouldn’t be stopping it from working right?Any help would be greatly appreciated.

    • racarrasco 2016-06-07

      also, where do we find the vendor id?

      • mulMillen 2016-06-20

        Try connecting your arduino to a linux system (e.g. a PC with ubuntu or Debian) and at terminal write
        lsusb -v
        This should display the arduinos vendor id

  • Aditya Agarwal 2016-06-22

    Your Arduino vendor ID might be different. Use this app to find out what it is - https://play.google.com/store/apps/details?id=com.keuwl.usbhost

  • Siddharth Gharge 2016-06-23

    Couldn’t find the jar file on that link. How to download jar file

  • Dipin Kumar 2016-07-01

    I am trying to communicate (send) data from Android phone to PC (Hyper terminal or putty).
    I have edited the Vendor ID to 0x045e Microsoft Corp. or 0x1d6b Linux Foundation, however i am still not able to see any data showing up on the PC side.

    Please let me know your views on the same

  • Aufa Husen 2016-07-08

    Hi, i have a problem to send the arduino response to the Log.d(). it seems as if the data that i got from the arduino turns into many chunks….while it appears normally in the text view

  • lamiri ahmed 2016-07-09

    I opened the project and run it with no errors but when I execute the app on my ODROID XU4 which is connected to my arduino(ODROID SHOW), and trying to write some thing on it, I get this message error:
    W/BroadcastQueue: Skipping deliver [background] BroadcastRecord{41fdd680 u0 com.hariharan.arduinousb.USB_PERMISSION} to ReceiverList{41f50b20 20334 com.hariharan.arduinousb/10062/u0 remote:41bb02a8}: process crashing
    WindowManager: Starting window AppWindowToken{420035b8 token=Token{41ca1740 ActivityRecord{41c33ff0 u0 com.hariharan.arduinousb/.MainActivity t30}}} timed out
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hariharan.arduinousb/com.hariharan.arduinousb.MainActivity}: java.lang.NullPointerException
    when I run lsusb -v I get : Bus 002 Device 004: ID 10c4:ea60
    and when I check the vendor ID in java code I found it : 4292 !! ( UsbDevice[mName=/dev/bus/usb/002/004,mVendorId=4292,mProductId=60000,mClass=0,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.os.Parcelable;@419ca658 ) !
    please can anyone help me I need it soon :/

  • Hi,

    I am using this program to get received data seperated into different textViews. I am using
    try {
              data = new String(arg0, “UTF-8”);
              //  tvAppend(textView, data);
              String[] separated = data.split(”,”);

    So that my data gets splitted when “,” is received and can be displayed in two different textviews. But somehows it crashes the app when I start receiving data. Can you help me if I am missing something ?

  • Regno 2016-08-08

    Is it possible to connect my phone with this app to a Windows or Linux pc and then read out the data? If so, how would one do that?

  • ghosty 2016-08-29

    I changed arduino vendor ID, mine is 10755 instead 9025.
    I modified device_filter.xml and also the code (if (deviceVID == 0x2A03)...)
    everything is Ok until I press on button begin, crashing android application:
    FATAL EXCEPTION: Thread-363 java.lang.NullPointerException at android.hardware.usb.UsbDeviceConnection.bulkTransfer(UsbDeviceConnection.java:140)
                                                      at com.felhr.usbserial.UsbSerialDevice$ReadThread.run
    Any idea of what can be wrong ??
    Thanks by advance

    • It’s working for me for both device IDs. You still having the issue ? It can be something else not the Id problem.

  • i am communicating with a device which give a bmp file as a output. how could i manage that?

  • Brad Harbert 2016-10-11

    FANTASTIC - Awesome work and worked like a charm.  Appreciate you sharing your knowledge!