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


control movil android adbnode-red

control movil android adb node-red

control movil android adb node-red

Demo (No operativa)

Control Movil (Via Adb)

20:07:00MenuHome EnterEscTabAtras Sett.Tether

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": []
    }
]