106.Android simple GPS real-time positioning

//Location permissions, network permissions:

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

//GPS switch and app positioning permissions are manually turned on, which are not provided here. The following targeting code:

//The following is the positioning tool class:

/**
 * System positioning tool class
 * todo: Pay attention to LocationManager.NETWORK_PROVIDER, LocationManager.GPS_PROVIDER, LocationManager.PASSIVE_PROVIDER
 * <p>
 * GPS_PROVIDER: This means that there is a GPS chip in the mobile phone, and then you can use the chip to obtain your own position using satellites information. But indoors, GPS positioning is basically useless, and it is very difficult to locate.
 * <p>
 * NETWORK_PROVIDER: This is the use of network positioning, generally using the addresses of mobile phone base stations and WIFI nodes to roughly locate the location. *
 This positioning method depends on the server, that is, it depends on the translation of base station or WIF node information into location information The capacity of the server.
 * Because most Android phones do not have Google's official location manager library installed.
 * The mainland network also disagrees. That is, there is no server to do this. Naturally, this method basically cannot achieve positioning.
 * <p>
 * PASSIVE_PROVIDER: Passive positioning method.
 * This meaning is also more obvious. It is ready-made, when other applications use the location to update the location information.
 * The system will save it. After the application receives the message, it can be read directly.
 * For example, assume that Baidu map and Gaode map have been installed in the system (accurate positioning can be achieved indoors).
 * You only use them after positioning. Using this method in your program will definitely be able to get more accurate positioning information.
 * <p>
 * Only the mode of NETWORK_PROVIDER is a reliable way for indoor positioning.
 * Because of the special network in mainland China, and most manufacturers will not use Google services, this positioning method is not available by default.
 * It is recommended to use other three-party positioning sdk
 * <p>
 * (1) GPS_PROVIDER: Obtain the latitude and longitude information of the geographical location through GPS; advantage: obtain the location information with high accuracy; disadvantage: it can only be used outdoors, and it takes time to obtain the latitude and longitude information , power consumption;
 * (2) NETWORK_PROVIDER: Obtain the geographical location through the base station of the mobile network or Wi-Fi; advantage: as long as there is a network, you can quickly locate it, both indoors and outdoors; disadvantage: the accuracy is not high; * (
 3 ) PASSIVE_PROVIDER: Passively receive updated geographic location information without requesting geographic location information yourself.
 * The location returned by PASSIVE_PROVIDER is generated by other providers. You can query the getProvider() method to determine the origin of the location update. ACCESS_FINE_LOCATION permission is required, but if GPS is not enabled, this provider may only return a rough location match; * (4) FUSED_PROVIDER
 : This has been abandoned, but it is now used again on Android12 (ie android api 31), but it relies on GMS, so it is temporarily unavailable in China.
 * We usually use the two methods of gps and network.
 * <p>
 * Indoor measurement: GPS_PROVIDER is invalid, PASSIVE_PROVIDER is invalid, NETWORK_PROVIDER is valid but not particularly accurate
 *
 * @author CJF
 */
public class LocationManagerUtil {
    private volatile static LocationManagerUtil locationManagerUtil = null;
    private final String TAG = "LocationManagerUtil";
    private final Context context = RecordApp.context;
    private final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    private LocationManagerListener listener;
    private final Handler handler = new Handler(Looper.myLooper());

    /**
     * Timeout time 10 seconds
     */
    private final long TIME_OUT = 10000;

    /**
     * Timeout end listener flag
     */
    private boolean endlistenerFlag = false;

    public static LocationManagerUtil getInstance() {
        if (null == locationManagerUtil) {
            synchronized (LocationManagerUtil.class) {
                if (null == locationManagerUtil) {
                    locationManagerUtil = new LocationManagerUtil();
                }
            }
        }
        return locationManagerUtil;
    }

    /**
     * Start single location location
     *
     * @param listener
     */
    public void startSingleLocation(LocationManagerListener listener) {         this.listener = listener;         endlistenerFlag = false;

        if (null == locationManager) {
            XLog.d(TAG, "locationManager=null return");
            return;
        }

        //Get the current network state
        boolean networkState = CommonMethod.checkNetworkState();

        if (!networkState) {             XLog.d(TAG, "No Network return");             return;         }


        //Check permission
        boolean permission = checkPermission();
        if (!permission) {             XLog.d(TAG, "Target permission is not enabled return");             return;         }


        String provider = LocationManager.NETWORK_PROVIDER;
        XLog.d(TAG, "provider:" + provider);

        //Judge whether the provider is available
        boolean providerEnabled = locationManager.isProviderEnabled(provider);
        if (!providerEnabled) {             XLog.d(TAG, provider + " unavailable return");             return;         }


        //Get the location information in the cache getLastKnownLocation
        Location location = locationManager.getLastKnownLocation(provider);
        if (null != location) {             String locationAddr = getLocationAddr(location.getLongitude(), location.getLatitude());             XLog.d(TAG , "The location information in the cache location:" + location.toString());             XLog.d(TAG, "The location information in the cache locationAddr:" + locationAddr);             //Clear the location information             location.reset();         }





//        getWifi();
//
//        getTelephonyManager();

        // Criteria crite = new Criteria();
// crite.setAccuracy(Criteria.ACCURACY_FINE); //accuracy
// crite.setPowerRequirement(Criteria.POWER_LOW); //power consumption type selection
// String provider = locationManager.getBestProvider( crite, true);

//        String networkProvider = LocationManager.NETWORK_PROVIDER;
//        String gpsProvider = LocationManager.GPS_PROVIDER;
//        String passiveProvider = LocationManager.PASSIVE_PROVIDER;

        //Add geofence
// locationManager.addProximityAlert(38.234, 114.234, 5, -1, PendingIntent.getBroadcast(this, 1, new Intent(), 3));
// You can set an area, when entering or leaving this area When you will receive a notification, the first two parameters specify a point, the third parameter is the radius, the fourth parameter is the timeout time, set to -1 means there is no timeout, and the last one is the broadcast receiver.
// The triggered Intent will use the key KEY_PROXIMITY_ENTERING, if the value is true, the device enters the proximity area, if false, the device leaves the area.

        //Get a location result requestSingleUpdate Single location
        locationManager.requestSingleUpdate(provider, locationListener, handler.getLooper());

        //Timeout end location
        handler.postDelayed(new Runnable() {             @Override             public void run() {                 locationManager.removeUpdates(locationListener);                 handler.removeCallbacks(this);                 if (!endlistenerFlag) {                     XLog.d(TAG, "location timeout");                     onFailureListener();                 }             }         }, TIME_OUT);     }










    /**
     * Start location and continue location
     *
     * @param listener
     */
    public void startLocationUpdates(LocationManagerListener listener) {         this.listener = listener;         endlistenerFlag = false;

        if (null == locationManager) {
            XLog.d(TAG, "locationManager=null return");
            return;
        }

        //Get the current network state
        boolean networkState = CommonMethod.checkNetworkState();

        if (!networkState) {             XLog.d(TAG, "No Network return");             return;         }


        //Check permission
        boolean permission = checkPermission();
        if (!permission) {             XLog.d(TAG, "Target permission is not enabled return");             return;         }


        String provider = LocationManager.NETWORK_PROVIDER;
        XLog.d(TAG, "provider:" + provider);

        //Judge whether the provider is available
        boolean providerEnabled = locationManager.isProviderEnabled(provider);
        if (!providerEnabled) {             XLog.d(TAG, provider + " unavailable return");             return;         }


        //Get the location information in the cache getLastKnownLocation
        Location location = locationManager.getLastKnownLocation(provider);
        if (null != location) {             String locationAddr = getLocationAddr(location.getLongitude(), location.getLatitude());             XLog.d(TAG , "The location information in the cache location:" + location.toString());             XLog.d(TAG, "The location information in the cache locationAddr:" + locationAddr);             //Clear the location information             location.reset();         }





// Criteria crite = new Criteria();
// crite.setAccuracy(Criteria.ACCURACY_FINE); //accuracy
// crite.setPowerRequirement(Criteria.POWER_LOW); //power consumption type selection
// String provider = locationManager.getBestProvider( crite, true);

//        String networkProvider = LocationManager.NETWORK_PROVIDER;
//        String gpsProvider = LocationManager.GPS_PROVIDER;
//        String passiveProvider = LocationManager.PASSIVE_PROVIDER;

        //Add geofence
// locationManager.addProximityAlert(38.234, 114.234, 5, -1, PendingIntent.getBroadcast(this, 1, new Intent(), 3));
// You can set an area, when entering or leaving this area When you will receive a notification, the first two parameters specify a point, the third parameter is the radius, the fourth parameter is the timeout time, set to -1 means there is no timeout, and the last one is the broadcast receiver.
// The triggered Intent will use the key KEY_PROXIMITY_ENTERING, if the value is true, the device enters the proximity area, if false, the device leaves the area.

        //Continuous positioning:
        //Binding monitoring, there are 4 parameters
        //Parameter 1, device: There are three types of GPS_PROVIDER, NETWORK_PROVIDER, PASSIVE_PROVIDER
        //Parameter 2, location information update cycle, in milliseconds
        //Parameter 3, the smallest change in location Distance: When the position distance changes beyond this value, the position information will be updated
        //parameter 4, listen
        //Remarks: parameters 2 and 3, if parameter 3 is not 0, then parameter 3 shall prevail; if parameter 3 is 0, then Update regularly by time; if the two are 0, refresh at any time
        //Update once every minute, or update once if the minimum displacement change exceeds 1 meter;
        locationManager.requestLocationUpdates(provider, 60 * 1000, 0, locationListener, handler.getLooper() );

        //Timeout end location
        handler.postDelayed(new Runnable() {             @Override             public void run() {                 locationManager.removeUpdates(locationListener);                 handler.removeCallbacks(this);                 if (!endlistenerFlag) {                     XLog.d(TAG, "location timeout");                     onFailureListener();                 }             }         }, TIME_OUT);     }










    /**
     * Location monitoring
     */
    private final LocationListener locationListener = new LocationListener() {         /**          * Triggered when the location information changes          * This method will be called back when the location changes, and the latitude and longitude related information is stored in the Location;          */         @Override         public void onLocationChanged(Location location) {             //assigned to true             endlistenerFlag = true;             if (null != locationManager) {                 //unregister the listener to end                 location locationManager.removeUpdates(this);             }             String time = DateTimeUtility.formatDateTime(location.getTime (), 0);             final double longitude = location. getLongitude();














            final double latitude = location.getLatitude();
            double altitude = location.getAltitude();
            double longitudeGd = location.getLongitude() + 0.0052719116;//The difference between longitude system positioning and Gaode positioning coordinates is 0.0052719116
            double latit udeGd = location. getLatitude( ) + 0.0010604858;//The difference between latitude system positioning and Gaode positioning coordinates is 0.0010604858

            //Get the geographic location
            String locationAddr = getLocationAddr(longitude, latitude);
            //Get the longitude and latitude address of Gaode
            String locationAddrGd = getLocationAddr(longitudeGd, latitudeGd);

            XLog.d(TAG, "Time:" + time);
            XLog.d(TAG, "Longitude:" + longitude);
            XLog.d(TAG, "Latitude:" + latitude);
            XLog.d(TAG, "Altitude : " + altitude);
            XLog.d(TAG, "Location:" + locationAddr);
            XLog.d(TAG, "Gold longitude: " + longitudeGd);
            XLog.d(TAG, "Gold latitude: " + latitudeGd );
            XLog.d(TAG, "Gode location:" + locationAddrGd);


            if (TextUtils.isEmpty(locationAddr)) {                 // failure callback                 onFailureListener();             } else {                 // success callback                 onSuccessListener(locationManager, location, longitudeGd, latitudeGd, locationAddr);             }         }






        /**
         * Triggered when the GPS status changes
         * The provider we use will call back when the status changes
         */
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {             switch (status) {                 //When the GPS status is visible                 case LocationProvider.AVAILABLE:                     Log.d(TAG, "The current GPS status is visible and the provider is available");                     break;                 //When the GPS status is outside the service area,                 case LocationProvider.OUT_OF_SERVICE:                     Log.d(TAG, "The current GPS status is The state outside the service area has no service");                     break;                 //When the GPS state is suspended service                 case LocationProvider.TEMPORARILY_UNAVAILABLE:











                    Log.d(TAG, "The current GPS status is suspended service status provider is unavailable");
                    break;
                default:
                    break;
            }
        }

        /**
         * Triggered when GPS is turned on
         * Triggered when the provider is available, for example, GPSProvider will call back this method when the positioning mode is switched to use precise location;
         */
        @Override
        public void onProviderEnabled(String provider) {

        }

        /**
         * Triggered when GPS is disabled
         * Triggered when the provider is unavailable, for example, GPSProvider will call back this method when the positioning mode is switched to use network positioning;
         */
        @Override
        public void onProviderDisabled(String proider) {

        }
    };

    /**
     * 检查权限
     *
     * @return
     */
    private boolean checkPermission() {
        if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            CommonMethod.showToast("请开启定位权限");
            return false;
        }
        return true;
    }

    /**
     * wifi定位 不准确
     */
    private void getWifi() {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (null == wifiManager) {
            XLog.d(TAG, "null == wifiManager return");
            return;
        }
        if (!wifiManager.isWifiEnabled()) {
            XLog.d(TAG, "wifi未启用 return");
            return;
        }
        WifiInfo connectionInfo = wifiManager.getConnectionInfo();
        String ssid = connectionInfo.getSSID();
        final String bssid = connectionInfo.getBSSID();
        int ipAddress = connectionInfo.getIpAddress();
        @SuppressLint("HardwareIds") String macAddress = connectionInfo.getMacAddress();
        String string = connectionInfo.toString();
        XLog.d(TAG, "wifi名称:" + ssid);
        XLog.d(TAG, "wifi的mac:" + bssid);
        XLog.d(TAG, "ipAddress:" + ipAddress);
        XLog.d(TAG, "macAddress:" + macAddress);
        XLog.d(TAG, "string:" + string);

        ThreadPoolExecutorUtil.getInstance().startThread(new Runnable() {             @Override             public void run() {                 try {                     URL url = new URL("http://api.celllocation.com:83/wifi/?mac=" + bssid + "&output=json");                     XLog.d(TAG, "url:" + url.toString());                     HttpURLConnection connection = (HttpURLConnection) url.openConnection();                     //Timeout                     connection.setConnectTimeout(3000);                     / / means to set this http request to use the GET method                     connection.setRequestMethod("GET");                     //Return to is the response number, such as: HTTP_OK means the connection is successful.











                    int responsecode = connection.getResponseCode();
                    if (responsecode == HttpURLConnection.HTTP_OK) {
                        InputStream inputStream = connection.getInputStream();
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
                        String result = bufferedReader.readLine();
                        XLog.d(TAG, "result:" + result);
                    } else {
                        XLog.d(TAG, "result responsecode:" + responsecode);
                    }
                    connection.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 手机基站信息定位 不准确
     */
    private void getTelephonyManager() {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (null == manager) {
            return;
        }
        String networkOperator = manager.getNetworkOperator();
        if (TextUtils.isEmpty(networkOperator)) {
            return;
        }
        GsmCellLocation location = (GsmCellLocation) manager.getCellLocation();
        final int mcc = Integer.parseInt(networkOperator.substring(0, 3));
        final int mnc = Integer.parseInt(networkOperator.substring(3));
        final int lac = location.getLac();
        final int cid = location.getCid();
        XLog.d(TAG, "mcc:" + mcc);
        XLog.d(TAG, "mnc:" + mnc);
        XLog.d(TAG, "lac:" + lac);
        XLog.d(TAG, "cid:" + cid);

        ThreadPoolExecutorUtil.getInstance().startThread(new Runnable() {             @Override             public void run() {                 try {                     URL url = new URL("http://api.celllocation.com:83/cell/?mcc=" + mcc + "&mnc=" + mnc + "&lac=" + lac + "&ci=" + cid + "&output=json"); XLog.d(TAG, "url:" + url.toString()); HttpURLConnection                     connection                     = (HttpURLConnection) url.openConnection();                     //Timeout                     connection.setConnectTimeout(3000);                     //Indicates that this http request is set to use the GET method                     connection.setRequestMethod("GET");                     //Return to is the response number, such as: HTTP_OK means the connection is successful.











                    int responsecode = connection.getResponseCode();
                    if (responsecode == HttpURLConnection.HTTP_OK) {
                        InputStream inputStream = connection.getInputStream();
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
                        String result = bufferedReader.readLine();
                        XLog.d(TAG, "result:" + result);
                    } else {
                        XLog.d(TAG, "result responsecode:" + responsecode);
                    }
                    connection.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取网络位置
     *
     * @param longitude
     * @param latitude
     */
    private void getNetworkAddress(final double longitude, final double latitude) {
        ThreadPoolExecutorUtil.getInstance().startThread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL("http://api.cellocation.com:83/regeo/?lat=" + latitude + "&lon=" + longitude + "&output=json");
                    XLog.d(TAG, "url:" + url.toString());
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    //超时时间
                    connection.setConnectTimeout(3000);
                    //Indicates that this http request is set to use the GET method
                    connection.setRequestMethod("GET");
                    //Return to is the response number, such as: HTTP_OK indicates that the connection is successful.
                    int responsecode = connection.getResponseCode();
                    if (responsecode == HttpURLConnection.HTTP_OK) {                         InputStream inputStream = connection.getInputStream();                         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_ 8));                         String result = bufferedReader. readLine();                         XLog.d(TAG, "result:" + result);                     } else {





                        XLog.d(TAG, "result responsecode:" + responsecode);
                    }
                    connection.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Get geographic location
     *
     * @param longitude
     * @param latitude
     * @return
     */
    private String getLocationAddr(double longitude, double latitude) {         Geocoder geocoder = new Geocoder(context, Locale.getDefault());         boolean flag = Geocoder.isPresent();         if (!flag) {             XLog.d(TAG, "Geocoding is not available");             return "";         }





// locality (address location) attribute
// and featureName (address element)
// such as country (countryName)
// zip code (postalCode)
// country code (countryCode)
// province (adminArea)
// secondary province (subAdminArea )
// secondary city (subLocality)
// road (thoroughfare) etc.;

        // getFromLocationName(): Returns a collection describing geographic location information, maxResults is the number of returned addresses, it is recommended to use 1-5;
// List<Address> addresses = geocoder.getFromLocationName("Xi'erqi", 1);
// if (addresses.size() > 0) { // // Return the current location with adjustable precision // Address address = addresses.get(0); // if (address != null) { // Log.e( "gzq", "sAddress:" + address.getLatitude()); // Log.e("gzq", "sAddress:" + address.getLongitude()); // } // }






        try {             //Return the corresponding geographical location information according to latitude and longitude, the parameter maxResults indicates the number of returned addresses, it is recommended to use 1-5;             List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);             if (addresses.size( ) == 0) {                 XLog.d(TAG, "addresses.size() == 0 return");                 return "";             }             Address address = addresses.get(0);             if (null == address) {                 XLog. d(TAG, "null == address return");                 return "";             }










            //Get the maximum address line index
            int maxAddressLineIndex = address.getMaxAddressLineIndex();
            //Cycle print the surrounding location address
            for (int i = 0; i < maxAddressLineIndex; i++) {                 String addressStr = address.getAddressLine(i);                 XLog.d (TAG, i + "addressStr:" + addressStr);             }


            StringBuilder addressBuilder = new StringBuilder();
            String addressLine = address.getAddressLine(0);
            String addressLine1 = address.getAddressLine(1);
            if (null != addressLine) {
                addressBuilder.append(addressLine);
            }
            if (null != addressLine1) {
                addressBuilder.append("靠近").append(addressLine1);
            }
            XLog.d(TAG, "addressBuilder:" + addressBuilder);
            return addressBuilder.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    public interface LocationManagerListener {         /**          * Location success data callback          */         void onSuccessLocationListener(LocationManager manager, Location location, double longitude, double latitude, String locationAddr);



        /**
         * Location failure callback
         */
        void onFailureLocationListener();
    }

    private void onSuccessListener(LocationManager manager, Location location, double longitude, double latitude, String locationAddr) {
        if (null != listener) {
            listener.onSuccessLocationListener(manager, location, longitude, latitude, locationAddr);
        }
    }

    private void onFailureListener() {
        if (null != listener) {
            listener.onFailureLocationListener();
        }
    }

}

//Call tool class:

// calling code
LocationManagerUtil.getInstance().startSingleLocation(new LocationManagerUtil.LocationManagerListener() {
    @Override
    public void onSuccessLocationListener(LocationManager manager, Location location, double longitude, double latitude, String locationAddr) {
        XLog.d(TAG, "Positioning successful");
        //This positioning time
        long time = DateTimeUtil.getInstance().getNowLongTime();
        XLog.d(TAG, "This location address address:" + locationAddr);
        XLog.d(TAG, "This positioning longitude longitude:" + longitude);
        XLog.d(TAG, "This positioning latitude latitude:" + latitude);
        XLog.d(TAG, "Time of this positioning:" + time + "-" + DateTimeUtil.getInstance().formatDateTime(time, 0));
        XLog.d(TAG, "This location.getTime() positioning time:" + location.getTime());

      
    }

    @Override
    public void onFailureLocationListener() {
        XLog.d(TAG, "Positioning failed");
    }
});

//------------------------------------------------ ---------------------------------------over---------- -------------------------------------------------- ---------------------

Guess you like

Origin blog.csdn.net/weixin_42061754/article/details/105224779