1

У меня есть приложение, которое получает текущее местоположение пользователей, а затем загружает карту Google и отображает маркеры, представляющие интерес в их районе. Он работает безупречно на всем, что находится ниже Зефира. Я добавил проверку разрешений во время выполнения, и они устанавливаются по мере того, как я получаю приглашение, и после того, как я нажал кнопку «Принять», я вижу разрешение, указанное в описании приложения, в настройках телефона. Тем не менее, я не могу за всю жизнь понять, почему я не возвращаюсь назад.Android Marshmallow getLastLocationLocation/LocationListeners не работает

Я использую пример, как показано здесь https://developer.android.com/training/location/retrieve-current.html

Я все разрешения, установленные с тегом в манифесте. У меня даже есть Fragment, реализующий LocationListener. Однако метод onLocationChanged никогда не вызван. Я зову его в методе onConnected от клиента API Google, как показано ниже ..

@Override 
    public void onConnected(@Nullable Bundle bundle) { 
     try { 
      Log.d("MYAPPTAG","isConnected: " + mGoogleApiClient.isConnected()); 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
      myLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     } catch (SecurityException ex) { 
      myLocation = null; 
     } 
    } 

onConnected метод не дозвонились, потому что я получаю свой лог в консоль. Однако myLocation всегда имеет значение null. Я получаю сообщение в консоли каждый раз я называю getLastLocation, что говорит

No Location to return for getLastLocation() 
GoogleSignatureVerifier: com.myappname.android signature not valid. Found: LONG KEY HERE 

Есть ли что-то особенное, что нужно сделать в Зефир?

мой метод OnLocationChanged

@Override 
    public void onLocationChanged(Location location) { 
     myLocation = location; 
     Log.d("MYAPPTAG", "LocatinChngListner, loc: " + location.getLatitude() + "," + location.getLongitude());  
    } 

AndroidManifest.xml - права раздела (выше узла)

<!--- App permissions --> 
    <permission android:name="com.myappname.android.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> 
    <uses-permission android:name="com.myappname.android.permission.MAPS_RECEIVE"/> 
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/> 
    <uses-permission android:name="android.permission.CALL_PHONE"/> 
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> 
    <uses-permission android:name="android.permission.WRITE_CONTACTS" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 

    <permission android:name="com.myappname.android.permission.C2D_MESSAGE" android:protectionLevel="signature" /> 
    <uses-permission android:name="com.myappname.android.permission.C2D_MESSAGE"/> 

OnCreate Метод фрагмент

createLocationRequest(); 
     if (mGoogleApiClient == null) { 
      mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     } 

createLocationRequest метод

private void createLocationRequest(){ 
     mLocationRequest = LocationRequest.create(); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setInterval(5000); 
     mLocationRequest.setFastestInterval(1000); 
    } 

OnStart() OnStop() методы

@Override 
public void onStart() { 
     if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect(); 
     super.onStart(); 
    } 

@Override  
public void onStop() { 
     if (mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect(); 
     super.onStop(); 
    } 

Я называю этот код ниже сразу после метода Фрагмент OnCreate

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1 && (ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { 
      requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_PERMISSION_USER_LOCATION); 
     } else { 
      googleMapsLocationPermissionContainer.setVisibility(View.GONE); 
      getUserLocationAndInitializeMap(); 
     } 

googleMapsLocationPermissionContainer является просто макет, который я накладываю на карту, пока не будут предоставлены разрешения.

getUserLocationAndInitializeMap()

try { 
       MapsInitializer.initialize(getActivity()); 
       // Set reference for map object 
       if (map == null) { 
        mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map); 
        mapFragment.getMapAsync(this); 
// Here I set the map to invisible then after I plot all the markers I set it to visible again 

        mapFragment.getView().setVisibility(View.INVISIBLE); 
       } 
      } catch (Exception e) { 
       // Show the google maps alert dialog 
       showGoogleMapsErrorDialog(); 
      } 
+0

Показать больше кода. Я делаю приложение с местоположением и отлично работает на 6.0. Моя первоначальная догадка заключается в том, что вам нужны разрешения манифеста для android 6.0. В Android-23 это совсем другое дело. –

+0

@AndreiT - какие разрешения явных в 23+? – Phil

+0

Что-то вроде этого: https://developer.android.com/training/permissions/requesting.html. У меня также было все, и в Android-6 он просто не работал, потому что мне не хватало разрешений и т. Д. –

ответ

1

Мой подход для этого является следующее:

@Override 
public void onResume() { 
    super.onResume(); 
    initGpsTracker(); 
} 

public synchronized void initGpsTracker() { 
    if (mMap != null) { 
     try { 
      checkIfPermissionAllowedForLocation(); 
     } catch (SecurityException secex) { 
      Toast.makeText(getActivity(), "not enabled in manifest", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

/** 
* rule is the following. First we check if the permissions are there. If not, we check if we can enable or not. 
* If the permissions are check if gps is enabled. 
*/ 
private void checkIfPermissionAllowedForLocation() { 

    //if permissions are set then we go to else, check for gps 
    if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     // Request missing location permission. 
     if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) { 
      askIfToRequestPermissions(); 
     } else { 
      requestPermissions(); 
     } 
    } else { 
     // Location permission has been granted, continue as usual. 
     if (!isGpsProviderEnabled()) { 
      askToEnableGPS(); 
     } else { 
      mMap.setMyLocationEnabled(true); 
     } 
    } 
} 


private void askToEnableGPS() { 
    CustomFragmentDialog customFragmentDialog = CustomFragmentDialog.newInstance(getString(R.string.enable_gps_title), 
      getString(R.string.enable_gps_message), 
      getString(R.string.ok), 
      getString(R.string.cancel), 
      callback); 
    customFragmentDialog.show(getFragmentManager(), CUSTOM_TAG); 
} 

private void requestPermissions() { 
    ActivityCompat.requestPermissions(getActivity(), 
      new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
      REQUEST_CODE_LOCATION); 
} 

private void enableGPS() { 
    if (enableLocationService != null) { 
     enableLocationService.askToEnableGps(locationCallback); 
    } 
} 

private GoogleAskToEnableLocationService.GpsCallback locationCallback = new GoogleAskToEnableLocationService.GpsCallback() { 
    @Override 
    public void onSuccess() { 
     initGpsTracker(); 
    } 

    @Override 
    public void onResolutionRequired(Status status) { 
     try { 
      status.startResolutionForResult(getActivity(), CONNECTION_RESOLUTION_CODE); 
     } catch (IntentSender.SendIntentException setex) { 
      Toast.makeText(getActivity(), "Exception in sending intent:", Toast.LENGTH_SHORT).show(); 
     } 
    } 

    @Override 
    public void onError() { 
     Toast.makeText(getActivity(), "Location services unavailable!", Toast.LENGTH_SHORT).show(); 
    } 
}; 

private void askIfToRequestPermissions() { 
    CustomFragmentDialog customFragmentDialog = CustomFragmentDialog.newInstance(getString(R.string.enable_gps_title), 
      getString(R.string.enable_permissions_message), 
      getString(R.string.ok), 
      getString(R.string.cancel), 
      callback_permissions); 
    customFragmentDialog.show(getFragmentManager(), CUSTOM_TAG); 
} 

private CustomFragmentDialog.Callback callback = new CustomFragmentDialog.Callback() { 
    @Override 
    public void onPositiveButtonClicked(Bundle bundle) { 
     enableGPS(); 
    } 

    @Override 
    public void onNegativeButtonClicked(Bundle bundle) { 

    } 
}; 


private CustomFragmentDialog.Callback callback_permissions = new CustomFragmentDialog.Callback() { 
    @Override 
    public void onPositiveButtonClicked(Bundle bundle) { 
     requestPermissions(); 
    } 

    @Override 
    public void onNegativeButtonClicked(Bundle bundle) { 

    } 
}; 

private boolean isGpsProviderEnabled() { 
    return googleUtils.isGpsProviderEnabled(); 
} 
//inside it is a normal check if locationManager can access 
//the gps provider 
    if (locationManager.getProvider(provider) == null) { 
     return false; 
    } 

Теперь для разрешения запроса есть некоторые обратные вызовы:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
     case CONNECTION_RESOLUTION_CODE: 
      switch (resultCode) { 
       case Activity.RESULT_OK: 
        initGpsTracker(); 
        break; 
       case Activity.RESULT_CANCELED: 
        Toast.makeText(getContext(), "Gps not enabled:", Toast.LENGTH_SHORT).show(); 
        break; 
       default: 
        break; 
      } 
      break; 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    if (requestCode == REQUEST_CODE_LOCATION) { 
     if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      initGpsTracker(); 
     } else { 
      Toast.makeText(getActivity(), "Manifest permission, not enabled", Toast.LENGTH_SHORT).show(); 

     } 
    } 
} 

Теперь, наконец, класс, где вы имеете дело с просьбой о местоположении, так что вам не придется идти в настройки:

public void askToEnableGps(final GpsCallback callback) { 
    if (locationClient == null) { 
     return; 
    } 
    mLocationRequestHighAccuracy = LocationRequest.create(); 
    mLocationRequestHighAccuracy.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    mLocationRequestHighAccuracy.setInterval(30 * 1000); 
    mLocationRequestHighAccuracy.setFastestInterval(5 * 1000); 
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() 
      .addLocationRequest(mLocationRequestHighAccuracy); 
    builder.setAlwaysShow(true); 
    PendingResult<LocationSettingsResult> result = 
      LocationServices.SettingsApi.checkLocationSettings(locationClient, builder.build()); 

    result.setResultCallback(getResultCallback(callback)); 
} 

private ResultCallback<LocationSettingsResult> getResultCallback(final GpsCallback callback) { 

    return new ResultCallback<LocationSettingsResult>() { 
     @Override 
     public void onResult(LocationSettingsResult result) { 
      if (result != null) { 
       final Status status = result.getStatus(); 
       if (callback != null) { 
        //final LocationSettingsStates statesResult = result.getLocationSettingsStates(); 
        switch (status.getStatusCode()) { 
         case LocationSettingsStatusCodes.SUCCESS: 
          // All location settings are satisfied. The client can initialize location 
          // requests here. 
          callback.onSuccess(); 
          break; 
         case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: 
          // Location settings are not satisfied. But could be fixed by showing the user 
          // a dialog. 
          callback.onResolutionRequired(status); 
          break; 
         case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: 
          // Location settings are not satisfied. However, we have no way to fix the 
          // settings so we won't show the dialog. 
          callback.onError(); 
          break; 
        } 
       } 
      } 
     } 
    }; 
} 

public interface GpsCallback { 
    /** 
    * callback method for when the result it is a success. 
    */ 
    void onSuccess(); 

    /** 
    * callback for when user interaction it is required. 
    * 
    * @param status the result from the service needed for the resolution. 
    */ 
    void onResolutionRequired(Status status); 

    /** 
    * Callback for when the change it is not possible. 
    */ 
    void onError(); 
} 
+0

Сообщите мне, если это сработает для вас. Я по-прежнему уточняю этот код, поэтому у него могут быть некоторые ошибки внутри, извините за это. –

+0

Весь приведенный выше код можно найти здесь: https://github.com/toaderandrei/live_tracking –

+1

Ваша помощь с благодарностью. В результате я пересмотрел некоторые из моих кодов, посмотрев на ваш пример. Основная проблема, если вы используете эмулятор в Android Studio - убедитесь, что вы нажмете SEND на странице настроек GPS, иначе устройство никогда не получит GPS-координаты. – Phil

Смежные вопросы