Control Remoto Movil Android (adb)
Aqui dejo un flujo muy chulo para node red.
permite controlar via web un movil android.
En el ejemplo se controla un movil conectado a una Raspberry-Pi
La raspberry-pi hace de servidor IOT y el movil le proporciona la conexion a internet.
(necesita tener instalado node-red y adb)
Enlaces
Pagina del proyecto y el codigo.
https://github.com/EM50L/Remote_Control_Android_Phone
Tambien esta publicado en la pagina oficial de node-red
https://flows.nodered.org/flow/7f35f7f413c7d4abd983e4ede0100ec7



Demo (No operativa)
Codigo Copiar y pegar en node-red
[
{
"id": "605c785.6d37088",
"type": "exec",
"z": "61414f15.486f38",
"command": "adb -d shell -n \"rm /sdcard/screen.png ; screencap -p /sdcard/screen.png\" ; adb -d pull /sdcard/screen.png ; stat screen.png",
"addpay": false,
"append": "",
"useSpawn": "false",
"timer": "10",
"oldrc": false,
"name": "Cap.",
"x": 165,
"y": 265,
"wires": [
[
"2567accc.f459b4"
],
[],
[]
]
},
{
"id": "7a8a090d.65ece8",
"type": "http in",
"z": "61414f15.486f38",
"name": "/movil2",
"url": "/movil2",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 55,
"y": 55,
"wires": [
[
"84b4ccc3.cb12f8",
"d3e068b.e898818"
]
]
},
{
"id": "d3e068b.e898818",
"type": "template",
"z": "61414f15.486f38",
"name": "html",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "<!DOCTYPE html>\n<html lang=\"es\">\n<head><!--url: {{req.url}} host: {{req.headers.host}} -->\n<meta charset=\"utf-8\">\n<meta name=\"description\" content=\"Jejo Control Movil con node-red\">\n<meta name=\"author\" content=\"Jejo(Em50L)\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link rel=\"stylesheet\" href=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\">\n</head>\n<body onload=\"setTimeout(function(){ \ndocument.getElementById('screen').src='scr.png?'+new Date().getTime();\n},1000);\">\n\n<div class=\"row justify-content-md-center\">\n<div class=\"col-sm-7\" style=\"min-width: 400px;\">\n<div class=\"panel panel-default\">\n<div class=\"panel-heading\"><h3 class=\"panel-title\">Control Movil <small>(Via Adb)</small></h3></div>\n\n\n<a class=\"btn btn-xs btn-warning\" href=\"?\" data-toggle=\"tooltip\" title=\"Si no refesca pulsa power o menu y luego Enter\">\n<span class=\"glyphicon glyphicon-refresh\"></span><small>{{flow.hora}}</small></a>\n\n<a class=\"btn btn-xs btn-primary\" href=\"?key=KEYCODE_POWER\"><span class=\"glyphicon glyphicon glyphicon-off\"></span></a>\n<a class=\"btn btn-xs btn-info\" href=\"?key=KEYCODE_WAKEUP\"><span class=\"glyphicon glyphicon-flash\"></span></a>\n<a class=\"btn btn-xs btn-primary\" href=\"?key=KEYCODE_DPAD_UP\"><span class=\"glyphicon glyphicon-arrow-up\"></span></a>\n<a class=\"btn btn-xs btn-primary\" href=\"?key=KEYCODE_DPAD_DOWN\"><span class=\"glyphicon glyphicon-arrow-down\"></span></a>\n<a class=\"btn btn-xs btn-primary\" href=\"?key=KEYCODE_DPAD_LEFT\"><span class=\"glyphicon glyphicon-arrow-left\"></span></a>\n<a class=\"btn btn-xs btn-primary\" href=\"?key=KEYCODE_DPAD_RIGHT\"><span class=\"glyphicon glyphicon-arrow-right\"></span></a>\n<a class=\"btn btn-xs btn-primary\" href=\"?key=KEYCODE_APP_SWITCH\"><span class=\"glyphicon glyphicon-retweet\"></span></a>\n<a class=\"btn btn-xs btn-success\" href=\"?key=KEYCODE_MENU\"><span class=\"glyphicon glyphicon-menu-hamburger\">Menu</a>\n<a class=\"btn btn-xs btn-success\" href=\"?key=KEYCODE_HOME\"><span class=\"glyphicon glyphicon-home\">Home</a>\n<br>\n<a class=\"btn btn-xs btn-default\" href=\"?key=KEYCODE_ENTER\">Enter</a>\n<a class=\"btn btn-xs btn-default\" href=\"?key=KEYCODE_ESCAPE\">Esc</a>\n<a class=\"btn btn-xs btn-default\" href=\"?key=KEYCODE_TAB\"><span class=\"glyphicon glyphicon-arrow-right\">Tab</a>\n<a class=\"btn btn-xs btn-default\" href=\"?key=KEYCODE_BACK\"><span class=\"glyphicon glyphicon-option-horizontal\">Atras</a>\n<a class=\"btn btn-xs btn-danger\" href=\"movil2?cmd=com.android.settings/.Settings\"><span class=\"glyphicon glyphicon-cog\">Sett.</a>\n<a class=\"btn btn-xs btn-danger\" href=\"movil2?cmd=com.android.settings/.TetherSettings\"><span class=\"glyphicon glyphicon-cog\">Tether</a>\n<a class=\"btn btn-xs btn-danger\" href=\"movil2?cmd=android.media.action.IMAGE_CAPTURE\"><span class=\"glyphicon glyphicon-camera\"></a>\n<a class=\"btn btn-xs btn-danger\" href=\"movil2?cmd=com.android.settings/.RadioInfo\"><span class=\"glyphicon glyphicon-signal\"></a>\n\n<script type=\"text/javascript\">\nfunction touch(event){//540 x 980???\n var x=event.offsetX;var y=event.offsetY;\n window.location.href=window.location.pathname+\"?touch&x=\"+x+\"&y=\"+y;\n}\n</script>\n\n<br><img id=\"screen\" src=\"\" onclick=\"touch(event);\" style=\"width:540px height:980px\"> \n\n</div><!--/panel-->\n</div><!--/col-sm-4-->\n</div><!--/row-->\n\n<!-- Bootstrap core JavaScript ================================ -->\n<!-- Placed at the end of the document so the pages load faster -->\n<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script> \n<script>window.jQuery || document.write('<script src=\"/jquery.min.js\"><\\/script>')</script>\n<script src=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\"></script>\n\n</body>\n</html>",
"output": "str",
"x": 204,
"y": 56,
"wires": [
[
"51f67a8b.5c6a14"
]
]
},
{
"id": "a6ab064c.66ea28",
"type": "http response",
"z": "61414f15.486f38",
"name": "",
"statusCode": "",
"headers": {
"content-type": "image/png",
"Cache-Control": "no-cache"
},
"x": 405,
"y": 255,
"wires": []
},
{
"id": "6f705ea9.3b2178",
"type": "comment",
"z": "61414f15.486f38",
"name": "Gestion Movil via ADB (V2)",
"info": "https://gist.github.com/Pulimet/5013acf2cd5b28e55036c82c91bd56d8\n\nhttps://www.growingwiththeweb.com/2014/01/handy-adb-commands-for-android.html\nhttps://developer.android.com/studio/command-line/adb\nhttp://android.magicer.xyz/tools/help/shell.html\nhttps://developer.android.com/reference/android/view/KeyEvent\n\nDesbloquear pantalla\nhttps://stackoverflow.com/questions/29072501/how-to-unlock-android-phone-through-adb\nadb shell input keyevent 82 && adb shell input keyevent 66\n\nCapturar pantalla\nhttps://stackoverflow.com/questions/27766712/using-adb-to-capture-the-screen\n\nhttps://github.com/mattwilson1024/android-pattern-unlock/blob/master/unlock.sh\n\nPara capturar eventos\nhttps://www.softteco.com/blog/android-writing-events-low-level-touch-screen-automated-shell-test-part-1/\n\ncaptura pantalla\nadb shell \"input keyevent 82 ; input swipe 80 880 80 380 ; screencap -p /sdcard/screencap.png\" ; adb pull /sdcard/screencap.png ; convert screencap.png -quality 70 -resize 50% screencap.jpg\n\nBoton home????\nadb shell -n am start -a android.intent.action.MAIN -c android.intent.category.HOME\n\n\n¿otra forma de enviar eventos?\nhttps://www.softteco.com/blog/android-decoding-click-low-level-event/\n\nlanzar aplicaciones\nhttps://medium.com/@xabaras/starting-an-activity-via-adb-47119bdf514f\nadb shell am start -a <signin_intent_action> -n <signin_component> -f <signin_intent_flags> -d <content_uri>\n\n\n0 KEYCODE_UNKNOWN\n1 KEYCODE_MENU\n2 KEYCODE_SOFT_RIGHT\n3 KEYCODE_HOME\n4 KEYCODE_BACK\n5 KEYCODE_CALL\n6 KEYCODE_ENDCALL\n7 KEYCODE_0\n8 KEYCODE_1\n9 KEYCODE_2\n10 KEYCODE_3\n11 KEYCODE_4\n12 KEYCODE_5\n13 KEYCODE_6\n14 KEYCODE_7\n15 KEYCODE_8\n16 KEYCODE_9\n17 KEYCODE_STAR\n18 KEYCODE_POUND\n19 KEYCODE_DPAD_UP\n20 KEYCODE_DPAD_DOWN\n21 KEYCODE_DPAD_LEFT\n22 KEYCODE_DPAD_RIGHT\n23 KEYCODE_DPAD_CENTER\n24 KEYCODE_VOLUME_UP\n25 KEYCODE_VOLUME_DOWN\n26 KEYCODE_POWER\n27 KEYCODE_CAMERA\n28 KEYCODE_CLEAR\n29 KEYCODE_A\n30 KEYCODE_B\n31 KEYCODE_C\n32 KEYCODE_D\n33 KEYCODE_E\n34 KEYCODE_F\n35 KEYCODE_G\n36 KEYCODE_H\n37 KEYCODE_I\n38 KEYCODE_J\n39 KEYCODE_K\n40 KEYCODE_L\n41 KEYCODE_M\n42 KEYCODE_N\n43 KEYCODE_O\n44 KEYCODE_P\n45 KEYCODE_Q\n46 KEYCODE_R\n47 KEYCODE_S\n48 KEYCODE_T\n49 KEYCODE_U\n50 KEYCODE_V\n51 KEYCODE_W\n52 KEYCODE_X\n53 KEYCODE_Y\n54 KEYCODE_Z\n55 KEYCODE_COMMA\n56 KEYCODE_PERIOD\n57 KEYCODE_ALT_LEFT\n58 KEYCODE_ALT_RIGHT\n59 KEYCODE_SHIFT_LEFT\n60 KEYCODE_SHIFT_RIGHT\n61 KEYCODE_TAB\n62 KEYCODE_SPACE\n63 KEYCODE_SYM\n64 KEYCODE_EXPLORER\n65 KEYCODE_ENVELOPE\n66 KEYCODE_ENTER\n67 KEYCODE_DEL\n68 KEYCODE_GRAVE\n69 KEYCODE_MINUS\n70 KEYCODE_EQUALS\n71 KEYCODE_LEFT_BRACKET\n72 KEYCODE_RIGHT_BRACKET\n73 KEYCODE_BACKSLASH\n74 KEYCODE_SEMICOLON\n75 KEYCODE_APOSTROPHE\n76 KEYCODE_SLASH\n77 KEYCODE_AT\n78 KEYCODE_NUM\n79 KEYCODE_HEADSETHOOK\n80 KEYCODE_FOCUS\n81 KEYCODE_PLUS\n82 KEYCODE_MENU\n83 KEYCODE_NOTIFICATION\n84 KEYCODE_SEARCH\n85 TAG_LAST_KEYCODE\n\n\nandroid adb commands Nibiru Launcher Override \n*some of these work with root access only\n\n// shop device ip address\nadb shell ip addr show\n// or \nadb shell ip addr show wlan0\n\n// take screenshot and save file to users folder (on pc, C:\\Users\\username)\n$ adb shell \"screencap -p\" | sed 's/\\r$//' > screen.png\n// https://stackpointer.io/mobile/android-screen-capture-using-adb/525/\n\n// send key commands\nhttps://stackoverflow.com/questions/7789826/adb-shell-input-events\n\nview logcat\n> adb logcat\nlogcat with only lines with these words\n> adb logcat -s Unity ActivityManager PackageManager dalvikvm DEBUG\n\nget list of activities (look for launcher see, android.intent.category.HOME)\n> adb shell dumpsys activity\n\nopen wifi settings menu from commandline\n> adb shell am start -a android.intent.action.MAIN -n com.android.settings/.Settings\n\nenable/disable wifi from adb\n> adb shell svc wifi enable\n\nreboot from commandline\n> adb reboot\n\nremove default launcher from nibiru vr phone\n> adb shell\n> pm block com.nibiru.launcher3d\n\nre-enable\n> adb shell\n> pm unblock com.nibiru.launcher3d\n\nrun app from adb shell (1 is main activity)\n> monkey -p com.package.name 1\n\nmodify net config (to connect automatically into certain ssid)\n> adb pull /data/misc/wifi/wpa_supplicant.conf\nedit conf\n> adb push wpa_supplicant.conf /data/misc/wifi/wpa_supplicant.conf\n\n\nProblems\n- Phone starts and stuck in startup image: Do you have any launcher apps?\n- Cannot start wifi (after editing config file) : set owner and permissions to conf file:\n> adb shell chown system.wifi /data/misc/wifi/wpa_supplicant.conf\n> adb shell chmod 660 /data/misc/wifi/wpa_supplicant.conf\n- \"Error: java.lang.SecurityException: Permission Denial: attempt to change component state\": run as root> adb root",
"x": 125,
"y": 20,
"wires": []
},
{
"id": "bf565703.fd97b",
"type": "exec",
"z": "61414f15.486f38",
"command": "adb -d shell -n input keyevent ",
"addpay": true,
"append": "",
"useSpawn": "false",
"timer": "9",
"oldrc": false,
"name": "key",
"x": 205,
"y": 96,
"wires": [
[
"21c05eb2.84bdca"
],
[
"21c05eb2.84bdca"
],
[]
]
},
{
"id": "84b4ccc3.cb12f8",
"type": "function",
"z": "61414f15.486f38",
"name": "cmd?",
"func": "var now = new Date();\nvar hour = now.getHours();\nvar min = now.getMinutes();if(min<10)min='0'+min;\nvar sec = now.getSeconds();if(sec<10)sec='0'+sec;\nflow.set('hora',hour+\":\"+min+\":\"+sec);\n\nif (msg.req.query.key != null) {\n msg.payload=msg.req.query.key;\n return [ msg, null ,null ,null];\n} else if (msg.req.query.cmd != null){\n msg.payload=msg.req.query.cmd;\n return [ null, msg,null,null];\n} else if (msg.req.query.touch != null){\n msg.payload=msg.req.query.cmd;\n return [ null, null,msg,null];\n} else {\n return [ null,null ,null, msg];\n}",
"outputs": 4,
"noerr": 0,
"x": 85,
"y": 150,
"wires": [
[
"bf565703.fd97b"
],
[
"2a78e60b.2ae14a"
],
[
"6a0963d5.dd679c"
],
[]
]
},
{
"id": "2a78e60b.2ae14a",
"type": "exec",
"z": "61414f15.486f38",
"command": "adb -d shell -n am start ",
"addpay": true,
"append": "",
"useSpawn": "false",
"timer": "9",
"oldrc": false,
"name": "cmd",
"x": 205,
"y": 144,
"wires": [
[
"21c05eb2.84bdca"
],
[
"21c05eb2.84bdca"
],
[]
]
},
{
"id": "c54b836c.fdb",
"type": "http in",
"z": "61414f15.486f38",
"name": "scr.png",
"url": "/movil2/scr.png",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 55,
"y": 265,
"wires": [
[
"605c785.6d37088"
]
]
},
{
"id": "2567accc.f459b4",
"type": "file in",
"z": "61414f15.486f38",
"name": "file",
"filename": "screen.png",
"format": "",
"chunk": false,
"sendError": false,
"x": 285,
"y": 255,
"wires": [
[
"a6ab064c.66ea28"
]
]
},
{
"id": "51f67a8b.5c6a14",
"type": "http response",
"z": "61414f15.486f38",
"name": "",
"statusCode": "",
"headers": {},
"x": 405,
"y": 55,
"wires": []
},
{
"id": "412dbcbc.e8c3d4",
"type": "exec",
"z": "61414f15.486f38",
"command": "adb -d shell input tap ",
"addpay": true,
"append": "",
"useSpawn": "false",
"timer": "9",
"oldrc": false,
"name": "touch",
"x": 355,
"y": 200,
"wires": [
[
"21c05eb2.84bdca"
],
[
"21c05eb2.84bdca"
],
[]
]
},
{
"id": "6a0963d5.dd679c",
"type": "change",
"z": "61414f15.486f38",
"name": "touch x,y",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "\" \" & msg.req.query.x & \" \" & msg.req.query.y",
"tot": "jsonata"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 210,
"y": 200,
"wires": [
[
"412dbcbc.e8c3d4",
"21c05eb2.84bdca"
]
]
},
{
"id": "21c05eb2.84bdca",
"type": "debug",
"z": "61414f15.486f38",
"name": "debug",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"x": 390,
"y": 110,
"wires": []
}
]