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
Post a Comment