Last active
January 20, 2016 15:50
-
-
Save sdabet/e85762ad3739941586b5 to your computer and use it in GitHub Desktop.
Implementation of Android command interpreter (usable via telnet for instance).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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