代码之家  ›  专栏  ›  技术社区  ›  shivam

无法使用Google的融合位置API获取位置

  •  4
  • shivam  · 技术社区  · 9 年前

    我正在尝试使用谷歌的融合位置API获取我的位置。为此,我创建了两个类。一个是MainActivity,另一个是FusedLocationService,其中MainActivaty是主类。但我得到的经度和纬度是0.0。所以请帮助我。

    这是我的MainActivity代码:-

    public class MainActivity extends AppCompatActivity {
    
    TextView tvLocation;
    FusedLocationService fusedLocationService;
    double latitude;
    double longitude;
    
    String locationResult = "";
    Location location;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        tvLocation = (TextView) findViewById(R.id.tvLocation);
        fusedLocationService = new FusedLocationService(this);
        location = fusedLocationService.getLocation();
    
        if (null != location) {
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            locationResult = "Latitude: " + latitude + "\n" +
                    "Longitude: " + longitude + "\n";
        } else {
            Timber.e("-error-%s", "Location Not Available!");
            locationResult = "Location Not Available!";
        }
    
        Log.e("Lati ", String.valueOf(latitude));
        Log.e("longi ", String.valueOf(longitude));
        tvLocation.setText(locationResult);
       }
     }
    

    这是我的FusedLocationService类:-

    public class FusedLocationService implements LocationListener, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {
    
    private static final long INTERVAL = 1000 * 30; //30sec
    private static final long FASTEST_INTERVAL = 1000 * 5; // 5sec
    
    Activity mActivity;
    public LocationRequest locationRequest;
    public GoogleApiClient googleApiClient;
    public Location location;
    public FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
    
    public FusedLocationService(Activity activity) {
    
        Timber.plant(new Timber.DebugTree());
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(INTERVAL);
        locationRequest.setFastestInterval(FASTEST_INTERVAL);
        mActivity = activity;
        googleApiClient = new GoogleApiClient.Builder(mActivity)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
    
        if (googleApiClient != null) {
            googleApiClient.connect();
        }
    
    }
    
    @Override
    public void onConnected(Bundle connectionHint) {
        Log.e("-onConnected-", "connected now");
        location = fusedLocationProviderApi.getLastLocation(googleApiClient);
        fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this);
    }
    
    @Override
    public void onLocationChanged(Location location) {
    }
    
    public Location getLocation() {
        return location;
    }
    
    @Override
    public void onConnectionSuspended(int i) {
    }
    
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
      }
    }
    

    我在清单和gradle文件夹中的lib中包含了权限。 所以请帮忙。提前谢谢你

    3 回复  |  直到 9 年前
        1
  •  2
  •   momo    9 年前

    缺少对新位置的引用:

    @Override
    public void onLocationChanged(Location location) {
        this.location = location;
    }
    

    此外,位置更新包括 异步地 所以你需要一个 回调 到活动。

    编辑:

    还要检查Google Play Services是否可用。您可以创建如下方法:

    public boolean checkPlayServices() {
       return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS;
    }
    

    看见 Google documentation

        2
  •  1
  •   blackkara    9 年前

    简短的解释

    您正在获取全局纬度和经度变量的默认值

    double latitude;
    double longitude;
    

    冗长的解释

    实例化FusedLocationService类时

    fusedLocationService = new FusedLocationService(this);
    

    它构建谷歌api客户端,然后尝试连接

    public FusedLocationService(Activity activity) {
        ...
        googleApiClient = new GoogleApiClient.Builder(mActivity)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();
    
        if (googleApiClient != null) {
            googleApiClient.connect();
        }
    }
    

    连接成功后,发出位置请求

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.e("-onConnected-", "connected now");
        location = fusedLocationProviderApi.getLastLocation(googleApiClient);
        fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this);
    }
    

    连接googleapi和接收位置是异步操作。

    这意味着, 你必须注意他们的回复

    但是,您在初始化FusedLocationService类后使用的是经纬度变量。这就是为什么纬度和经度都是0.0。

    Log.e("Lati ", String.valueOf(latitude));
    Log.e("longi ", String.valueOf(longitude));
    tvLocation.setText(locationResult);
    

    EDIT—最后润色

    首先,您可以删除或移动这些代码。您正在处理异步操作。

    日志e(“Lati”,String.valueOf(纬度));
    日志e(“longium”,String.valueOf(经度));
    tvLocation.setText(locationResult);
    

    连接google api后,检查之前收到的位置并更新ui(如果有)

    @Override
    public void onConnected(Bundle connectionHint) {
        ...
        Location location = fusedLocationProviderApi.getLastLocation(googleApiClient);
        // Provider could return null, because it tries to get location if any 
        if(location != null){
            // UPDATE YOUR UI
        }
        fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this);
    }
    

    收到新位置后,更新您的ui

    @Override
    public void onLocationChanged(Location location) {
        // You have received fresh location
        // UPDATE YOUR UI
    }
    

    同时检查此项 link ,您将更好地理解我提到的方面。

        3
  •  0
  •   Nilesh    8 年前

    我创建了一个名为LocationActivity的类

    public class LocationActivitity extends AppCompatActivity
                implements LocationListener,
                GoogleApiClient.ConnectionCallbacks,
                GoogleApiClient.OnConnectionFailedListener {
    
            final String TAG = "GPS";
            private long UPDATE_INTERVAL = 2 * 1000;  /* 10 secs */
            private long FASTEST_INTERVAL = 2000; /* 2 sec */
            static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
    
            GoogleApiClient gac;
            LocationRequest locationRequest;
            public String tvLatitude, tvLongitude, tvTime;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
    
                isGooglePlayServicesAvailable();
    
                if(!isLocationEnabled())
                    showAlert();
    
                locationRequest = new LocationRequest();
                locationRequest.setInterval(UPDATE_INTERVAL);
                locationRequest.setFastestInterval(FASTEST_INTERVAL);
                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                gac = new GoogleApiClient.Builder(this)
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .addApi(LocationServices.API)
                        .build();
            }
    
            @Override
            protected void onStart() {
                gac.connect();
                super.onStart();
            }
    
            @Override
            protected void onStop() {
                gac.disconnect();
                super.onStop();
            }
    
            @Override
            public void onLocationChanged(Location location) {
                if (location != null) {
                    updateUI(location);
                }
            }
    
            @Override
            public void onConnected(@Nullable Bundle bundle) {
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED
                        && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    
                    return;
                }
                Log.d(TAG, "onConnected");
    
                Location ll = LocationServices.FusedLocationApi.getLastLocation(gac);
                Log.d(TAG, "LastLocation: " + (ll == null ? "NO LastLocation" : ll.toString()));
    
                LocationServices.FusedLocationApi.requestLocationUpdates(gac, locationRequest, this);
            }
    
            @Override
            public void onRequestPermissionsResult(
                    int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    
                switch (requestCode) {
                    case MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
                        // If request is cancelled, the result arrays are empty.
                        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                            Toast.makeText(this, "Permission was granted!", Toast.LENGTH_LONG).show();
    
                            try{
                                LocationServices.FusedLocationApi.requestLocationUpdates(
                                        gac, locationRequest, this);
                            } catch (SecurityException e) {
                                Toast.makeText(this, "SecurityException:\n" + e.toString(), Toast.LENGTH_LONG).show();
                            }
                        } else {
                            Toast.makeText(this, "Permission denied!", Toast.LENGTH_LONG).show();
                        }
                        return;
                    }
                }
            }
    
            @Override
            public void onConnectionSuspended(int i) {}
    
            @Override
            public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                Toast.makeText(this, "onConnectionFailed: \n" + connectionResult.toString(),
                        Toast.LENGTH_LONG).show();
                Log.d("DDD", connectionResult.toString());
            }
    
            private void updateUI(Location loc) {
                Log.d(TAG, "updateUI");
                tvLatitude=loc.getLatitude()+"";
                tvLongitude=loc.getLongitude()+"";
                //tvTime.setText(DateFormat.getTimeInstance().format(loc.getTime()));
            }
    
            private boolean isLocationEnabled() {
                LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
                        locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            }
    
            private boolean isGooglePlayServicesAvailable() {
                final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
                GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
                int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
                if (resultCode != ConnectionResult.SUCCESS) {
                    if (apiAvailability.isUserResolvableError(resultCode)) {
                        apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                                .show();
                    } else {
                        Log.d(TAG, "This device is not supported.");
                        finish();
                    }
                    return false;
                }
                Log.d(TAG, "This device is supported.");
                return true;
            }
    
            private void showAlert() {
                final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
                dialog.setTitle("Enable Location")
                        .setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
                                "use this app")
                        .setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
    
                                Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                startActivity(myIntent);
                                finish();
                            }
                        })
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                            }
                        });
                dialog.show();
            }
        }
    

    这里有一个方法updateUI(Location loc),您可以在其中获取位置。