Android Hybrid 定时推送经纬度到服务器

之前项目有个需求,就是APP端隔几秒实时推送经纬度到服务器,最先APP是用MUI的方式实现的,因此在MUI的基础上折腾了一番,但是因为所有的业务都只能在前台UI线程里跑,因此推送经纬度的程序总是死掉,APP的运行效果也并不能让人满意,于是考虑将这个APP转为Hybrid APP。

目前我们WEB端用的是百度地图做的轨迹渲染,因此APP端也推送的百度经纬度,获取到本地GPS经纬度后需要进行转换,下面我把那两个工具类分享出来。

如果有疑问,欢迎在下方留言交流!!!

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.widget.Toast;
import java.util.List;
import cdyy.etap.Config;
import cdyy.etap.other.DbHelper;
import cdyy.etap.other.HttpUtil;
import cdyy.etap.other.PtConvert;

/**
 * 经纬度获取推送工具类
 */
public class LocationUtil {

    private static final String TAG = "【LocationUtils】";

    private volatile static LocationUtil localClient;
    private LocationManager locationManager;
    private String locationProvider;
    private Location location;

    private LocationUtil(Context context) {
        getLocation();
    }

    //采用Double CheckLock(DCL)实现单例
    public static LocationUtil getInstance(Context context) {
        if (localClient == null) {
            synchronized (LocationUtil.class) {
                if (localClient == null) {
                    localClient = new LocationUtil( context );
                }
            }
        }
        return localClient;
    }

    private void getLocation() {
        //1.获取位置管理器
        locationManager = (LocationManager) mContext.getSystemService( Context.LOCATION_SERVICE );
        //2.获取位置提供器,GPS或是NetWork
        List<String> providers = locationManager.getProviders( true );

        if (providers.contains( LocationManager.GPS_PROVIDER )) {
            //如果是GPS定位
            Log.w( TAG,"本应用采取GPS定位");
            locationProvider = LocationManager.GPS_PROVIDER;
        } else if (providers.contains( LocationManager.NETWORK_PROVIDER )) {
            //如果是网络定位
            Log.w(TAG,"本应用使用网络定位");
            locationProvider = LocationManager.NETWORK_PROVIDER;
        } else {
            Log.w( TAG,"没有位置提供器" );
            return;
        }

        // 需要检查权限,否则编译报错,想抽取成方法都不行,还是会报错。只能这样重复 code 了。
        if (Build.VERSION.SDK_INT >= 23 &&
                ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        //3.获取上次的位置,一般第一次运行,此值为null
        Location location = locationManager.getLastKnownLocation( locationProvider );
        if (location != null) {
            setLocation( location );
        }
        // 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
        locationManager.requestLocationUpdates( locationProvider, Config.minTime, Config.minDistance, locationListener );
    }

    /**给后台传递当前救护车经纬度*/
    private void setLocation(Location location) {

        this.location = location;
        Log.d(TAG,"经纬度推送-------------------------------------------------------------------------------------------------------------------------->");
        Log.i(TAG, "从安卓获取到的GPS:经度:" + location.getLongitude() + "纬度:" + location.getLatitude() );

        //经纬度GPS转换为百度经纬度
        double[] jwd = PtConvert.wgs2bd(location.getLatitude(),location.getLongitude());
        double latitude = jwd[0]; //纬度
        double longitude = jwd[1]; //经度
        Log.i( TAG, "通过函数转换后的经度:"+longitude+",纬度"+latitude );

        new Thread(){
            public void run(){
            // 在此处执行经纬度的推送,可以使用http或者socket等方式推送到服务器...
            }
        }.start();

    }

    // 移除定位监听 !
    public void removeLocationUpdatesListener() {
        // 需要检查权限,否则编译不过
        if (Build.VERSION.SDK_INT >= 23 &&
                ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
                ActivityCompat.checkSelfPermission( mContext, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        if (locationManager != null) {
            localClient = null;
            locationManager.removeUpdates( locationListener );
        }
    }

    /**
     * LocationListern监听器
     * 参数:地理位置提供器、监听位置变化的时间间隔、位置变化的距离间隔、LocationListener监听器
     */

    LocationListener locationListener = new LocationListener() {

        //当某个位置提供者的状态发生改变时
        @Override
        public void onStatusChanged(String provider, int status, Bundle arg2) {

        }

        //某个设备打开时
        @Override
        public void onProviderEnabled(String provider) {

        }

        //某个设备关闭时
        @Override
        public void onProviderDisabled(String provider) {

        }

        //手机位置发生变动
        @Override
        public void onLocationChanged(Location location) {
            location.getAccuracy();//精确度
            //Log.d("精度值:",String.valueOf(location.getAccuracy()));
            setLocation( location );
        }
    };
}
/**
 * 坐标转换类
 */
public class PtConvert {

    static double pi = 3.14159265358979324;
    static double a = 6378245.0;
    static double ee = 0.00669342162296594323;
    public final static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;

    //GPS坐标转百度
    public static double[] wgs2bd(double lat, double lon) {
        double[] wgs2gcj = wgs2gcj(lat, lon);
        double[] gcj2bd = gcj2bd(wgs2gcj[0], wgs2gcj[1]);
        return gcj2bd;
    }

    public static double[] gcj2bd(double lat, double lon) {
        double x = lon, y = lat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
        double bd_lon = z * Math.cos(theta) + 0.0065;
        double bd_lat = z * Math.sin(theta) + 0.006;
        return new double[] { bd_lat, bd_lon };
    }

    public static double[] bd2gcj(double lat, double lon) {
        double x = lon - 0.0065, y = lat - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
        double gg_lon = z * Math.cos(theta);
        double gg_lat = z * Math.sin(theta);
        return new double[] { gg_lat, gg_lon };
    }

    public static double[] wgs2gcj(double lat, double lon) {
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        double[] loc = { mgLat, mgLon };
        return loc;
    }

    private static double transformLat(double lat, double lon) {
        double ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * Math.sqrt(Math.abs(lat));
        ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lon * pi) + 40.0 * Math.sin(lon / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(lon / 12.0 * pi) + 320 * Math.sin(lon * pi  / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    private static double transformLon(double lat, double lon) {
        double ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * Math.sqrt(Math.abs(lat));
        ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(lat / 12.0 * pi) + 300.0 * Math.sin(lat / 30.0 * pi)) * 2.0 / 3.0;
        return ret;
    }

}

275 Clicks !

发表评论

电子邮件地址不会被公开。