OnLocationChanged issue

148 Views Asked by At

I'm working on an app that finds user's position and locates near access points and signal area.

When I'm manually requesting location updates via button it just doesn't calls the callback function.

This is my activity:

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener, OnMapReadyCallback, LocationListener{

//LOG tag
private static final String LOG = MainActivity.class.getSimpleName();
private static final String DEBUG = "Debugging MainActivity:";
private static final String TEST = "Test";
private static final float ZOOM_LEVEL = 15.5f;
//The map
private GoogleMap mGmap;
private LocationManager mLocationManager;
private Location mLocation;
private WifiManager mWifiManager;
private BroadcastReceiver mBroadcastReceiver;
private List<ScanResult> mResultList;
private String mProvider;
private Criteria mCriteria;
//Controller
private AccessPointController mController;

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

    //Toolbar
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    mController = new AccessPointController();

    startReceivingLocationUpdates();
    mCriteria = new Criteria();
    mCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
    mCriteria.setPowerRequirement(Criteria.POWER_MEDIUM);
    mProvider = mLocationManager.getBestProvider(mCriteria, false);
    Log.i(DEBUG, mProvider);
    mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent intent) {
            if(intent.getAction() == WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) {
                mResultList = mWifiManager.getScanResults();
                mController.setApList(mResultList);
            }
        }
    };

    mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    registerReceiver(mBroadcastReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    mWifiManager.startScan();

    //Map handling
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

private void startReceivingLocationUpdates() {
    if(mLocationManager == null) {
        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    }
}

@Override
public void onLocationChanged(Location location) {
    Log.i(DEBUG, "onLocationChanged");
    mLocation = new Location(location);
    mController.setCurrentPosition(mLocation);
    Log.i(DEBUG, "setted new position");
    mController.showOnMap(mGmap);
    mGmap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLocation.getLatitude(), mLocation.getLongitude()), ZOOM_LEVEL));
}

@Override
protected void onResume() {
    super.onResume();
    try {
        mLocationManager.requestSingleUpdate(mProvider, this, null);
    } catch(SecurityException e) {
        System.out.println("OnResume Error: " + e.getMessage());
    }
}

@Override
protected void onPause() {
    super.onPause();
    mLocationManager.removeUpdates(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    Log.i(DEBUG, "onMapReady");
    mGmap = googleMap;
    try {
        mLocation = mLocationManager.getLastKnownLocation(mProvider);
        mController.setCurrentPosition(mLocation);
    } catch(SecurityException e) {
        e.printStackTrace();
    }
    mGmap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLocation.getLatitude(), mLocation.getLongitude()), ZOOM_LEVEL));
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_explore) {
        try {
            if(mLocationManager != null) {
                try {
                    Log.i(DEBUG, "manual update request");
                    mLocationManager.requestSingleUpdate(mProvider, this, null);
                } catch (SecurityException e) {
                    Toast.makeText(this, "Failed to request location updates, ignore: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                } catch (IllegalArgumentException e) {
                    Toast.makeText(this, "Provider does not exist: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    } else if (id == R.id.nav_open_networks) {
        Toast.makeText(this, "Open network pressed", Toast.LENGTH_SHORT).show();

    } else if (id == R.id.nav_closed_networks) {
        Toast.makeText(this, "Closed network pressed", Toast.LENGTH_SHORT).show();
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

}

Basically when the user presses the explore button the app should locate the user and show him on the map.

Here is the logcat:

/Debugging MainActivity:: network

/Debugging MainActivity:: onMapReady

/Debugging controller:: set position

/Debugging MainActivity:: manual update request

and the /Debugging MainActivity:: onLocationChanged never shows up.

I tried also to use a variable as a LocationListener, it does not work. And yes, my permissions in the manifest are fine.

I really don't understand what I'm doing wrong.

1

There are 1 best solutions below

0
On

Since the map was loaded asynchronously, asking to do stuff in the onMapReady() method was too early.

Replacing the LocationManager approach with the FusedLocation approach allows me to wait until a connection is established and then calculate.