¿Solicitar permiso de ubicación cuando no se supervisa en segundo plano?
Estoy usando la Biblioteca de Android Beacon. Desde Marshmallow, estoy viendo el siguiente error, como se esperaba y documentado.
Permiso de denegación: Necesita ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION permiso para obtener los resultados del análisis
- PercentRelativeLayout dentro de ScrollView
- Android M Preview 3 emulador Native Browser crash
- Appwidget listview filas que no se actualizan o cargan después de la actualización de Marshmallow
- Conéctese a wifi sin Internet mediante programación
- PopupWindow Enter Exit La animación no funciona en Marshmallow (23)
Tengo mi código de alcance en un fragmento, y la RuntimeException se lanza cuando el fragmento está en la pantalla, como se espera, ya que no estoy pidiendo permiso. Si toco el botón de inicio, se llama Pausa, y estoy desenlazando beaconManager, y la excepción ya no se activa, de nuevo, como se esperaba. Volviendo a la actividad de la lista anterior de aplicaciones, RuntimeException se lanza de nuevo cada exploración.
¿Por qué se produce la excepción cuando está en primer plano aunque he añadido el permiso al AndroidManifest?
De acuerdo con la documentación AQUÍ , sólo tiene que pedir al usuario permiso de ubicación si está realizando una exploración en segundo plano?
Obtendrá el siguiente error en LogCat cuando intente realizar una exploración Bluetooth en segundo plano y no se detectarán balizas
¿Significa esto SÓLO una exploración en segundo plano, o estoy malinterpretando la documentación, y usted debe preguntar sin tener en cuenta? Quiero evitar el extra (off-putting tal vez a los usuarios nerviosos) pedir permiso dentro de la aplicación si es evitable!
Mi Manifiesto contiene –
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Mi código cortado del Fragmento es –
public class NearMeNowFragment extends Fragment implements BeaconConsumer { //Beacon manager stuff private BeaconManager beaconManager; <SNIP> @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); beaconManager = BeaconManager.getInstanceForApplication(getActivity()); beaconManager.getBeaconParsers().add(new BeaconParser(). setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.near_me_now, container, false); //Set up beacon stuff if Bluetooth available if (verifyBluetooth(false)) { beaconManager.bind(this); } <SNIP> return rootView; } /*************************** Beacon config methods **************************** */ @Override public void onBeaconServiceConnect() { //update all scan periods beaconManager.setForegroundScanPeriod(1100l); beaconManager.setForegroundBetweenScanPeriod(8900l); beaconManager.setAndroidLScanningDisabled(true); try { beaconManager.updateScanPeriods(); } catch (RemoteException e) { e.printStackTrace(); } beaconManager.setRangeNotifier(new RangeNotifier() { @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { <SNIP> //handling beacons here ... } else { Log.i(TAG, "ZERO BEACONS IN SCAN"); } } }); try { beaconManager.startRangingBeaconsInRegion(new Region(TAG, null, null, null)); } catch (RemoteException e) { e.printStackTrace(); } } @Override public Context getApplicationContext() { return getActivity().getApplicationContext(); } @Override public void unbindService(ServiceConnection serviceConnection) { getActivity().unbindService(serviceConnection); } @Override public boolean bindService(Intent intent, ServiceConnection serviceConnection, int mode) { return getActivity().bindService(intent, serviceConnection, mode); } @Override public void onPause() { super.onPause(); if(beaconManager.isBound(this)){ beaconManager.unbind(this); } } @Override public void onResume() { super.onResume(); beaconManager.bind(this); } @Override public void onDestroy() { super.onDestroy(); if(beaconManager.isBound(this)){ beaconManager.unbind(this); } }
}
Mi error real de Logcat es
W / Binder: Capturado un RuntimeException de la implementación de stub de enlace. Java.lang.SecurityException: Necesita el permiso ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION para obtener los resultados del análisis
- Enviar solicitud a través de WiFi (sin conexión) incluso si los datos móviles están activados (con conexión) en Android M
- Android Marshmallow - Llamada a un módulo de biblioteca (biblioteca nativa) de otro módulo de biblioteca que se estrelló
- Android 6 EditText.setError no funciona correctamente
- Appcelerator Studio: la aplicación de Android se bloquea en Marshmallow cuando carga una URL en un reproductor de video
- No puede solicitar permiso READ_EXTERNAL_STORAGE
- Android 6.0 Marshmallow - no se puede conectar a un periférico bluetooth cuando otra aplicación está escaneando
- La biblioteca de escaneo de códigos de barras ZBAR no funciona cuando se usa la versión 23 de sdk de destino en gradle
- Utilización de ACTION_CAPTIVE_PORTAL_SIGN_IN
Para aclarar el requisito es diferente dependiendo de si estableces targetSdkVersion 23
en tu archivo build.gradle.
Si segmentas SDK 23 (Marshmallow):
- Debe declarar android.permission.ACCESS_COARSE_LOCATION o android.permission.ACCESS_FINE_LOCATION en su manifiesto.
- Debe solicitar un permiso al usuario como se describe en la entrada de mi blog aquí.
- El usuario debe aceptar este permiso y no desactivarlo.
- Si alguno de los requisitos anteriores no se cumple, no podrá detectar balizas en primer plano o en el fondo.
Si NO apuntas al SDK 23 (Marshmallow):
- Usted puede declarar opcionalmente android.permission.ACCESS_COARSE_LOCATION o android.permission.ACCESS_FINE_LOCATION en su manifiesto.
- El usuario puede activar o desactivar el permiso accediendo a la configuración.
- Si no se concede uno de los permisos, seguirá siendo capaz de detectar balizas en primer plano, pero no en segundo plano.
Vea aquí y aquí para más detalles.
Tuve el mismo problema con mi aplicación cuando lo probé en un dispositivo Marshmallow. Para evitar solicitar permiso al usuario, acabo de cambiar la variable targetSdkVersion a 22. La compileSdkVersion puede permanecer en 23. Después de cambiar build.gradle, puede que tenga que ejecutar Herramientas> Android> Sincronizar proyecto con archivos Gradle. Si usa Eclipse, targetSdkVersion está en el archivo de manifiesto.
- LinearLayout con dos hijos de igual ancho
- Activar el servicio de fondo en un momento específico de Android