Saltar al contenido

Cuadro de diálogo LocationSettingsRequest para habilitar GPS – onActivityResult () omitido

Solución:

ACTUALIZAR

La respuesta original a continuación es usar Java y el SettingsApi ahora obsoleto.

Aquí hay un enfoque más moderno usando Kotlin y SettingsClient:

override fun showEnableLocationSetting() 
    activity?.let 
        val locationRequest = LocationRequest.create()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY

        val builder = LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest)

        val task = LocationServices.getSettingsClient(it)
                .checkLocationSettings(builder.build())

        task.addOnSuccessListener  response ->
            val states = response.locationSettingsStates
            if (states.isLocationPresent) 
                //Do something
            
        
        task.addOnFailureListener  e ->
            if (e is ResolvableApiException) 
                try 
                    // Handle result in onActivityResult()
                    e.startResolutionForResult(it,
                            MainActivity.LOCATION_SETTING_REQUEST)
                 catch (sendEx: IntentSender.SendIntentException)  
            
        
    

En MainActivity, defina la constante:

companion object 
    const val LOCATION_SETTING_REQUEST = 999

RESPUESTA ORIGINAL:

Parece que el problema principal es que tiene todo el código en un Fragmento, y desde startResolutionForResult() necesita que se le pase una Actividad, la Actividad es lo que obtiene el onActivityResult() llamar de vuelta.

Una forma de evitarlo es utilizar la técnica descrita aquí, llamar manualmente al Fragmento onActivityResult() método de la Actividad cuando llegue el resultado.

Acabo de hacer funcionar este sencillo ejemplo.

Primero, la Actividad, que agrega el Fragmento, y también tiene funcionalidad para transmitir el resultado de onActivityResult() al Fragmento:

public class MainActivity extends AppCompatActivity

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

        lFrag = LocationFragment.newInstance();
        getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, lFrag).commit();

    

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
        if (requestCode == LocationFragment.REQUEST_LOCATION)
            lFrag.onActivityResult(requestCode, resultCode, data);
        
        else 
            super.onActivityResult(requestCode, resultCode, data);
        
    

Aquí está el Fragmento, que contiene toda la funcionalidad para mostrar el diálogo y manejar el resultado. En este ejemplo simple, solo utilicé mensajes de Toast para verificar que funciona como se esperaba. Tenga en cuenta que el cambio principal que hice aquí desde el código de su pregunta es el uso de getActivity() para obtener la referencia de actividad necesaria para la llamada a startResolutionForResult().

public class LocationFragment extends Fragment
        implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener 


    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    PendingResult result;
    final static int REQUEST_LOCATION = 199;

    public static LocationFragment newInstance() 
        LocationFragment fragment = new LocationFragment();
        return fragment;
    

    public LocationFragment() 
        // Required empty public constructor
    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 

        mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();
        mGoogleApiClient.connect();

        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_location, container, false);
    


    @Override
    public void onResume() 
        super.onResume();
    

    @Override
    public void onConnected(Bundle bundle) 

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(30 * 1000);
        mLocationRequest.setFastestInterval(5 * 1000);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(mLocationRequest);
        builder.setAlwaysShow(true);

        result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

        result.setResultCallback(new ResultCallback() 
            @Override
            public void onResult(LocationSettingsResult result) 
                final Status status = result.getStatus();
                //final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) 
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        //...
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try 
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(
                                    getActivity(),
                                    REQUEST_LOCATION);
                         catch (IntentSender.SendIntentException e) 
                            // Ignore the error.
                        
                        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.
                        //...
                        break;
                
            
        );

    

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    
        Log.d("onActivityResult()", Integer.toString(resultCode));

        //final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode)
        
            case REQUEST_LOCATION:
                switch (resultCode)
                
                    case Activity.RESULT_OK:
                    
                        // All required changes were successfully made
                        Toast.makeText(getActivity(), "Location enabled by user!", Toast.LENGTH_LONG).show();
                        break;
                    
                    case Activity.RESULT_CANCELED:
                    
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(getActivity(), "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
                        break;
                    
                    default:
                    
                        break;
                    
                
                break;
        
    

    @Override
    public void onConnectionSuspended(int i) 

    

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) 

    


Estos son los resultados visualmente, primero se muestra el cuadro de diálogo si el Modo de ubicación está deshabilitado:

ingrese la descripción de la imagen aquí

Luego, si el usuario hace clic en No, el resultado se pasa de la Actividad al Fragmento, que muestra un brindis:

ingrese la descripción de la imagen aquí

Lo mismo ocurre cuando el usuario hace clic en Sí, pero con un resultado exitoso, y el Modo de ubicación está habilitado:

ingrese la descripción de la imagen aquí

Tenga en cuenta que podría ser una mejor opción simplemente mantener toda esta funcionalidad en la Actividad y luego llamar a un método público en el Fragmento cuando llegue el resultado.

Aquí hay un código completamente funcional para mantener la funcionalidad en la Actividad. Por supuesto, en esta solución, necesitaría agregar una llamada al Fragmento para actualizar el estado del Modo de ubicación después onActivityResult() se llama.

public class MainActivity extends AppCompatActivity
        implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener 


    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    PendingResult result;
    final static int REQUEST_LOCATION = 199;

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

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();
        mGoogleApiClient.connect();

    

    @Override
    public void onConnected(Bundle bundle) 

        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(30 * 1000);
        mLocationRequest.setFastestInterval(5 * 1000);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(mLocationRequest);
        builder.setAlwaysShow(true);

        result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

        result.setResultCallback(new ResultCallback() 
            @Override
            public void onResult(LocationSettingsResult result) 
                final Status status = result.getStatus();
                //final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) 
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        //...
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try 
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(
                                    MainActivity.this,
                                    REQUEST_LOCATION);
                         catch (SendIntentException e) 
                            // Ignore the error.
                        
                        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.
                        //...
                        break;
                
            
        );

    

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    
        Log.d("onActivityResult()", Integer.toString(resultCode));

        //final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode)
        
            case REQUEST_LOCATION:
                switch (resultCode)
                
                    case Activity.RESULT_OK:
                    
                        // All required changes were successfully made
                        Toast.makeText(MainActivity.this, "Location enabled by user!", Toast.LENGTH_LONG).show();
                        break;
                    
                    case Activity.RESULT_CANCELED:
                    
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(MainActivity.this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
                        break;
                    
                    default:
                    
                        break;
                    
                
                break;
        
    

    @Override
    public void onConnectionSuspended(int i) 

    

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) 

    

Debe agregar esto a su devolución de llamada de resultado:

case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
    try 
        fragment.startIntentSenderForResult(status.getResolution().getIntentSender(), REQUEST_CHECK_SETTINGS, null, 0, 0, 0, null);
     catch (IntentSender.SendIntentException e) 
        // Ignore the error.
    
    break;

onActivityResult se llamará en su fragmento, no necesita llamarlo manualmente en su actividad. Esto es esencialmente como startResolutionForResult obras.

Si desea que los resultados vuelvan a su fragmento, utilice

startIntentSenderForResult(status.getResolution().getIntentSender(), REQUEST_CODE_LOCATION_SETTING, null, 0, 0, 0, null);

en lugar de status.startResolutionForResult(YourActivity, LOCATION_REQUEST);

UTILIZAR el método anterior devolverá el resultado solo a su fragmento.

Si entiendes que te ha resultado de ayuda este post, sería de mucha ayuda si lo compartes con el resto programadores de esta manera contrubuyes a difundir este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *