android - SecurityException thrown when calling WifiManager startScan -


i'm using pendingintent launched alarmmanager (with setrepeating) start wifi scans (using intentservice) every few minutes. on devices , in cases, there no problem that. however, on several devices following error (couldn't reproduce error on test device. crash log user's device):

java.lang.runtimeexception: unable start service com.myapp.android.service.myservice@44a9701 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 android asks run user -1 calling user 0; requires android.permission.interact_across_users_full or android.permission.interact_across_users        @ android.app.activitythread.handleserviceargs(activitythread.java:3021)        @ android.app.activitythread.-wrap17(activitythread.java)        @ android.app.activitythread$h.handlemessage(activitythread.java:1443)        @ android.os.handler.dispatchmessage(handler.java:102)        @ android.os.looper.loop(looper.java:148)        @ android.app.activitythread.main(activitythread.java:5415)        @ java.lang.reflect.method.invoke(method.java)        @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:725)        @ com.android.internal.os.zygoteinit.main(zygoteinit.java:615) caused by: java.lang.securityexception: permission denial: broadcast android asks run user -1 calling user 0; requires android.permission.interact_across_users_full or android.permission.interact_across_users        @ android.os.parcel.readexception(parcel.java:1599)        @ android.os.parcel.readexception(parcel.java:1552)        @ android.net.wifi.iwifimanager$stub$proxy.startscan(iwifimanager.java:1045)        @ android.net.wifi.wifimanager.startscan(wifimanager.java:1088)        ... 

i'm creating pendingintent app see no reason securityexception thrown wifimanager (especially since happens rarely).

the intentservice launched pendingintent code follows:

mcontext.registerreceiver(mwifiscanreceiver, new intentfilter(                     wifimanager.scan_results_available_action));  boolean ok = mwifimanager.startscan(); 

any ideas on might causing this?

this happening because of new app permissions android m. see comment above source code of wifimanager's getscanresults() api 23-

/**      * return results of latest access point scan.      * @return list of access points found in recent scan. 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 valid results.      */ public list<scanresult> getscanresults() {         try {             return mservice.getscanresults(mcontext.getoppackagename());         } catch (remoteexception e) {             return null;         }     } 

hence, have ask user permissions on runtime. put these permissions in manifest-

  <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"/> 

from api 23 onwards require permission access user location use it. suggest use permissions check based on api level , start intent if permissions have been granted. this-

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 allow access 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 , gps on         launchservice(true);       } } 

further check results-

@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;     }   } 

update:

android.permission.interact_across_users_full signature level permission. add android:protectionlevel="signature" in manifest .

for more details can check this

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

<permission android:name="android.permission.interact_across_users_full" android:protectionlevel="signature"/> 

Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -