如何使用谷歌地图 Api 获得最精确的位置 [重复]

Posted

技术标签:

【中文标题】如何使用谷歌地图 Api 获得最精确的位置 [重复]【英文标题】:How to get most precise location using google maps Api [duplicate] 【发布时间】:2020-11-28 08:09:57 【问题描述】:

我正在尝试使用谷歌地图 API 获取用户当前位置,但即使在我打开 GPS 之后,我也无法最准确地获取当前位置,尽管我没有收到任何错误。首先,我检查权限,然后检查是否启用 GPS,然后在当前位置显示标记

我的代码

    public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback 

    public static final int DEFAULT_ZOOM = 15;
    public static final int PERMISSION_REQUEST_CODE = 9001;
    private static final int PLAY_SERVICES_ERROR_CODE = 9002;
    public static final String TAG = "MyTag";
    private boolean mLocationPermissionGranted;

    private FusedLocationProviderClient mLocationClient;

    Toolbar toolbar;

    String LatitudeBack;
    String LongitudeBack;


    Double LATITUDE,LONGITUDE;
    private double Delhi_LAT = 28.630597;
    private double Delhi_LONG= 77.218978;


    private GoogleMap mGoogleMap;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        toolbar = findViewById(R.id.myToolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                finish();
            
        );


        isServicesOk();

        mLocationClient = new FusedLocationProviderClient(this);

        SupportMapFragment supportMapFragment= (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_fragment);
        assert supportMapFragment != null;
        supportMapFragment.getMapAsync(this);
    

    @Override
    public void onMapReady(GoogleMap googleMap) 

        mGoogleMap = googleMap;
    

    private void initGoogleMap() 

        if(isServicesOk())
            if (isGPSEnabled()) 
                if (checkLocationPermission()) 
                    SupportMapFragment supportMapFragment = SupportMapFragment.newInstance();

                    getCurrentLocation();
                 else 
                    requestLocationPermission();
                
            
        


    

    private void requestLocationPermission() 
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) 
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
                requestPermissions(new String[]Manifest.permission.ACCESS_FINE_LOCATION, PERMISSION_REQUEST_CODE);
            
        
    

    private void gotoLocation(double lat,double lng)

        LatLng latLng=new LatLng(lat,lng);

        CameraUpdate cameraUpdate= CameraUpdateFactory.newLatLngZoom(latLng,DEFAULT_ZOOM);

        mGoogleMap.moveCamera(cameraUpdate);
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

    

    private boolean checkLocationPermission() 

        return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED;

    

    private boolean isServicesOk() 

        GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance();

        int result= googleApi.isGooglePlayServicesAvailable(this);

        if(result == ConnectionResult.SUCCESS)
            return true;
        else if(googleApi.isUserResolvableError(result))
            Dialog dialog=googleApi.getErrorDialog(this,result,PLAY_SERVICES_ERROR_CODE, task->
                    Toast.makeText(this, "Dialog is cancelled by User", Toast.LENGTH_SHORT).show());
            dialog.show();
        else
            Toast.makeText(this, "Play services are required by this application", Toast.LENGTH_SHORT).show();
        
        return false;
    

    private void showMarker(double lat, double lng) 
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(new LatLng(lat, lng));
        mGoogleMap.addMarker(markerOptions);
    

    @Override
    public void onBackPressed() 
        super.onBackPressed();

        Intent intent =new Intent(MapsActivity.this,Upload_New_Product.class);

        startActivity(intent);
    

    private void getCurrentLocation() 

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                this, 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;
        
        mLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() 
            @Override
            public void onComplete(@NonNull Task<Location> task) 

                if (task.isSuccessful())
                
                    Location location = task.getResult();

                    assert location != null;
                    Log.d(TAG,"Map 2 , "+String.valueOf(location.getLatitude())+ location.getLongitude());

                    LATITUDE =location.getLatitude();
                    LONGITUDE =location.getLongitude();
                    gotoLocation(LATITUDE,LONGITUDE);
                    showMarker(LATITUDE,LONGITUDE);
                    //  LocationEditText.setText(MyLat+","+MyLong);
                    // geoCoder(location.getLatitude(),location.getLongitude());

                
                else
                
                    Log.d(TAG, "getCurrentLocation: Error: " + task.getException().getMessage());
                    Toast.makeText(MapsActivity.this, "Can't get Location", Toast.LENGTH_SHORT).show();
                


            
        );

    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 

        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_map, menu);


        return super.onCreateOptionsMenu(menu);


    

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) 

        if (item.getItemId() == R.id.CurrentLocation) 

            initGoogleMap();


        

        return super.onOptionsItemSelected(item);


    

    private boolean isGPSEnabled() 

        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        boolean providerEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        if (providerEnabled) 
            return true;
         else 

            AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setTitle("GPS Permissions")
                    .setMessage("GPS is required for accessing the Shop location. Please enable GPS.")
                    .setPositiveButton("OK", ((dialogInterface, i) -> 
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivityForResult(intent, GPS_REQUEST_CODE);
                    ))
                    .setCancelable(false)
                    .show();

        
        return false;
    

【问题讨论】:

您能准确定义什么适合您吗?比如多少米或者你的精度目标是什么? @MateoHervas 最精确的可以是 5 到 10 米 获取位置与谷歌地图或任何其他地图无关。 【参考方案1】:

getLastLocation() 不会激活位置更新,因此可能不会返回设备的最新位置,您必须调用 requestLocationUpdates() 并设置回调以接收最新的位置更新。

【讨论】:

其实我不想不断收到位置更新我想获取当前位置一次然后上传

以上是关于如何使用谷歌地图 Api 获得最精确的位置 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用谷歌地图 api 获取当前位置? [复制]

谷歌地图api中的Html5地理位置[重复]

如何通过经纬度确定位置 知道经纬度怎么查询实际地点?

如何在没有谷歌地图 API 的情况下在我的应用程序中获取经度和纬度?

从谷歌地图API位置搜索框的示例中获取坐标? [重复]

如何使用谷歌地图 api 获得速度限制?