Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


SecurityException lanzada al llamar a WifiManager startScan

Estoy usando un PendingIntent lanzado por AlarmManager (con setRepeating ) para iniciar las exploraciones wifi (usando IntentService ) cada pocos minutos. En la mayoría de los dispositivos y en la mayoría de los casos, no hay ningún problema con eso. Sin embargo, en varios dispositivos obtengo el siguiente error (No se pudo reproducir el error en ningún dispositivo de prueba: un registro de bloqueo desde el dispositivo de un usuario):

 java.lang.RuntimeException: Unable to start service com.myapp.android.service.MyService@44a9701 with Intent { act=com.myapp.android.ACTION_PERFORM_WIFI_SCAN flg=0x4 cmp=com.myapp/com.mayapp.android.service.MyService (has extras) }: java.lang.SecurityException: Permission Denial: broadcast from android asks to run as user -1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3021) at android.app.ActivityThread.-wrap17(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1443) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5415) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:725) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:615) Caused by: java.lang.SecurityException: Permission Denial: broadcast from android asks to run as user -1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS at android.os.Parcel.readException(Parcel.java:1599) at android.os.Parcel.readException(Parcel.java:1552) at android.net.wifi.IWifiManager$Stub$Proxy.startScan(IWifiManager.java:1045) at android.net.wifi.WifiManager.startScan(WifiManager.java:1088) ... 

Estoy creando el PendingIntent de mi aplicación así que no veo ninguna razón para el SecurityException lanzado de WifiManager (especialmente porque esto sucede raramente).

El IntentService lanzado desde el código de PendingIntent es el siguiente:

 mContext.registerReceiver(mWifiScanReceiver, new IntentFilter( WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); boolean ok = mWifiManager.startScan(); 

¿Alguna idea de lo que pueda estar causando esto?

  • ¿Cómo puedo configurar ProxySettings y ProxyProperties en la conexión Wi-Fi de Android usando Java?
  • Android M: no se puede quitar Wi-Fi AP programáticamente
  • ¿Hay alguna manera de ser notificado cuando las redes wifi SSIS conocidas entran o salen del rango?
  • Android Wi-Fi Direct leer la intensidad de la señal rssi
  • Android WifiLock WIFI_MODE_SCAN_ONLY no funciona
  • Establecer IP estática y pasarela programáticamente en Android 6.x (Marshmallow)
  • ¿Cómo puedo configurar ProxySettings y ProxyProperties en la conexión Wi-Fi de Android usando Java?
  • Obtener la dirección MAC del dispositivo: cuando el wifi está desactivado
  • 3 Solutions collect form web for “SecurityException lanzada al llamar a WifiManager startScan”

    Esto está sucediendo debido a los nuevos permisos de aplicación para android m. Ver el comentario sobre el código fuente de wifimanager's getScanResults() for api 23

     /** * Return the results of the latest access point scan. * @return the list of access points found in the most recent scan. An app must hold * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission * in order to get valid results. */ public List<ScanResult> getScanResults() { try { return mService.getScanResults(mContext.getOpPackageName()); } catch (RemoteException e) { return null; } } 

    Por lo tanto, tendrá que pedir permisos al usuario en tiempo de ejecución. Ponga estos permisos en su manifiesto-

      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 

    Desde api 23 en adelante requiere un permiso para acceder a la ubicación del usuario para usarlo. Le sugiero que utilice una comprobación de permisos basada en el nivel de api y que inicie la intención sólo si los permisos se han concedido. Algo como esto-

     if (Build.VERSION.SDK_INT >= 23) { int hasReadLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); if (hasReadLocationPermission != PackageManager.PERMISSION_GRANTED) { if (!ActivityCompat.shouldShowRequestPermissionRationale(HomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) { showMessageOKCancel("You need to allow access to GPS", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, GPS_ENABLE_REQUEST); } }); return; } ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, GPS_ENABLE_REQUEST); return; } if (locationManager != null && !locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { gotoGPSEnableScreen(); } else { //Permissions granted and gps is on launchService(true); } } 

    Para comprobar los resultados,

     @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case GPS_ENABLE_REQUEST: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { gotoGPSEnableScreen(); } } else { launchService(false); } default: return; } } 

    ACTUALIZAR:

    Android.permission.INTERACT_ACROSS_USERS_FULL es un permiso de nivel de firma. Simplemente añada este android: protectionLevel = "firma" en su manifiesto.

    Para más detalles puede comprobar esto

    http://developer.android.com/guide/topics/manifest/permission-element.html

     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/> 

    Si vas a anular

     onCreate() 

    en tus

     IntentService, 

    Entonces asegúrese de llamar

     super.onCreate() 

    en eso. Que parece ser muy probable que su problema.

    Su problema es que está llamando desde diferentes usuarios y pidiendo que se ejecute en diferentes usuarios y que requiere android.permission.INTERACT_ACROSS_USERS_FULL y que es el permiso de nivel de firma. Simplemente añada este android:protectionLevel="signature" en su manifiesto.

    Para más detalles puede comprobar esto

    http://developer.android.com/guide/topics/manifest/permission-element.html

     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/> 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.