element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Pi IoT
  • Challenges & Projects
  • Design Challenges
  • Pi IoT
  • More
  • Cancel
Pi IoT
Blog [Pi IoT] Smart Competition Home #7: Competition system II - Android Competition application: tracking the distance
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: clazarom
  • Date Created: 27 Aug 2016 8:02 PM Date Created
  • Views 501 views
  • Likes 1 like
  • Comments 1 comment
  • design challenge
  • smart competition home
  • gps
  • android app
  • distance_measurement
  • sqlite (software)
  • steps
  • piot
Related
Recommended

[Pi IoT] Smart Competition Home #7: Competition system II - Android Competition application: tracking the distance

clazarom
clazarom
27 Aug 2016

This update describer the Android application created to manage the acquisition of points for the competition. At this moment, the competition only includes running or walking the maximum number of km at the end of each month. Also, since we can not trust the participants good will (or, since we know how witty they can be) we will prevent two basic cheating:image

    1. Driving - it will be an easy, fast and effortless way of increase the status
    2. Shaking the phone -the resident does not move but still increases the total distance

So, the distance tracking will involve both GPS location and the phone's accelerations data

 

Furthermore, the application will have to retain the information after being close. Consequently, we will be using a local database in the phone, an SQLite.

 

This update will developing in the User's Node, a Nexus 5 phone.

 

Main application

Initial setup:Nexus 5 - Android 6.0.1

Full code in github - SmartApp

 

MainActivity

When launching, the user will be able to select one of our two activities:

  • SmartHome - currently disabled till previous version is updated
  • CompetitionActivity - to be used when the person wants to improve their status in the competition. It will start recording and update the central node

image

 

 

Competition System Activity - Version 1 (ONLY INDIVIDUAL TRACKING)

imageimage

 

The GUI is constantly updated to show:

  1. Current distance
  2. Today's distance
  3. Monthly distance

 

Additionally, this information is stored in a local database in the phone.

 

PODIUM (Not enabled yet) > request other residents information from the server and see current state of the competititon

 

How to track the phone distance

 

GPS Location

To access GPS Location - we use Android Location library (android.location)
image

 

More in detail, the app uses of its classes:

  • Location - hold the GPS information (such as latitude and longitude) and offers some methods to operate them.
  • LocationListener - offers callbacks when the location, status or accuracy has changed
  • LocationManager - manager of the Location Service.

 

The app needs to obtain current location, compare it with the previous one and extract the distance.

This distance will then be updated in the main GUI and included in monthly and daily calculations.

 

Permissions

For certain sensible  operations, an Android app will have to request permission (so that the user can decide whether to grant it or not). It can be done in the apps Manifest (programmatically) or directly requested at run time .

 

We include the COARSE and FINE LOCATION permission in our Android Manifest:

<!-- GPS -->

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

 

NOTE - For API 23 or more: permission request needs to be done during run time. So, I include the following lines in our CompetitionActivity (inside the onCreate() method)

** It also includes request for the external storage, needed for the local database

// ****** REQUESTS *****
//Location and Write/Read external storage
requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);

//Check permissions
if (!canAccessLocation() || !canAccessMemory()) {

     requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);

     Toast.makeText(ctx, "Request Permissions", Toast.LENGTH_LONG).show();

}else {
     //Start tracking service

     if ( ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
          System.out.println("Start tracking ");

          mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

          mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_REFRESH_TIME, LOCATION_REFRESH_DISTANCE, mLocationListener);
          

     }else{
     //Do nothing  
     }
}

The code will first request the permission. Afterwards, checks whether it was granted (if not, requests again) and if so, starts the GPS Tracking activity

 

The code: CompetitionTrackActivity.java

We will have to create an instance of LocationManager and attach a self defined LocationListener(we did so when checking and requesting the permissions):

          mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, LOCATION_REFRESH_TIME, LOCATION_REFRESH_DISTANCE, mLocationListener);

 

The mLocationListener itself implements the methods:

  • onLocationChanged - this is the one used to obtained the distance
  • onStatusChanged - not used for now
  • onProviderEnabled - not used for now
  • onProviderDisabled - not used for now

 

Withe onLocationChanged, we will compare the new obtain location with the previous one and obtained the distance between them:

@Override

public void onLocationChanged(final Location location) {
     //Check if it is the first updated location

     
     if (previousLocation ==null) {

          previousLocation = location;
     }else{
          float distance = previousLocation.distanceTo(location);
          
          CompetitionTrackActivity.updateSessionDistance(distance);
          
          previousLocation = location;
     }
     }
}

(*) CompetitionTrackActivity.(distance) is a method to update the GUI with the new data

 

Problem with this approach: cars

It is very easy to gain a lot of kms while driving or commuting in the train if we just implement this approach.

 

A direct solution, using the same library is calculating the speed too (we have the distance, we can timestamp each location ---> V = distance/ time_variation ). If the speed is above a threshold (say.... 20km/h as the do in Pokemon Go), we discard the obtained distance

 

This app, however, will combine GPS solution with a step counter (to make sure the person is moving).

 

!!! GPS Location will probably drain a lot of battery, so I will keep an eye on it

 

Step counter from acceleration data

To count the steps we make use of the hardware Android library(we will use accelerometer data)https://image.winudf.com/225/02270293bebce13c/icon=150x.png

 

With this approach, we will count the number of steps. Since the system will always give us the total step number, the StepCounter will store the initial step_number and obtain the steps walked by subtracting to the absolute total.

 

Again, we implement a listener that will tell the app when the step number has bee updated.

 

The code: CountSteps.java

CountSteps implements SensorEventListener, with the meethods:

  • onSensorChanged() - when new step is recorded
  • onAccuracyChanged() - not used

 

To obtain the number of steps walked, the app has the following code:

@Override
public void onSensorChanged(SensorEvent event) {
   if (activityRunning) {
   if (!started) {
   initial_count = event.values[0];
   started = true;
   }
  System.out.println(event.values[0] + "vs "+initial_count);
   count = event.values[0] - initial_count;


   }

}

 

 

Problem with this approach:shaking the phone

As with any other step counter, if you shake the device the number of steps increases. We will need other methods to determine whether the person is really moving or not (aka GPS location).

 

This solution - Combination of both

In the final app, we use the GPS LocationListener to determined that the person is moving. Also, we include a min_distance parameter to make sure it is, in fact, moving and not some GPS variation.

 

However, the distance is not obtain with this new location, but with the step counter ! (again, this may not be a good enough solution: in the future, we can try to correlate the GPS distance and the distance obtained from the steps themselves to see any kind of trick).

 

The code is in this case:

@Override

public void onLocationChanged(final Location location) {
     //Check if it is the first updated location

     
     if (previousLocation ==null) {

          previousLocation = location;
     }else{
          float distance = previousLocation.distanceTo(location);

          
              previousLocation = location;          

          //Obtain distance from step counter, not GPS
float steps = stepCounter.getSteps();
   
if (distance > MIN_DISTANCE_THRESHOLD) {
  Toast.makeText(ctx, "Location steps: " + steps, Toast.LENGTH_LONG).show();
  if (steps >0)
  CompetitionTrackActivity.updateSessionDistance(stepsToKm(steps));
}else {
   //Restart counter
  // Steps but no movement??? Cheating....
   initial_steps = initial_steps +steps;
   stepCounter = new CountSteps(ctx, initial_steps);

}

}

 

How to retain the information

http://a2.mzstatic.com/us/r30/Purple/v4/8f/8f/fe/8f8ffeba-a1bf-5c07-c714-8cc6a2852375/icon175x175.png

Local database - SQLite

SQLite library

 

Permissions

We include the WRITE and READ EXTERAL STORAGE permission in our Android Manifest:

<!-- Write and read -->

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

NOTE - For API 23 or more: permission request needs to be done during run time. So, I include the following lines in our CompetitionActivity (inside the onCreate() method)

** This code is shown in the previous section

 

The code: DatabaseManager.java

 

First, I developed the functions to constantly store the distance values in a table. This table has the user as name, and columns for the time_stamp, current distance, day distance,month distance and updated(to be used when updating to the central node server).

image

 

Thanks to this database the app will retrieve today's and the month accumulated distance when restarting !!

 

 

The final result

Please see the following video showing the first running of the application image

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

 

Conclusion

In this post I explained how to create an Android application to track the traveled distance. This is the main app of the competition system. It will:

  • Record the resident's distance:
    • current distance
    • update the values of day total and month total (since it is a monthly competition!)
  • Store it in a local database
  • Sign in to reply

Top Comments

  • volly
    volly over 9 years ago +1
    clazarom . Pretty nifty Android development!
  • volly
    volly over 9 years ago

    clazarom. Pretty nifty Android development!

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube