How to get Current Location using seperate class in Android

别等时光非礼了梦想. 提交于 2019-12-17 19:54:52

问题


I need to get current location using seperate class which not in the Activity. This is my code and it doesnt't work. Anyone have idea to fix this.This application is always crash when I try to get location details.

  package com.example.ishanfx.departmentapp.network;

import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;


public class LocationHandler implements LocationListener,GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    private LocationManager locationManager;
    Location mLastLocation;
    LocationRequest mLocationRequest;
    private String latitude;
    private String longitude;
    Context context;
    private static GoogleApiClient mGoogleApiClient;

    public LocationHandler(Context context) {
        this.context = context;
        locationManager = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        buildGoogleApiClient();


    }
    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(context)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();

    }
    private void setMostRecentLocation(Location lastKnownLocation) {

    }

    public String getLatitude() {
        return latitude;
    }

    public String getLongitude() {
        return longitude;
    }


    @Override
    public void onLocationChanged(Location location) {
        double lon = (double) (location.getLongitude());
        double lat = (double) (location.getLatitude());

        latitude = lat + "";
        longitude = lon + "";

    }

    /*
     * (non-Javadoc)
     *
     * @see
     * android.location.LocationListener#onProviderDisabled(java.lang.String)
     */
    @Override
    public void onProviderDisabled(String arg0) {
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     *
     * @see
     * android.location.LocationListener#onProviderEnabled(java.lang.String)
     */
    @Override
    public void onProviderEnabled(String arg0) {
        // TODO Auto-generated method stub

    }


    @Override
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onConnected(Bundle bundle) {
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        if (mLastLocation != null) {
            latitude =String.valueOf(mLastLocation.getLatitude());
            longitude = String.valueOf(mLastLocation.getLongitude());
        }

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }
}

This is the mainActivity.When I call this application will crash.

LocationHandler appLocationManager = new LocationHandler(HomeActivity.this);

                Toast.makeText(getApplicationContext(), appLocationManager.getLatitude().toString(), Toast.LENGTH_SHORT).show();
                Toast.makeText(getApplicationContext(), appLocationManager.getLongitude().toString(), Toast.LENGTH_SHORT).show();

This is the Log

FATAL EXCEPTION: main
                                                                               java.lang.NullPointerException
                                                                                   at com.example.ishanfx.departmentapp.HomeActivity.onOptionsItemSelected(HomeActivity.java:172)
                                                                                   at android.app.Activity.onMenuItemSelected(Activity.java:2502)
                                                                                   at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:361)
                                                                                   at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:147)
                                                                                   at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:100)
                                                                                   at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:100)
                                                                                   at android.support.v7.app.ToolbarActionBar$2.onMenuItemClick(ToolbarActionBar.java:68)
                                                                                   at android.support.v7.widget.Toolbar$1.onMenuItemClick(Toolbar.java:172)
                                                                                   at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:760)
                                                                                   at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:811)
                                                                                   at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
                                                                                   at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:958)
                                                                                   at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:948)
                                                                                   at android.support.v7.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java:191)
                                                                                   at android.widget.AdapterView.performItemClick(AdapterView.java:292)
                                                                                   at android.widget.AbsListView.performItemClick(AbsListView.java:1065)
                                                                                   at android.widget.AbsListView$PerformClick.run(AbsListView.java:2522)
                                                                                   at android.widget.AbsListView$1.run(AbsListView.java:3183)
                                                                                   at android.os.Handler.handleCallback(Handler.java:605)
                                                                                   at android.os.Handler.dispatchMessage(Handler.java:92)
                                                                                   at android.os.Looper.loop(Looper.java:137)
                                                                                   at android.app.ActivityThread.main(ActivityThread.java:4441)
                                                                                   at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                   at java.lang.reflect.Method.invoke(Method.java:511)
                                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
                                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
                                                                                   at dalvik.system.NativeStart.main(Native Method)

回答1:


I have updated above class in a clean way.

public class LocationHandler implements LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {
    private Context mContext;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private OnLocationUpdateListener onLocationUpdateListener;

    public LocationHandler(Context mContext) {
        this.mContext = mContext;
        buildGoogleApiClient();
        createLocationRequest();
    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(mContext)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    public void startLocationUpdates(Context mContext) {
        if (ActivityCompat.checkSelfPermission(mContext,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    }

    private void stopLocationUpdate(Context mContext) {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
    }

    //other new Methods but not using right now..
    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);//set the interval in which you want to get locations
        mLocationRequest.setFastestInterval(5000);//if a location is available sooner you can get it (i.e. another app is using the location services)
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        startLocationUpdates(mContext);
    }

    @Override
    public void onConnectionSuspended(int i) {
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    @Override
    public void onLocationChanged(Location location) {
        if(mGoogleApiClient.isConnected() && onLocationUpdateListener != null){
            onLocationUpdateListener.onLocationChange(location);
        }
    }

    public void setOnLocationUpdateListener(OnLocationUpdateListener onLocationUpdateListener) {
        this.onLocationUpdateListener = onLocationUpdateListener;
    }
}

where OnLocationUpdateListener is

public interface OnLocationUpdateListener {
    void onLocationChange(Location location);
    void onError(EnumUtil.ErrorType errorType);
}



回答2:


It takes a little time for the onConnected event to fire. You need to give it a little time before making your toasts. I'd add an isConnected property to your LocationHandler class like so:

private boolean isconnected = false;

public boolean isConnected() {
    return isconnected;
}

@Override
public void onConnected(Bundle bundle) {
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    if (mLastLocation != null) {
        latitude =String.valueOf(mLastLocation.getLatitude());
        longitude = String.valueOf(mLastLocation.getLongitude());
    }
    this.isconnected = true;
}

Then in MainActivity

LocationHandler appLocationManager = new LocationHandler(HomeActivity.this);

while(!appLocationManager.isConnected()) {
// wait for a bit
}

if (appLocationManager.isConnected()) {
    Toast.makeText(getApplicationContext(), appLocationManager.getLatitude().toString(), Toast.LENGTH_SHORT).show();
    Toast.makeText(getApplicationContext(), appLocationManager.getLongitude().toString(), Toast.LENGTH_SHORT).show();
}



回答3:


You have to set the value of latitude and longitude using setter and then get using getter.. since no value is getting set the getter is returning null value thus null pointer exception.




回答4:


Here is another solution with FusedLocationProviderClient as FusedLocationApi is deprecated.

    public class LocationHandler {
    private Activity activity;
    private FusedLocationProviderClient mFusedLocationProviderClient;
    private Location mLastKnownLocation;
    private LocationCallback mLocationCallback;
    private LocationRequest mLocationRequest;
    private OnLocationUpdateListener onLocationUpdateListener;
    private boolean updateStartedInternally = false;

    public LocationHandler(Activity activity, OnLocationUpdateListener onLocationUpdateListener) {
        this.activity = activity;
        this.onLocationUpdateListener = onLocationUpdateListener;
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(activity);
        createLocationRequest();
        getDeviceLocation();

        mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                List<Location> locationList = locationResult.getLocations();
                if (locationList.size() > 0) {
                    //The last location in the list is the newest
                    Location location = locationList.get(locationList.size() - 1);
                    mLastKnownLocation = location;
                    if (onLocationUpdateListener != null) {
                        onLocationUpdateListener.onLocationChange(location);
                        if(updateStartedInternally){
                            stopLocationUpdate();
                        }
                    }
                }
            }
        };
    }

    private void getDeviceLocation() {
        /*
         * Get the best and most recent location of the device, which may be null in rare
         * cases when a location is not available.
         */
        try {
            Task locationResult = mFusedLocationProviderClient.getLastLocation();
            locationResult.addOnCompleteListener(activity, task -> {
                if (task.isSuccessful()) {
                    // Set the map's camera position to the current location of the device.
                    mLastKnownLocation = (Location) task.getResult();
                    if (mLastKnownLocation == null) {
                        updateStartedInternally = true;
                        mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                    } else {
                        onLocationUpdateListener.onLocationChange(mLastKnownLocation);
                    }
                } else {
                    onLocationUpdateListener.onError("Can't get Location");
                }
            });
        } catch (SecurityException e) {
            Log.e("Exception: %s", e.getMessage());
            onLocationUpdateListener.onError(e.getMessage());

        }
    }

    public void startLocationUpdates() {
        if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        updateStartedInternally = false;
        mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
    }

    private void stopLocationUpdate() {
        mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
    }


    //other new Methods but not using right now..
    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);//set the interval in which you want to get locations
        mLocationRequest.setFastestInterval(5000);//if a location is available sooner you can get it (i.e. another app is using the location services)
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }
}

where OnLocationUpdateListener is

public interface OnLocationUpdateListener {
    void onLocationChange(Location location);
    void onError(String error);
}


来源:https://stackoverflow.com/questions/36436686/how-to-get-current-location-using-seperate-class-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!