GPS monitor for Android "KidsTrack"

    The task: summer is coming, children spend more and more time somewhere on the street, and I would like to know where they are. The ideal option is that I just give them the old android phone with me, and then watch them on the map on a large home monitor.
    In this article I will tell you why and how I wrote my first Android application with GPS functions “KidsTrack”, and what discoveries I made. This article will be useful to those who recently started programming for Android.


    Searches on Google Play gave me hundreds of different applications with the functions of GPS-monitors. I already started sorting through them, but around the 2nd decade I realized that the time spent on choosing can be quite comparable with the time spent on development. After all, my functional requirements are very simple:
    • the application must periodically send anonymous coordinates to the server,
    • the server should show a map with a marker in the appropriate place.

    It's all!

    There are still requirements that are not related to functionality, but which are no less important:
    • no need for registration, and account linking
    • free
    • lack of advertising
    • the absence of unnecessary functions that are already on the phone or in other applications, such as messaging, panic buttons, notifications, erasing data, phone locks, chat, etc.
    And yes, the coordinates will be stored on a server that is not free. But hosting now costs such a penny that I think it’s wrong to take money from people for storing a couple of numbers (or even a few kilobytes).

    In a word, having tried several applications from Google Play, I decided to write a tracker myself.

    Further, everything is trivial: installed Android Studio, drew a single screen with 3 buttons, wrote, it seemed to me, a service, debugged everything in the emulator, then in the USB debugger, everything seemed to work.
    3-button screen



    But as soon as I tried to run it on a physical device, surprises began. I would like to talk about some of them.

    Power Management Surprises



    Real Android devices tend to turn off their power whenever possible. Only very primitive system clocks are constantly powered (the mobile communication module is not considered here). The watch has a register (s) where you can use the AlarmManager to record the next time the phone’s processor wakes up. If the processor does not wake the clock, then it will continue to sleep without doing anything. This is done for a simple reason: an included processor will drain the battery in an hour. Therefore, if you want the service to do something once a minute, then desktop programming techniques like Thread.sleep (60000) will not work, but instead you need to use AlarmManager , something like this:

    public class YourService extends Service {
        public int onStartCommand(Intent intent, int flags, int startId) {
            /* Что-то делаем */
            ...
            /* Планируем следующий страрт */
            Intent ai = new Intent("info.izhforum.kidstrack.START_ALARM");
            PendingIntent pai = PendingIntent.getBroadcast(mInstance, 0, ai, 0);
            mAlarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+60000, pai);
            ...
        }
    }
    

    In this example, we program AlarmManager to wake up the phone after 1 minute, and send the START_ALARM intent to all the applications that are subscribed to it.

    Intents are received in all textbooks by the BroadcastReceiver object, however, if we need to:
    1. the phone woke from a deep sleep
    2. launched our service,
    3. did not fall asleep until completion

    then BroadcastReceiver will not work, and instead you need to use WakefulBroadcastReceiver - this object is guaranteed to prevent the phone from falling into sleep until the completeWakefulIntent method is called . In any case, I still could not get BroadcastReceiver to work reliably on a physical device.

    If your service can theoretically access the Internet via WiFi, then you need to take care that the WiFi module also has power on during the connection, since it is separate. If this is not done, then it can be difficult to understand why the application does not work on a physical device: after all, when debugging on an emulator or a device connected to a debugger via USB, the WiFi module’s power does not turn off, and everything works fine. You can disable WiFi power off like this:

    private WifiManager mWifiManager = null;
    private WifiManager.WifiLock mWifiManagerLock = null;
    ...
    mWifiManagerLock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "MyWFL");
    mWifiManagerLock.acquire();
    /* Здесь осуществляем сетевой ввод/вывод */
    mWifiManagerLock.release();
    


    GPS Surprises


    In the first version of the application, I made the determination of the coordinates of the device only using the "GPS" provider. And it was very surprising to me to observe on the server how more than 90% of the devices could not determine the coordinates and sent zeros.
    As it turned out, GPS is a rather capricious technology with many limitations, low speed and unpredictable accuracy. When using traditional GPS, the receiver’s sensor should receive data on all GPS satellites (and there are more than two dozen of them), select the most suitable among all of them, and calculate the coordinates from them. Data acquisition and enumeration can take 5 minutes or more, therefore the first “cold” start of GPS is always the slowest.
    If the GPS receiver has a clock and remembers the past coordinates and positions of the satellites, then it can use this data to determine the satellites that can be attached to at the moment. Therefore, restarting GPS usually happens much faster.
    In modern smartphones, the initial rough determination of coordinates can be carried out by the nearby transmitting cell towers, which also allows you to accelerate the "cold start" of GPS. To use this method, permission is required to use the "network" provider in Manifest, so the Internet can be used to determine the coordinates of towers.
    Another function of the “network” provider is to determine coordinates by visible WiFi networks. The determination is carried out by searching for the coordinates of the currently visible networks by their names and MAC addresses on Google servers via the Internet. Of course, in the background and without unnecessary notifications there is also reverse traffic: the phone, when it has determined its coordinates by GPS, can quietly send data about the WiFi networks surrounding it to Google servers, in this way to maintain the current status of the base of WiFi networks. We will leave the sad thoughts about the potential power of Google over the owners of Androids and WiFi networks beyond the scope of this article ...
    Having clarified all these nuances, I urgently corrected the application so that it would use not only the GPS provider but also the network. After that, a typical sequence of method callsonLocationChanged began to look like this:
      1) 00: 00.234 provider = “network”, accuracy = 1672m // coordinates came from cell towers
      2) 00: 00.933 provider = “network”, accuracy = 52m // coordinates for WiFi came
      3) 00: 16.310 provider = “gps”, accuracy = 28m // GPS coordinates came
    

    Still, I really wanted to use GPS, since this is usually the most accurate way, so I set the signal waiting time from the GPS sensor to 30 seconds, and if this is the first start, to 2 minutes. And if the GPS sensor did not work, then the coordinates from the provider "network" are used. After this change, devices began sending normal, non-zero coordinates to the server.
    GPS accuracy has also been very arbitrary. For example, often the accuracy of the coordinates obtained from the sensor of a stationary lying device may look like this:
    	05:13:05 76m
    	05:14:36 ​​68m
    	05:15:58 37m
    	05:17:20 79m
    	05:19:00 116m
    

    From these data it is clear that GPS is good for finding buildings or other large objects, but finding a person in a crowd or a phone in a snowdrift will not be easy.

    We should also mention GPS power. The GPS module is very voracious, therefore, in the textbooks, when requestLocationUpdates is called, do not set too short parameters for the minimum interval in time and distance. But in my experiments with 3 different physical devices, it turned out that a constantly-on GPS module charges the battery the same way with different parameters. Then I already found somewhere a mention that these parameters affect only the frequency of the onLocationChanged method call , but not necessarily the power consumption of the sensor itself.

    Other surprises



    Google Play : The first version lay on Google Play for two days, after which it was replaced by a new one, with a corrected coordinate determination algorithm. Despite the fact that this happened two weeks ago, I continue to see on the server that activation of the old version continues to happen very often. I already added a message about the need for updates on the monitoring web page, but this does not always help. It’s not clear where in general people get the old version. I do not know how to explain this.

    Users : Almost a third of the users who installed the application never opened a page on which the device can be monitored. Without a monitoring page, the application is useless, so I can’t explain this phenomenon either.
    monitoring page



    Yandex.Maps : The monitoring page was originally implemented using the Yandex.Maps API, since there is no ID required and there are no restrictions on the number of map downloads per day. But it turned out that on weak devices Yandex.Maps either slow down or do not open at all. I had to do this page in 2 versions: Yandex.Maps for desktop computers, and Google Maps for weak mobile devices. Google Maps turned out to be significantly faster.

    Summary


    From a practical point of view, the results are, of course, modest, since there are already many much more advanced GPS monitors. But judging by the reviews, it was the simplicity of KidsTrack that many liked.
    For me personally, the results are much more impressive. The main result is an invaluable experience that could not be obtained from articles or textbooks. The rake described above made us reconsider the realism and design of other larger projects that I am working on.

    Also popular now: