Cómo solicitar permiso de ubicación en tiempo de ejecución en Android 6

En el archivo de manifiesto agregué permisos groseros y finos, y cuando corro en el dispositivo con Android 6, ¡no pasa nada! Intento todo, pero no hay forma de obtener actualizaciones de ubicación …

¿Qué estoy haciendo mal?

public class MainActivity extends AppCompatActivity implements LocationListener { LocationManager locationManager; String provider; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); provider = locationManager.getBestProvider(new Criteria(), false); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } Location location = locationManager.getLastKnownLocation(provider); if (location != null) { Log.i("Location Info", "Location achieved!"); } else { Log.i("Location Info", "No location :("); } } @Override protected void onResume() { super.onResume(); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } locationManager.requestLocationUpdates(provider, 400, 1, this); } @Override protected void onPause() { super.onPause(); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } locationManager.removeUpdates(this); } @Override public void onLocationChanged(Location location) { Double lat = location.getLatitude(); Double lng = location.getLongitude(); Log.i("Location info: Lat", lat.toString()); Log.i("Location info: Lng", lng.toString()); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } public void getLocation(View view) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } Location location = locationManager.getLastKnownLocation(provider); onLocationChanged(location); } } 

En realidad, debe solicitar el permiso de Ubicación en tiempo de ejecución (observe los comentarios en su código que indican esto).

Aquí está el código probado y de trabajo para solicitar el permiso de Ubicación.

Asegúrese de importar android.Manifest :

 import android.Manifest; 

Luego ponga este código en la Actividad:

 public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; public boolean checkLocationPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. new AlertDialog.Builder(this) .setTitle(R.string.title_location_permission) .setMessage(R.string.text_location_permission) .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //Prompt the user once explanation has been shown ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION); } }) .create() .show(); } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION); } return false; } else { return true; } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_LOCATION: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // location-related task you need to do. if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { //Request location updates: locationManager.requestLocationUpdates(provider, 400, 1, this); } } else { // permission denied, boo! Disable the // functionality that depends on this permission. } return; } } } 

Luego llame al método onCreate() en onCreate() :

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

Luego puede usar onResume() y onPause() exactamente como está en la pregunta.

Aquí hay una versión condensada que es un poco más limpia:

 @Override protected void onResume() { super.onResume(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { locationManager.requestLocationUpdates(provider, 400, 1, this); } } @Override protected void onPause() { super.onPause(); if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { locationManager.removeUpdates(this); } } 

Me gusta el código corto. Yo uso RxPermission para los permisos.

Primero agregue estos permisos (o uno que necesite) en su manifest.xml .

   

Luego pida permiso de tiempo de ejecución del usuario en su actividad.

 RxPermissions rxPermissions = new RxPermissions(this); rxPermissions .request(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION) // ask single or multiple permission once .subscribe(granted -> { if (granted) { // All requested permissions are granted } else { // At least one permission is denied } }); 

agregue esta biblioteca en su build.gradle

 allprojects { repositories { ... maven { url 'https://jitpack.io' } } } dependencies { implementation 'com.github.tbruyelle:rxpermissions:0.10.1' implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1' } 

¿No es esto fácil?

Google ha creado una biblioteca para facilitar la administración de permisos. Se llama EasyPermissions

Aquí hay un ejemplo simple al solicitar el permiso de Ubicación usando esta biblioteca.

 public class MainActivity extends AppCompatActivity { private final int REQUEST_LOCATION_PERMISSION = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestLocationPermission(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } @AfterPermissionGranted(REQUEST_LOCATION_PERMISSION) public void requestLocationPermission() { String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION}; if(EasyPermissions.hasPermissions(this, perms)) { Toast.makeText(this, "Permission already granted", Toast.LENGTH_SHORT).show(); } else { EasyPermissions.requestPermissions(this, "Please grant the location permission", REQUEST_LOCATION_PERMISSION, perms); } } } 

@AfterPermissionsGranted(REQUEST_CODE) se utiliza para indicar el método que debe ejecutarse después de una solicitud de permiso con el código de solicitud REQUEST_CODE .

En este caso, se requestLocationPermission() el método método requestLocationPermission() si el usuario concede el permiso para acceder a servicios de ubicación. Entonces, ese método actúa como una callback y un método para solicitar los permisos.

Puede implementar devoluciones de llamada independientes para permisos otorgados y permisos denegados también. Se explica en la página de github.