org.navitproject.navit.NavitVehicle.java Source code

Java tutorial

Introduction

Here is the source code for org.navitproject.navit.NavitVehicle.java

Source

/**
 * Navit, a modular navigation system.
 * Copyright (C) 2005-2008 Navit Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * 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, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

package org.navitproject.navit;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;

import java.util.List;

public class NavitVehicle {

    private static final String GPS_FIX_CHANGE = "android.location.GPS_FIX_CHANGE";

    public static Location lastLocation = null;

    private static LocationManager sLocationManager = null;
    private static Context context = null;
    private int vehicle_pcbid;
    private int vehicle_scbid;
    private int vehicle_fcbid;
    private String preciseProvider;
    private String fastProvider;

    private static NavitLocationListener preciseLocationListener = null;
    private static NavitLocationListener fastLocationListener = null;

    public native void VehicleCallback(int id, Location location);

    public native void VehicleCallback(int id, int satsInView, int satsUsed);

    public native void VehicleCallback(int id, int enabled);

    private class NavitLocationListener extends BroadcastReceiver implements GpsStatus.Listener, LocationListener {
        public boolean precise = false;

        public void onLocationChanged(Location location) {
            lastLocation = location;
            // Disable the fast provider if still active
            if (precise && fastProvider != null) {
                sLocationManager.removeUpdates(fastLocationListener);
                fastProvider = null;
            }

            VehicleCallback(vehicle_pcbid, location);
            VehicleCallback(vehicle_fcbid, 1);
        }

        public void onProviderDisabled(String provider) {
        }

        public void onProviderEnabled(String provider) {
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {
        }

        /**
         * Called when the status of the GPS changes.
         */
        public void onGpsStatusChanged(int event) {
            if (ContextCompat.checkSelfPermission(context,
                    android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // Permission is not granted
                return;
            }
            GpsStatus status = sLocationManager.getGpsStatus(null);
            int satsInView = 0;
            int satsUsed = 0;
            Iterable<GpsSatellite> sats = status.getSatellites();
            for (GpsSatellite sat : sats) {
                satsInView++;
                if (sat.usedInFix()) {
                    satsUsed++;
                }
            }
            VehicleCallback(vehicle_scbid, satsInView, satsUsed);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(GPS_FIX_CHANGE)) {
                if (intent.getBooleanExtra("enabled", false)) {
                    VehicleCallback(vehicle_fcbid, 1);
                } else {
                    if (!intent.getBooleanExtra("enabled", true)) {
                        VehicleCallback(vehicle_fcbid, 0);
                    }
                }
            }
        }
    }

    /**
     * @brief Creates a new {@code NavitVehicle}
     *
     * @param context
     * @param pcbid The address of the position callback function called when a location update is received
     * @param scbid The address of the status callback function called when a status update is received
     * @param fcbid The address of the fix callback function called when a
     * {@code android.location.GPS_FIX_CHANGE} is received, indicating a change in GPS fix status
     */
    NavitVehicle(Context context, int pcbid, int scbid, int fcbid) {
        if (ContextCompat.checkSelfPermission(context,
                android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // Permission is not granted
            return;
        }
        this.context = context;
        sLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        preciseLocationListener = new NavitLocationListener();
        preciseLocationListener.precise = true;
        fastLocationListener = new NavitLocationListener();

        /* Use 2 LocationProviders, one precise (usually GPS), and one
           not so precise, but possible faster. The fast provider is
           disabled when the precise provider gets its first fix. */

        // Selection criteria for the precise provider
        Criteria highCriteria = new Criteria();
        highCriteria.setAccuracy(Criteria.ACCURACY_FINE);
        highCriteria.setAltitudeRequired(true);
        highCriteria.setBearingRequired(true);
        highCriteria.setCostAllowed(true);
        highCriteria.setPowerRequirement(Criteria.POWER_HIGH);

        // Selection criteria for the fast provider
        Criteria lowCriteria = new Criteria();
        lowCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
        lowCriteria.setAltitudeRequired(false);
        lowCriteria.setBearingRequired(false);
        lowCriteria.setCostAllowed(true);
        lowCriteria.setPowerRequirement(Criteria.POWER_HIGH);

        Log.e("NavitVehicle", "Providers " + sLocationManager.getAllProviders());

        preciseProvider = sLocationManager.getBestProvider(highCriteria, false);
        Log.e("NavitVehicle", "Precise Provider " + preciseProvider);
        fastProvider = sLocationManager.getBestProvider(lowCriteria, false);
        Log.e("NavitVehicle", "Fast Provider " + fastProvider);
        vehicle_pcbid = pcbid;
        vehicle_scbid = scbid;
        vehicle_fcbid = fcbid;

        context.registerReceiver(preciseLocationListener, new IntentFilter(GPS_FIX_CHANGE));
        sLocationManager.requestLocationUpdates(preciseProvider, 0, 0, preciseLocationListener);
        sLocationManager.addGpsStatusListener(preciseLocationListener);

        /*
         * Since Android criteria have no way to specify "fast fix", lowCriteria may return the same
         * provider as highCriteria, even if others are available. In this case, do not register two
         * listeners for the same provider but pick the fast provider manually. (Usually there will
         * only be two providers in total, which makes the choice easy.)
         */
        if (fastProvider == null || preciseProvider.compareTo(fastProvider) == 0) {
            List<String> fastProviderList = sLocationManager.getProviders(lowCriteria, false);
            fastProvider = null;
            for (String fastCandidate : fastProviderList) {
                if (preciseProvider.compareTo(fastCandidate) != 0) {
                    fastProvider = fastCandidate;
                    break;
                }
            }
        }
        if (fastProvider != null) {
            sLocationManager.requestLocationUpdates(fastProvider, 0, 0, fastLocationListener);
        }
    }

    public static void removeListener() {
        if (sLocationManager != null) {
            if (preciseLocationListener != null) {
                sLocationManager.removeUpdates(preciseLocationListener);
                sLocationManager.removeGpsStatusListener(preciseLocationListener);
                context.unregisterReceiver(preciseLocationListener);
            }
            if (fastLocationListener != null) {
                sLocationManager.removeUpdates(fastLocationListener);
            }
        }

    }
}