Saturday, April 9, 2016

Call custom methods on Android app using a real device

Android developers have the benefit of testing on a device emulator which provides just about anything you need when developing. However, when QA is testing your Android app on a real device, they may need to override or customize certain functionality in order to test certain features. In this post I'm going to show you how you can create a way to call methods in your Android apps using the Android Debug Bridge(adb).

The problem

 Obviously you want your QA guys to test the real app as much as possible without having to mock up anything. Sometimes this is not possible and you need to dummy up some data or mock something to imitate the real world environment. For my specific use case I had an app that had to verify the phone number of the device. To do this we had to send a verification code via sms to the device and I have a custom SMS BroadcastReceiver that would intercept it and send the message back to the server to verify the device. Our QA device doesn't have a sim card so the device used for testing couldn't receive incoming texts. There was also one other use case that I'll mention later.

 After searching the internet long and hard I couldn't find anywhere that showed how to send a fake sms to a real device. There are several options for sending to an emulator but not for a real device. There are several apps that do fake SMS messaging but they somehow bypass the normal SMS functioning. I tried several but my SMS handling code never got invoked. So I had to figure out another way to get the device registered so that QA could test the app.

As a side note, our app did not allow the user to input the code. The app intercepted the SMS message and did it for them. If the app allowed the user to input the code, this would not have been an issue. Even so, this is still a useful method so don't get caught up in my use case details.


What is a BroadcastReceiver?

A BroadcastReceiver is a component that allows you to receive system events and events you want your app to fire. There's a good blog post about that here if you want to read more.

 For our app I developed an SMSBroadcastReceiver that registered to listen for all SMS messages and basically did the following:
  1. Parse out the registration code from the SmsMessage
  2. Send the code to our server for verification
  3. Save a boolean in user preferences indicating verification was successful
  4. Broadcast to the RegistrationActivity that registration was successful so the screen would refresh and allow the user to have access to the app

The solution

So I thought I could tackle this problem another way. I would create a "back door". I know, this sounds horrible from a security perspective but for this case it seemed pretty harmless and the user of the back door would have to have the verification code and a lot of knowledge about our app to use it. Also you can protect it with a hard coded username/password that will get obfuscated with progaurd if you wish.

 The Android Debug Bridge(adb) tool allows you to broadcast intents and send key-value pairs along with it. So all you have to do is register a QABroadcastReceiver to listen for custom intents. This BroadcastReceiver can pick out any data that you send to it via adb. Bam! We have a solution. I created one that allowed special commands to be sent that it would recognize. So if I broadcast a com.mycompany.android.SMS_CODE intent, and put a code=123 string in the intent, then the BroadcastReceiver would do everything the regular SMSBroadcastReceiver did without having to send the SMS.

Let's take a look at some code so you can see this in action!

Create the QABroadcastReceiver class

This class is simply going to show a Toast message that we send to it to prove that our method works.


Registering in the AndroidManifest.xml file

You can name the intent filter whatever you would like. In fact you can create multiple intent filters and use them like command names in your BroadcastReceiver. Or you can just use one intent filter and embed the commands as key-value pairs. It's really up to you.



That's all of the android code that we'll have to write. The rest is getting adb to broadcast a message that our BroadcastReceiver will...you guessed it, RECEIVE!

Setting up adb to broadcast messages to your app

If you have the Android sdk installed then the adb.exe is located in the sdk/platform-tools folder. You can download adb by itself but I haven't tested that download so try at your own risk. On windows I would recommend creating an environment variable for %ANDROID_HOME% pointing to your Android sdk location and editing the path variable to include %ANDROID_HOME%/platform-tools. That way you should be able to pull up a command line and type "adb" without the quotes and see that it starts the adb command line tool.

The adb command to invoke our BroadcastReceiver and log the message "Hello" is the following:

adb shell am broadcast -a com.mycompany.android.intent.QA_MESSAGE --es message Hello

Now that you have hooked in to your app on a real device you can pretty much invoke whatever you would like. You just have to create the custom functionality in your QABroadcastReceiver.

Other use cases

You can do lots with this. Another use case was that we had an auto-refresh on one screen, where if the last refresh time was more than 1 hour ago, we would auto refresh the data. For QA this is a pain! So I added functionality to set this to x seconds so that QA could set it to whatever they liked and not have to wait a whole hour to test.

A word of warning

Don't go too far with this though. You don't want your app that QA uses to be very different in functionality from production. Use this as a last resort and evaluate the risk of missing a potential bug by using this. Also depending on the nature of your app this may be too risky from a security standpoint so just use common sense.

Summary

So in this post we created a custom BroadcastReceiver to do our bidding on a real device! Once you have this in place you can can build custom functions to override pretty much anything in your app. I hope this helps someone in the future. Please leave comments and let me know what you think.

Thanks for reading!

9 comments:

  1. Thankyou for this wondrous post, I am happy I watched this site on yippee.
    Android App Development

    ReplyDelete
  2. Certainly helped) Thanks for the help. Something equally important to make an SMS dispatch is very convenient, for everyone.There is brilliant an opportunity to collect statistics and evaluate the performance of the database! You may read the full info here. Keep it, for a detailed list of services.

    ReplyDelete
  3. Android is a Linux based mobile OS that is known for being an open source platform. This allows more freedom not only for the front-end users but with the development process as well.gerald winata gozali

    ReplyDelete
  4. This comment has been removed by a blog administrator.

    ReplyDelete
  5. This article provided me with a wealth of information about app development company in usa. The article is both educational and helpful. Thank you for providing this information. Keep up the good work. 

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete

Note: Only a member of this blog may post a comment.