Android 获取判断是否有悬浮窗权限的方法
现在很多应用都会用到悬浮窗,很多国产rom把悬浮窗权限加入控制了,你就需要判断是否有悬浮窗权限,然后做对应操作。
Android原生有自带权限管理的,只是被隐藏了。看android源码在android.app下就有个AppOpsManager类。
类说明如下:
/** *APIforinteractingwith"applicationoperation"tracking. * *ThisAPIisnotgenerallyintendedforthirdpartyapplicationdevelopers;most *featuresareonlyavailabletosystemapplications.Obtainaninstanceofitthrough *{@linkContext#getSystemService(String)Context.getSystemService}with *{@linkContext#APP_OPS_SERVICEContext.APP_OPS_SERVICE}.
*/
上面说明了只对系统应用有用,rom厂商们应该就是利用这个AppOps机制开放一些权限控制。
我们要判断是否有权限该如何做呢?就只能通过反射去判断了。
AppOpsManager的checkOp方法,就是检测是否有某项权限的方法有这些返回值,分别是允许,忽略,错误和默认:
/** *Resultfrom{@link#checkOp},{@link#noteOp},{@link#startOp}:thegivencalleris *allowedtoperformthegivenoperation. */ publicstaticfinalintMODE_ALLOWED=0; /** *Resultfrom{@link#checkOp},{@link#noteOp},{@link#startOp}:thegivencalleris *notallowedtoperformthegivenoperation,andthisattemptshould *silentlyfail(itshouldnotcausetheapptocrash). */ publicstaticfinalintMODE_IGNORED=1; /** *Resultfrom{@link#checkOpNoThrow},{@link#noteOpNoThrow},{@link#startOpNoThrow}:the *givencallerisnotallowedtoperformthegivenoperation,andthisattemptshould *causeittohaveafatalerror,typicallya{@linkSecurityException}. */ publicstaticfinalintMODE_ERRORED=2; /** *Resultfrom{@link#checkOp},{@link#noteOp},{@link#startOp}:thegivencallershould *useitsdefaultsecuritycheck.Thismodeisnotnormallyused;itshouldonlybeused *withappoppermissions,andcallersmustexplicitlycheckforitanddealwithit. */ publicstaticfinalintMODE_DEFAULT=3;
只有MODE_ALLOWED才是确定有权限的。
类里面checkOp方法如下,三个参数分别是操作id,uid和包名:
/** *Doaquickcheckforwhetheranapplicationmightbeabletoperformanoperation. *Thisisnotasecuritycheck;youmustuse{@link#noteOp(int,int,String)} *or{@link#startOp(int,int,String)}foryouractualsecuritychecks,whichalso *ensurethatthegivenuidandpackagenameareconsistent.Thisfunctioncanjustbe *usedforaquickchecktoseeifanoperationhasbeendisabledfortheapplication, *asanearlyrejectofsomework.Thisdoesnotmodifythetimestamporotherdata *abouttheoperation. *@paramopTheoperationtocheck.OneoftheOP_*constants. *@paramuidTheuseridoftheapplicationattemptingtoperformtheoperation. *@parampackageNameThenameoftheapplicationattemptingtoperformtheoperation. *@returnReturns{@link#MODE_ALLOWED}iftheoperationisallowed,or *{@link#MODE_IGNORED}ifitisnotallowedandshouldbesilentlyignored(without *causingtheapptocrash). *@throwsSecurityExceptionIftheapphasbeenconfiguredtocrashonthisop. *@hide */ publicintcheckOp(intop,intuid,StringpackageName){ try{ intmode=mService.checkOperation(op,uid,packageName); if(mode==MODE_ERRORED){ thrownewSecurityException(buildSecurityExceptionMsg(op,uid,packageName)); } returnmode; }catch(RemoteExceptione){ } returnMODE_IGNORED; }
操作id即op可以在该类中找到静态值定义,android23里面有62种权限,我们需要的是OP_SYSTEM_ALERT_WINDOW=24
知道这些就可以用反射把我们的方法写出了:
/** *判断悬浮窗口权限是否打开 * *@paramcontext *@returntrue允许false禁止 */ publicstaticbooleangetAppOps(Contextcontext){ try{ Objectobject=context.getSystemService("appops"); if(object==null){ returnfalse; } ClasslocalClass=object.getClass(); Class[]arrayOfClass=newClass[3]; arrayOfClass[0]=Integer.TYPE; arrayOfClass[1]=Integer.TYPE; arrayOfClass[2]=String.class; Methodmethod=localClass.getMethod("checkOp",arrayOfClass); if(method==null){ returnfalse; } Object[]arrayOfObject1=newObject[3]; arrayOfObject1[0]=Integer.valueOf(24); arrayOfObject1[1]=Integer.valueOf(Binder.getCallingUid()); arrayOfObject1[2]=context.getPackageName(); intm=((Integer)method.invoke(object,arrayOfObject1)).intValue(); returnm==AppOpsManager.MODE_ALLOWED; }catch(Exceptionex){ } returnfalse; }
测试在魅族华为小米大部分机型上都是可以的,但这个方法也不能保证正确,一些机型上会返回错误即MODE_ERRORED,就是获取不到权限值,这个方法就返回了false,但实际上悬浮窗是可以使用的。
以上这篇Android获取判断是否有悬浮窗权限的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。