{"id":153,"date":"2021-12-12T19:53:13","date_gmt":"2021-12-12T18:53:13","guid":{"rendered":"https:\/\/www.davidestebanmunoz.com\/?p=153"},"modified":"2023-11-01T18:45:09","modified_gmt":"2023-11-01T17:45:09","slug":"wearlive","status":"publish","type":"post","link":"https:\/\/www.davidestebanmunoz.com\/?p=153","title":{"rendered":"Wearlive"},"content":{"rendered":"\n<p><a href=\"https:\/\/www.davidestebanmunoz.com\/?p=178&amp;lang=es\">Este art\u00edculo se puede leer en castellano aqu\u00ed<\/a><\/p>\n\n\n\n<p>Wearlive is accessible at <a href=\"https:\/\/wearlive.davidestebanmunoz.com\">https:\/\/wearlive.davidestebanmunoz.com<\/a> .<\/p>\n\n\n\n<p>Wearlive is divided into two different parts, an android wear App and a web service. Both of them have been developed 100% by me.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wearlive Android Wear app<\/h2>\n\n\n\n<p>Wearlive android wear app is a native android app, coded in Java using Android Studio as IDE.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"367\" height=\"352\" src=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen.png\" alt=\"\" class=\"wp-image-154\" srcset=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen.png 367w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-300x288.png 300w\" sizes=\"auto, (max-width: 367px) 100vw, 367px\" \/><\/figure>\n\n\n\n<p>It receives GPS location each 5 seconds from Android system, and sends it to wearlive.tk server by UDP. It is really useful if you have a smartwatch with e-sim.<\/p>\n\n\n\n<p>Before starting using it, android watch serial number must be registered into <a href=\"https:\/\/wearlive.davidestebanmunoz.com\">https:\/\/wearlive.davidestebanmunoz.com<\/a> .<\/p>\n\n\n\n<p>For privacy and security purposes, tracks can be protected using password, in that case Protect switch must be set .<\/p>\n\n\n\n<p>Once serial number has been registered, just switch on \u00abStart tracking\u00bb and start with your activity, app will launch a background service that will send your location every 5 seconds. The app itself shows when it is live tracking and when Android has got a valid GPS status.<\/p>\n\n\n\n<p>One special trick of this app is that it works even if the APN of the mobile network operator is not correctly set. This is because in Spain, Movistar disabled its HTTP proxy on April 2021 and Android Wear does not allow us to modify APN. So using raw UDP frames allows to bypass this problem. Also, as UDP is connectionless, battery usage has been reduced.<\/p>\n\n\n\n<p>Using a Xiaomi Mi Watch this app has used 38% of its battery for 10km and 56 minutes  session.<\/p>\n\n\n\n<p> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wearlive Web Server<\/h2>\n\n\n\n<p>Wearlive web server is formed using several docker containers and technologies:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"612\" height=\"282\" src=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/wearlive_server.png\" alt=\"\" class=\"wp-image-155\" srcset=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/wearlive_server.png 612w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/wearlive_server-300x138.png 300w\" sizes=\"auto, (max-width: 612px) 100vw, 612px\" \/><\/figure>\n\n\n\n<p>The blue stack is the same we saw on previous posts and its explanation can be seen <a href=\"https:\/\/www.davidestebanmunoz.com\/?p=130\">here<\/a>.<\/p>\n\n\n\n<p>The green stack has a NGINX for web server, PHP docker for getting location data from MariaDB and also for registering users and the Python docker receives UDP frames at 20002 port and if its data is valid and the serial of the sender has been registered, inserts location into MariaDB.<\/p>\n\n\n\n<p>The docker-compose recipe of green stack can be seen here:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nversion: '3'\nservices:\n    db_wearlivetk:\n        image: mariadb:10.5\n        container_name: db_wearlivetk\n        restart: unless-stopped\n        env_file: .env\n        environment:\n            - MYSQL_DATABASE=$WEARLIVE_MYSQL_DATABASE\n            - MYSQL_USER=$WEARLIVE_MYSQL_USER\n            - MYSQL_PASSWORD=$WEARLIVE_MYSQL_PASSWORD\n            - MYSQL_ROOT_PASSWORD=$WEARLIVE_MYSQL_ROOT_PASSWORD\n        volumes:\n            - \"\/home\/ubuntu\/dockers\/wearlive\/data\/db\/:\/var\/lib\/mysql\"\n        #command: '--default-authentication-plugin=mysql_native_password'\n        networks:\n          - david\n    webwearlive:\n        container_name: webwearlive\n        depends_on:\n          - db_wearlivetk\n        build:\n            dockerfile: Dockerfile_php\n        image: php7-fpm_mysqli\n        volumes:\n            - \"\/home\/ubuntu\/dockers\/wearlive\/data\/html:\/var\/www\/html\"\n        env_file: .env\n        environment:\n          - DB_HOST=db_wearlivetk:3306\n          - DB_USER=$WEARLIVE_MYSQL_USER\n          - DB_PASSWORD=$WEARLIVE_MYSQL_PASSWORD\n          - DB_NAME=$WEARLIVE_MYSQL_DATABASE\n        networks:\n          - david\n          \n    wearlive_receiver:\n        depends_on:\n          - db_wearlivetk\n        build:\n            dockerfile: Dockerfile_wearlive_receiver\n        image: wearlive_receiver:0.0.1\n        container_name: wearlive_receiver\n        restart: unless-stopped\n        env_file: .env\n        environment:\n          - DB_HOST=db_wearlivetk\n          - DB_USER=$WEARLIVE_MYSQL_USER\n          - DB_PASSWORD=$WEARLIVE_MYSQL_PASSWORD\n          - DB_NAME=$WEARLIVE_MYSQL_DATABASE\n        volumes:\n            - \"\/home\/ubuntu\/dockers\/wearlive\/data\/receiver:\/code\/\"\n        networks:\n          - david\n        command: python \/code\/udp_server.py\n        ports:\n            - 20002:20002\/udp\n    \n\n    wearlive_nginx:\n        image: nginx\n        depends_on:\n          - webwearlive\n        container_name: wearlive_nginx\n        networks:\n          - proxy_nginx-proxy\n          - david\n        environment:\n            - VIRTUAL_HOST=wearlive.davidestebanmunoz.com\n            - LETSENCRYPT_HOST=wearlive.davidestebanmunoz.com\n        volumes:\n            - \"\/home\/ubuntu\/dockers\/wearlive\/data\/nginx\/etc_nginx:\/etc\/nginx\"\n            - \"\/home\/ubuntu\/dockers\/wearlive\/data\/html:\/var\/www\/html\"\n            \n    phpmyadmin:\n        image: arm64v8\/phpmyadmin\n        container_name: phpmyadmin\n        depends_on:\n          - db_wearlivetk\n        links:\n          - db_wearlivetk:db\n        networks:\n          - david\n        environment:\n          PMA_HOST: db_wearlivetk\n          PMA_PORT: 3306\n          PMA_ARBITRARY: 1\n          MYSQL_ROOT_PASSWORD: $WEARLIVE_MYSQL_ROOT_PASSWORD\n        restart: always\n        ports:\n          - 8081:80\nnetworks:\n    david:\n    proxy_nginx-proxy:\n        external: true        \n       <\/code><\/pre>\n\n\n\n<p>As can be seen in recipe, in this case dockerfiles have been used , for PHP(webwearlive) and for Python(wearlive_receiver) dockers. In both cases, it is used to install MySQL support.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM php:7-fpm\nRUN docker-php-ext-install mysqli\nRUN docker-php-ext-enable mysqli<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM python:3.8-slim\nRUN pip install pymysql<\/code><\/pre>\n\n\n\n<p>The wearlive webserver is based on PHP, Javascript and HTML code.  Using AJAX procedures, and based on OpenStreetMaps , the location is read from DB and drawn over a map layer.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"956\" height=\"756\" src=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/mapa.png\" alt=\"\" class=\"wp-image-156\" srcset=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/mapa.png 956w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/mapa-300x237.png 300w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/mapa-768x607.png 768w\" sizes=\"auto, (max-width: 956px) 100vw, 956px\" \/><\/figure>\n\n\n\n<p>In case the user has selected to protect its live tracking with a password, it is prompted before allowing to see where is it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"519\" height=\"146\" src=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-1.png\" alt=\"\" class=\"wp-image-157\" srcset=\"https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-1.png 519w, https:\/\/www.davidestebanmunoz.com\/wp-content\/uploads\/2021\/12\/imagen-1-300x84.png 300w\" sizes=\"auto, (max-width: 519px) 100vw, 519px\" \/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Type: Android APP + Website<\/li>\n\n\n\n<li>Where: Android app on smartwatches + Docker containers on VPS<\/li>\n\n\n\n<li>Languages and technologies used: Java, GPS, UDP, Python, SQL, PHP, HTML, Javascript<\/li>\n\n\n\n<li>Github repo: no<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/www.davidestebanmunoz.com\/?p=153\">Read More<span class=\"screen-reader-text\">Wearlive<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[50,38,40,51,59,42,49,52,53],"class_list":["post-153","post","type-post","status-publish","format-standard","hentry","category-personal-projects","tag-android","tag-docker-en","tag-html-en","tag-java","tag-javascript","tag-php-en","tag-python","tag-sql","tag-udp","excerpt"],"_links":{"self":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/153","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=153"}],"version-history":[{"count":10,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/153\/revisions"}],"predecessor-version":[{"id":288,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=\/wp\/v2\/posts\/153\/revisions\/288"}],"wp:attachment":[{"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=153"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=153"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.davidestebanmunoz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}