How to get Current Location using seperate class in Android
Asked Answered
Y

4

2

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)
Yearly answered 5/4, 2016 at 20:44 Comment(5)
What is the Logcat output?Shay
Nullpointer Exception @ShayYearly
Put the whole logs in your question. Here is a link answering what a NullPointerException is, https://mcmap.net/q/17345/-what-is-a-nullpointerexception-and-how-do-i-fix-it/1478764Shay
Read the logs, the first line states: java.lang.NullPointerException at com.example.ishanfx.departmentapp.HomeActivity.onOptionsItemSelected(HomeActivity.java:172) which tells you the problem you are facing is in your HomeActivity class line 172. Refer to the link I posted in a previous comment for what a NullPointerException is.Shay
I think you have import android.location.LocationListener; which is wrong.use fusedApi locationListener like import com.google.android.gms.location.LocationListener;Heyday
H
2

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);
}
Heyday answered 1/2, 2017 at 13:40 Comment(1)
Yes it require's a context . simply pass service context to it. and you are good to goHeyday
F
1

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();
}
Firooc answered 5/4, 2016 at 21:9 Comment(2)
It freeze the App.Yearly
create an interface(callback ) and when connected it returns . appLocationManager .setOnConnectedListener(new OnConnected(){})Heyday
P
0

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.

Perjure answered 2/7, 2018 at 11:47 Comment(0)
F
0

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);
}
Fleshy answered 3/4, 2019 at 15:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.