2017-07-10 4 views
0

Je travaille sur une application qui trouve la position de l'utilisateur et localise près des points d'accès et de la zone de signal.Numéro OnLocationChanged

Lorsque je demande manuellement des mises à jour de localisation via le bouton, il n'appelle pas la fonction de rappel.

Ceci est mon activité:

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; 
} 

}

Fondamentalement, lorsque l'utilisateur appuie sur le bouton d'explorer l'application doit localiser l'utilisateur et lui montrer sur la carte.

Voici le logcat:

/Debugging MainActivity :: réseau

/Debugging MainActivity :: onMapReady

/contrôleur Debugging :: position définie

/Debugging MainActivity :: manuel demande de mise à jour

et le/Debugging MainActivity :: onLocationChanged n'apparaît jamais.

J'ai également essayé d'utiliser une variable comme LocationListener, cela ne fonctionne pas. Et oui, mes autorisations dans le manifeste sont très bien. Je ne comprends vraiment pas ce que je fais de mal.

+0

Il me semble que vous utilisez la «vieille» approche et non fusionné mises à jour de localisation. Pas que cela ne devrait pas fonctionner encore, mais pouvez-vous essayer cette bibliothèque: https://github.com/mcharmas/Android-ReactiveLocation? Aussi, si votre targetSdk est supérieur à 23, vous devez configurer les permissions d'exécution – cYrixmorten

+0

Il y a aussi de grandes librairies pour ça, juste fyi :) – cYrixmorten

+0

Oui j'ai oublié de mentionner que j'ai une "splash_activity" qui demande les permissions. Je vais essayer d'utiliser le fusedLocation, car c'est pour un examen scolaire et j'ai besoin d'expliquer en théorie ce qui se passe dans mon code. Merci pour le conseil –

Répondre

0

Étant donné que la carte a été chargée de manière asynchrone, demander de faire des choses dans la méthode onMapReady() était trop tôt.

Le remplacement de l'approche LocationManager par l'approche FusedLocation me permet d'attendre qu'une connexion soit établie, puis de calculer.