ubicacion tiempo studio real partir obtener gratis google geolocalizacion direccion crear coordenadas app activar java android

java - studio - Cómo solicitar permiso de ubicación en tiempo de ejecución



obtener ubicacion android studio 2018 (5)

En el archivo de manifiesto agregué permisos gruesos y finos, y cuando ejecuto 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 lo indican).

Aquí se prueba y funciona el código 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); } }


Este código me funciona. También manejé el caso "Nunca me preguntes"

En AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

En build.gradle (Módulo: aplicación)

dependencies { .... implementation "com.google.android.gms:play-services-location:16.0.0" }

Este es CurrentLocationManager.kt

import android.Manifest import android.app.Activity import android.content.Context import android.content.IntentSender import android.content.pm.PackageManager import android.location.Location import android.location.LocationListener import android.location.LocationManager import android.os.Bundle import android.os.CountDownTimer import android.support.v4.app.ActivityCompat import android.support.v4.content.ContextCompat import android.util.Log import com.google.android.gms.common.api.ApiException import com.google.android.gms.common.api.CommonStatusCodes import com.google.android.gms.common.api.ResolvableApiException import com.google.android.gms.location.LocationRequest import com.google.android.gms.location.LocationServices import com.google.android.gms.location.LocationSettingsRequest import com.google.android.gms.location.LocationSettingsStatusCodes import java.lang.ref.WeakReference object CurrentLocationManager : LocationListener { const val REQUEST_CODE_ACCESS_LOCATION = 123 fun checkLocationPermission(activity: Activity) { if (ContextCompat.checkSelfPermission( activity, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions( activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_CODE_ACCESS_LOCATION ) } else { Thread(Runnable { // Moves the current Thread into the background android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND) // requestLocationUpdates(activity) }).start() } } /** * be used in HomeActivity. */ const val REQUEST_CHECK_SETTINGS = 55 /** * The number of millis in the future from the call to start(). * until the countdown is done and onFinish() is called. * * * It is also the interval along the way to receive onTick(long) callbacks. */ private const val TWENTY_SECS: Long = 20000 /** * Timer to get location from history when requestLocationUpdates don''t return result. */ private var mCountDownTimer: CountDownTimer? = null /** * WeakReference of current activity. */ private var mWeakReferenceActivity: WeakReference<Activity>? = null /** * user''s location. */ var currentLocation: Location? = null @Synchronized fun requestLocationUpdates(activity: Activity) { if (mWeakReferenceActivity == null) { mWeakReferenceActivity = WeakReference(activity) } else { mWeakReferenceActivity?.clear() mWeakReferenceActivity = WeakReference(activity) } //create location request: https://developer.android.com/training/location/change-location-settings.html#prompt val mLocationRequest = LocationRequest() // Which your app prefers to receive location updates. Note that the location updates may be // faster than this rate, or slower than this rate, or there may be no updates at all // (if the device has no connectivity) mLocationRequest.interval = 20000 //This method sets the fastest rate in milliseconds at which your app can handle location updates. // You need to set this rate because other apps also affect the rate at which updates are sent mLocationRequest.fastestInterval = 10000 mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //Get Current Location Settings val builder = LocationSettingsRequest.Builder().addLocationRequest(mLocationRequest) //Next check whether the current location settings are satisfied val client = LocationServices.getSettingsClient(activity) val task = client.checkLocationSettings(builder.build()) //Prompt the User to Change Location Settings task.addOnSuccessListener(activity) { Log.d("CurrentLocationManager", "OnSuccessListener") // All location settings are satisfied. The client can initialize location requests here. // If it''s failed, the result after user updated setting is sent to onActivityResult of HomeActivity. val activity1 = mWeakReferenceActivity?.get() if (activity1 != null) { startRequestLocationUpdate(activity1.applicationContext) } } task.addOnFailureListener(activity) { e -> Log.d("CurrentLocationManager", "addOnFailureListener") val statusCode = (e as ApiException).statusCode when (statusCode) { CommonStatusCodes.RESOLUTION_REQUIRED -> // Location settings are not satisfied, but this can be fixed // by showing the user a dialog. try { val activity1 = mWeakReferenceActivity?.get() if (activity1 != null) { // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). val resolvable = e as ResolvableApiException resolvable.startResolutionForResult( activity1, REQUEST_CHECK_SETTINGS ) } } catch (sendEx: IntentSender.SendIntentException) { // Ignore the error. sendEx.printStackTrace() } 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. } } } } fun startRequestLocationUpdate(appContext: Context) { val mLocationManager = appContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager if (ActivityCompat.checkSelfPermission( appContext.applicationContext, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED ) { //Utilities.showProgressDialog(mWeakReferenceActivity.get()); if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { mLocationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 10000, 0f, this ) } else { mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 10000, 0f, this ) } } /*Timer to call getLastKnownLocation() when requestLocationUpdates don ''t return result*/ countDownUpdateLocation() } override fun onLocationChanged(location: Location?) { if (location != null) { stopRequestLocationUpdates() currentLocation = location } } override fun onStatusChanged(provider: String, status: Int, extras: Bundle) { } override fun onProviderEnabled(provider: String) { } override fun onProviderDisabled(provider: String) { } /** * Init CountDownTimer to to get location from history when requestLocationUpdates don''t return result. */ @Synchronized private fun countDownUpdateLocation() { mCountDownTimer?.cancel() mCountDownTimer = object : CountDownTimer(TWENTY_SECS, TWENTY_SECS) { override fun onTick(millisUntilFinished: Long) {} override fun onFinish() { if (mWeakReferenceActivity != null) { val activity = mWeakReferenceActivity?.get() if (activity != null && ActivityCompat.checkSelfPermission( activity, Manifest.permission.ACCESS_FINE_LOCATION ) == PackageManager.PERMISSION_GRANTED ) { val location = (activity.applicationContext .getSystemService(Context.LOCATION_SERVICE) as LocationManager) .getLastKnownLocation(LocationManager.PASSIVE_PROVIDER) stopRequestLocationUpdates() onLocationChanged(location) } else { stopRequestLocationUpdates() } } else { mCountDownTimer?.cancel() mCountDownTimer = null } } }.start() } /** * The method must be called in onDestroy() of activity to * removeUpdateLocation and cancel CountDownTimer. */ fun stopRequestLocationUpdates() { val activity = mWeakReferenceActivity?.get() if (activity != null) { /*if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {*/ (activity.applicationContext .getSystemService(Context.LOCATION_SERVICE) as LocationManager).removeUpdates(this) /*}*/ } mCountDownTimer?.cancel() mCountDownTimer = null } }

En MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... CurrentLocationManager.checkLocationPermission(this@LoginActivity) } override fun onDestroy() { CurrentLocationManager.stopRequestLocationUpdates() super.onDestroy() } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == CurrentLocationManager.REQUEST_CODE_ACCESS_LOCATION) { if (grantResults[0] == PackageManager.PERMISSION_DENIED) { //denied val builder = AlertDialog.Builder(this) builder.setMessage("We need permission to use your location for the purpose of finding friends near you.") .setTitle("Device Location Required") .setIcon(com.eswapp.R.drawable.ic_info) .setPositiveButton("OK") { _, _ -> if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.ACCESS_FINE_LOCATION ) ) { //only deny CurrentLocationManager.checkLocationPermission(this@LoginActivity) } else { //never ask again val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) val uri = Uri.fromParts("package", packageName, null) intent.data = uri startActivityForResult(intent, CurrentLocationManager.REQUEST_CHECK_SETTINGS) } } .setNegativeButton("Ask Me Later") { _, _ -> } // Create the AlertDialog object and return it val dialog = builder.create() dialog.show() } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { CurrentLocationManager.requestLocationUpdates(this) } } } //Forward Login result to the CallBackManager in OnActivityResult() override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { when (requestCode) { //case 1. After you allow the app access device location, Another dialog will be displayed to request you to turn on device location //case 2. Or You chosen Never Ask Again, you open device Setting and enable location permission CurrentLocationManager.REQUEST_CHECK_SETTINGS -> when (resultCode) { RESULT_OK -> { Log.d("REQUEST_CHECK_SETTINGS", "RESULT_OK") //case 1. You choose OK CurrentLocationManager.startRequestLocationUpdate(applicationContext) } RESULT_CANCELED -> { Log.d("REQUEST_CHECK_SETTINGS", "RESULT_CANCELED") //case 1. You choose NO THANKS //CurrentLocationManager.requestLocationUpdates(this) //case 2. In device Setting screen: user can enable or not enable location permission, // so when user back to this activity, we should re-call checkLocationPermission() CurrentLocationManager.checkLocationPermission(this@LoginActivity) } else -> { //do nothing } } else -> { super.onActivityResult(requestCode, resultCode, data) } } }


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

Aquí hay un ejemplo simple sobre cómo solicitar 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 que se haya otorgado una solicitud de permiso con el código de solicitud REQUEST_CODE .

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

Puede implementar devoluciones de llamada separadas para el permiso otorgado y el permiso denegado también. Se explica en la página de github.


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

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

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Luego pida permiso de tiempo de ejecución al 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?


verifique este código de MainActivity

// Check location permission is granted - if it is, start // the service, otherwise request the permission fun checkOrAskLocationPermission(callback: () -> Unit) { // Check GPS is enabled val lm = getSystemService(Context.LOCATION_SERVICE) as LocationManager if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Toast.makeText(this, "Please enable location services", Toast.LENGTH_SHORT).show() buildAlertMessageNoGps(this) return } // Check location permission is granted - if it is, start // the service, otherwise request the permission val permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) if (permission == PackageManager.PERMISSION_GRANTED) { callback.invoke() } else { // callback will be inside the activity''s onRequestPermissionsResult( ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSIONS_REQUEST ) } }

más

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == PERMISSIONS_REQUEST) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED){ // Permission ok. Do work. } } }

más

fun buildAlertMessageNoGps(context: Context) { val builder = AlertDialog.Builder(context); builder.setMessage("Your GPS is disabled. Do you want to enable it?") .setCancelable(false) .setPositiveButton("Yes") { _, _ -> context.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)) } .setNegativeButton("No") { dialog, _ -> dialog.cancel(); } val alert = builder.create(); alert.show(); }

uso

checkOrAskLocationPermission() { // Permission ok. Do work. }