Skip to content

Instantly share code, notes, and snippets.

@sdabet
Last active January 20, 2016 15:50
Show Gist options
  • Save sdabet/e85762ad3739941586b5 to your computer and use it in GitHub Desktop.
Save sdabet/e85762ad3739941586b5 to your computer and use it in GitHub Desktop.
Implementation of Android command interpreter (usable via telnet for instance).
package com.example.sdabet.test;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
public class CmdService extends Service {
private static final String LOG_TAG = CmdService.class.getSimpleName();
private static final int PORT = 3000;
private final CmdThread cmdThread = new CmdThread(this, PORT);
@Override
public void onCreate() {
Log.d(LOG_TAG, "onCreate()");
cmdThread.start();
}
@Override
public void onDestroy() {
Log.d(LOG_TAG, "onDestroy()");
try {
cmdThread.terminate();
cmdThread.join();
} catch (InterruptedException e) {
Log.e(LOG_TAG, "onDestroy: failed to stop command thread", e);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
package com.example.sdabet.test;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collections;
import java.util.List;
public class CmdThread extends Thread {
private static final String LOG_TAG = CmdThread.class.getSimpleName();
private static final String CMD_EXIT = "exit", CMD_ACTIVITY = "activity";
private final int port;
private ServerSocket server;
private Socket socket;
private final Context context;
public CmdThread(Context context, int port) {
super(LOG_TAG);
this.context = context;
this.port = port;
}
@Override
public void run() {
try {
server = new ServerSocket(port);
Log.d(LOG_TAG, "Server started on " + getIPAddress(true) + ":" + port);
while(!isInterrupted()) {
socket = server.accept();
Log.d(LOG_TAG, "New connection accepted from " + socket.getInetAddress());
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String cmd;
while (!isInterrupted() && (cmd = reader.readLine()) != null) {
Log.d(LOG_TAG, "Received '" + cmd + "'");
String[] args = cmd.split(" ");
if (CMD_EXIT.equals(cmd)) {
writer.println("Goodbye!");
break;
} else if(CMD_ACTIVITY.equals(args[0])) {
if(args.length != 2) {
writer.println("Usage: 'activity <activity_name>'");
}
else {
try {
Class activity = Class.forName(args[1]);
writer.println("Starting activity " + args[1]);
Intent intent = new Intent(context, activity);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (ClassNotFoundException e) {
writer.println("Invalid activity '" + args[1] + "'");
}
}
} else {
writer.println("Unknown command");
}
}
Log.d(LOG_TAG, "Closing current connection...");
socket.close();
Log.d(LOG_TAG, "Current connection closed");
}
Log.d(LOG_TAG, "Stopping server...");
server.close();
Log.d(LOG_TAG, "Server stopped");
} catch (IOException e) {
Log.d(LOG_TAG, "Server terminated");
}
}
public void terminate() {
Log.d(LOG_TAG, "terminate()");
try {
if(socket != null) socket.close();
if(server != null) server.close();
} catch (IOException e) {
Log.e(LOG_TAG, "terminate: error", e);
}
}
/**
* Get IP address from first non-localhost interface
* @param useIPv4 true=return ipv4, false=return ipv6
* @return address or empty string
*/
private static String getIPAddress(boolean useIPv4) {
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface intf : interfaces) {
List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
for (InetAddress addr : addrs) {
if (!addr.isLoopbackAddress()) {
String sAddr = addr.getHostAddress();
//boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
boolean isIPv4 = sAddr.indexOf(':')<0;
if (useIPv4) {
if (isIPv4)
return sAddr;
} else {
if (!isIPv4) {
int delim = sAddr.indexOf('%'); // drop ip6 zone suffix
return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase();
}
}
}
}
}
} catch (Exception ex) { } // for now eat exceptions
return "";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment