溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Android中判斷是否有懸浮窗權限

發(fā)布時間:2021-01-28 10:49:17 來源:億速云 閱讀:545 作者:Leah 欄目:移動開發(fā)

這期內容當中小編將會給大家?guī)碛嘘P怎么在Android中判斷是否有懸浮窗權限,文章內容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Android 原生有自帶權限管理的,只是被隱藏了??碼ndroid源碼在android.app下就有個AppOpsManager類。

類說明如下:

/**
 * API for interacting with "application operation" tracking.
 *
 * <p>This API is not generally intended for third party application developers; most
 * features are only available to system applications. Obtain an instance of it through
 * {@link Context#getSystemService(String) Context.getSystemService} with
 * {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.</p>
 */

上面說明了只對系統(tǒng)應用有用,rom廠商們應該就是利用這個AppOps機制開放一些權限控制。

我們要判斷是否有權限該如何做呢?就只能通過反射去判斷了。

AppOpsManager的checkOp方法,就是檢測是否有某項權限的方法有這些返回值,分別是允許,忽略,錯誤和默認:

/**
 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
 * allowed to perform the given operation.
 */
public static final int MODE_ALLOWED = 0;

/**
 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
 * not allowed to perform the given operation, and this attempt should
 * <em>silently fail</em> (it should not cause the app to crash).
 */
public static final int MODE_IGNORED = 1;

/**
 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
 * given caller is not allowed to perform the given operation, and this attempt should
 * cause it to have a fatal error, typically a {@link SecurityException}.
 */
public static final int MODE_ERRORED = 2;

/**
 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
 * use its default security check. This mode is not normally used; it should only be used
 * with appop permissions, and callers must explicitly check for it and deal with it.
 */
public static final int MODE_DEFAULT = 3;

只有MODE_ALLOWED才是確定有權限的。

類里面checkOp方法如下,三個參數分別是操作id,uid和包名:

/**
 * Do a quick check for whether an application might be able to perform an operation.
 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
 * or {@link #startOp(int, int, String)} for your actual security checks, which also
 * ensure that the given uid and package name are consistent. This function can just be
 * used for a quick check to see if an operation has been disabled for the application,
 * as an early reject of some work. This does not modify the time stamp or other data
 * about the operation.
 * @param op The operation to check. One of the OP_* constants.
 * @param uid The user id of the application attempting to perform the operation.
 * @param packageName The name of the application attempting to perform the operation.
 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
 * causing the app to crash).
 * @throws SecurityException If the app has been configured to crash on this op.
 * @hide
 */
public int checkOp(int op, int uid, String packageName) {
 try {
  int mode = mService.checkOperation(op, uid, packageName);
  if (mode == MODE_ERRORED) {
   throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
  }
  return mode;
 } catch (RemoteException e) {
 }
 return MODE_IGNORED;
}

操作id即op可以在該類中找到靜態(tài)值定義,android23里面有62種權限,我們需要的是OP_SYSTEM_ALERT_WINDOW=24

知道這些就可以用反射把我們的方法寫出了:

 /**
  * 判斷 懸浮窗口權限是否打開
  *
  * @param context
  * @return true 允許 false禁止
  */
 public static boolean getAppOps(Context context) {
  try {
   Object object = context.getSystemService("appops");
   if (object == null) {
    return false;
   }
   Class localClass = object.getClass();
   Class[] arrayOfClass = new Class[3];
   arrayOfClass[0] = Integer.TYPE;
   arrayOfClass[1] = Integer.TYPE;
   arrayOfClass[2] = String.class;
   Method method = localClass.getMethod("checkOp", arrayOfClass);
   if (method == null) {
    return false;
   }
   Object[] arrayOfObject1 = new Object[3];
   arrayOfObject1[0] = Integer.valueOf(24);
   arrayOfObject1[1] = Integer.valueOf(Binder.getCallingUid());
   arrayOfObject1[2] = context.getPackageName();
   int m = ((Integer) method.invoke(object, arrayOfObject1)).intValue();
   return m == AppOpsManager.MODE_ALLOWED;
  } catch (Exception ex) {
 
  }
  return false;
 }

上述就是小編為大家分享的怎么在Android中判斷是否有懸浮窗權限了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI