it.ms.theing.loquitur.functions.LocationInterface.java Source code

Java tutorial

Introduction

Here is the source code for it.ms.theing.loquitur.functions.LocationInterface.java

Source

/*
Loquitur, Location Module
    
Copyright (C) 2015 by TheIng
http://github.com/theing/Loquitur
    
This file is part of Loquitur.
    
Loquitur is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
*/

package it.ms.theing.loquitur.functions;

import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.JavascriptInterface;

import org.json.JSONArray;

import java.util.Calendar;
import java.util.List;
import java.util.Locale;

import it.ms.theing.loquitur.Loquitur;

/**
 * This module retrieves the user current location.
 */

public class LocationInterface implements LoquiturModules {

    private LocationManager locationManager;
    private Loquitur context;
    private Handler timeout = new Handler();
    private String gpsCallback = "";
    private boolean done = false;
    private final long TIMEOUT = 60000;
    private final long TIMEVAL = 60000;

    private void sendLocation(Location location) {
        String conv = String.format(Locale.ENGLISH, "(%3.8f,%3.8f,%3.8f)", location.getLatitude(),
                location.getLongitude(), location.getAltitude());
        context.executeCallback(gpsCallback + conv);
    }

    private final LocationListener ll = new LocationListener() {
        @Override
        public void onLocationChanged(android.location.Location location) {
            timeout.removeCallbacks(tout);
            sendLocation(location);
        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {

        }

        @Override
        public void onProviderEnabled(String s) {

        }

        @Override
        public void onProviderDisabled(String s) {
            timeout.removeCallbacks(tout);
            tout.run();
        }
    };

    private Runnable tout = new Runnable() {
        @Override
        public void run() {
            locationManager.removeUpdates(ll);
            context.executeCallback(gpsCallback + "(1000.00,1000.00,1000.00)");
        }
    };

    public LocationInterface(Loquitur activity) {
        locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
        context = activity;
    }

    private Location getLocation() {
        done = true;
        long timeInMillis = Calendar.getInstance().getTimeInMillis();
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        String fine = locationManager.getBestProvider(criteria, true);
        if (fine == null)
            return null;
        Location location = locationManager.getLastKnownLocation(fine);
        if (location != null) {
            if (timeInMillis - location.getTime() < TIMEVAL) {
                return location;
            }
        }
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        String coarse = locationManager.getBestProvider(criteria, true);
        if (!(fine.equals(coarse))) {
            location = locationManager.getLastKnownLocation(fine);
            if (location != null) {
                if (timeInMillis - location.getTime() < TIMEVAL) {
                    return location;
                }
            }
        }
        timeout.postDelayed(tout, TIMEOUT); // At most 1 minute
        //locationManager.requestSingleUpdate(fine, ll, Looper.myLooper());
        locationManager.requestSingleUpdate(fine, ll, null);
        done = false;
        return null;
    }

    /**
     * Get the current location
     * @param callback
     * after the location has been taken calling back the location coordinates
     * example : Location.currentLocation('callThis');
     * after grabbed the location it calls "callThis(50.22213,0.523713,300)"
     * if something goes wrong, it calls : "callThis(999,999,999)"
     *
     */

    @JavascriptInterface
    public void currentLocation(String callback) {
        Location loc = getLocation();
        gpsCallback = callback;
        if (loc == null) {
            if (done) {
                tout.run();
                return;
            }
        } else {
            sendLocation(loc);
        }
    }

    /**
     * Get a string with the location.
     * @param lat
     * latitude
     * @param lon
     * longitude
     * @return
     * location or empty string
     */
    @JavascriptInterface
    public String geoCoder(float lat, float lon) {
        try {
            Geocoder geo = new Geocoder(context);
            if (!geo.isPresent())
                return "";
            List<Address> addresses = geo.getFromLocation(lat, lon, 1);
            if (addresses == null)
                return "";
            if (addresses.size() > 0) {
                JSONArray ja = new JSONArray();
                if (addresses.get(0).getFeatureName() != null)
                    ja.put(addresses.get(0).getFeatureName());
                else
                    ja.put("");
                if (addresses.get(0).getAddressLine(0) != null)
                    ja.put(addresses.get(0).getAddressLine(0));
                else
                    ja.put("");
                if (addresses.get(0).getLocality() != null)
                    ja.put(addresses.get(0).getLocality());
                else
                    ja.put("");
                if (addresses.get(0).getAdminArea() != null)
                    ja.put(addresses.get(0).getAdminArea());
                else
                    ja.put("");
                if (addresses.get(0).getCountryName() != null)
                    ja.put(addresses.get(0).getCountryName());
                else
                    ja.put("");
                return ja.toString();
            }
        } catch (Exception e) {
        }
        return "";
    }

    @Override
    public String getJavascriptName() {
        return "Location";
    }

    @Override
    public void endModule() {
        locationManager.removeUpdates(ll);
        timeout.removeCallbacks(tout);
    }
}