2

To make development easier, I want to be able to send textual commands to my android app (especially prior to having prior the UI completely fleshed out). Presumably in the emulator, but it would be great if it also worked on a device connected via USB. Of course, I could add an editText control to my app and type the commands in there, but would prefer not have deal with debug things cluttering up the UI and all the complications of that. I also would like to be able to paste text from computer clipboard, which sorta rules out EditText controls.

Is there any way to do this, say via any of the android-sdk/tools/ stuff? I would implement the command processor java class/method, but need some way to be able to actually feed it a string. I suppose I could do something that talks to the emulator via the file system or something, but would prefer not have to spend a lot of time doing this if there is something already available.

rob
  • 9,933
  • 7
  • 42
  • 73

2 Answers2

3

If it were me I'd just have the application listen on an unprivileged TCP port for connections from telnet or netcat (nc) run on the host passed into the emulator by setting up an adb port forward, or run nc from within the emulator under the adb shell. But I say that as someone who spent a few years building test equipment with TCP remote control channels.

Actually, if you want to use nc from the adb shell, you could use a unix domain socket instead of tcp, which may simplify some of the pesky reconnect issues with TCP.

(NickT's SMS idea is an interesting one, not sure which would prove better)

Chris Stratton
  • 39,853
  • 6
  • 84
  • 117
  • I'm interested in this solution. My answer, whilst it works OK, is a bit like using a hammer to knock in a screw. I've always let Eclipse look after the ADB and treated it as a black box. If the debugger was running could I just use the 'adb forward' command in a shell and expect it to affect the running debug session or is there a way to set this adb forwarding through the debug launch configuration in Eclipse? – NickT Nov 22 '10 at 12:30
  • an adb forward isn't really part of the 'debugger'. Instead what it does is set up a port forward so a tcp or whatever connection to the development machine on a specific port goes instead into the emulator on a specific port. You can have a tcp server listening there. As for which answer is better, it may be that writing a uniquely android sms receiver is easier than writing a generic tcp server. – Chris Stratton Nov 22 '10 at 16:43
  • Thanks Chris, I used Nick's solution mostly because I could just paste it in and it worked (feeling lazy this morning :) ) but I may revisit this and try your way as well. – rob Nov 22 '10 at 17:00
  • Chris, I managed to get your solution going. I can see definite advantages to this in a multi thread app, as you could have a listener on each thread. With a better telnet client than the Windows version, it would be more useful. – NickT Nov 22 '10 at 17:07
  • Nick I'd love to see what you did to make this work. When I get a chance I'd like to make it run as a bare-bones http server, so I could talk to it via little ajax command-sender thing (which would have the additional benefit of being able to get a response) – rob Nov 22 '10 at 17:58
2

One way of feeding a string to the emulator would be to implement a BroadcastReceiver for SMS messages. Then from a DOS box you could 'telnet localhost 5554' (or whatever number your emulator starts up as) Then you can use the emulator command sms send 1234 yourString. (1234 is just a dummy for the 'sending' phone number.

You would have to parse the string inside the receiver to make it alter different class member variables etc or whatever.

It's a pretty clunky method but it wouldn't impact your UI and it would only need a dozen or so lines of code for the receiver.

I just stuck this bit of code into onCreate and set a breakpoint to test the principle

   rcvIncoming = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
          String message = "";
          Bundle data = intent.getExtras();
          if (data != null) {
              Object pdus[] = (Object[]) data.get("pdus");
              String sender = null;
              for (Object pdu : pdus) {
                 SmsMessage part = SmsMessage.createFromPdu((byte[]) pdu);
                 message += part.getDisplayMessageBody();
                 if (sender == null) {
                 sender = part.getDisplayOriginatingAddress();
              }
           }
         }
         String test = message;// breakpoint here to test
      }
   };
   registerReceiver(rcvIncoming, new IntentFilter(
                "android.provider.Telephony.SMS_RECEIVED"));

you'll need this in the manifest too:

  <uses-permission android:name="android.permission.RECEIVE_SMS" /> 

.

NickT
  • 23,844
  • 11
  • 78
  • 121
  • Interesting idea. Never done BroadcastReceivers, I assume it is pretty straightforward (I'm looking at this as an example: http://stackoverflow.com/questions/1944102/android-sms-receiver-not-working ) – rob Nov 22 '10 at 03:33
  • Not too difficult to do. I edited the original to show the code basics – NickT Nov 22 '10 at 09:21