दिलचस्प पोस्ट
4.4 किट कैट पर पारदर्शी स्थिति-बार / सिस्टम-यू PhotoImage के अंतर्गत छवि का आकार बदलना क्या मैं एक नियंत्रण के अंदर एक विंडोज़ प्रोजेक्ट होस्ट कर सकता हूं? रेल प्राथमिक कुंजी और ऑब्जेक्ट आईडी .resx फ़ाइल में सभी संसाधनों के माध्यम से लूप किसी भी तरह से स्मृति में कर्ल की कुकीज़ रखने के लिए और डिस्क पर नहीं PopupWindow $ BadTokenException: विंडो जोड़ने में असमर्थ – टोकन नल मान्य नहीं है php: कर्ल के साथ html स्रोत कोड प्राप्त करें "स्ट्रीम पहले ही चालू या बंद कर दिया गया" (जावा 8) से बचने के लिए एक स्ट्रीम की प्रतिलिपि बनाएँ Jquery का उपयोग यूआरएल से डोमेन नाम कैसे प्राप्त करें ..? कैसे एक जीआईटी रिपॉजिटरी को एक दूसरे पर रिबेस करने के लिए? PHP – उपयोगकर्ता को फ़ाइल भेजें कैसे + = (प्लस समान) काम करता है? एकाधिक कोर का उपयोग करके जी ++ के साथ संकलित करना फ़ंक्शन ऑब्जेक्ट को कॉल करते समय तर्क मूल्यांकन के आदेश की गारंटी कैसे दें?

SYSTEM_ALERT_WINDOW की अनुमति को कैसे प्रबंधित करें, कुछ पूर्व-मार्शमॉलो उपकरणों पर स्वत: अनुमति नहीं दी जा रही है

मुझे कुछ ज़ियामी उपकरणों की रिपोर्ट मिल रही है (जैसे मी 2, एपीआई स्तर 21 चल रहा है) ओवरले नहीं दिखा रहा है मेरा ऐप लक्ष्य एपीआई 23

इस बारे में कई पद हैं ऐसा लगता है कि एमआईयूआई डिवाइस स्थापित समय पर इस अनुमति को सक्षम नहीं करते हैं (अन्य प्री-मार्शमॉल उपकरण के विपरीत)।

दुर्भाग्यवश, Settings.canDrawOverlays() केवल एंड्रॉइड 23+ पर काम करता है

  1. यह जांच करने का सही तरीका क्या है कि क्या यह अनुमति अभी तक पूर्व-मार्शमॉल को सक्षम नहीं कर पाई है?
  2. उपयोगकर्ता को प्रासंगिक MUIU सेटिंग्स पृष्ठ पर ले जाने का एक इरादा है? हो सकता है: new Intent("android.settings.action.MANAGE_OVERLAY_PERMISSION", packageName) लेकिन मुझे इसका परीक्षण करने का कोई मतलब नहीं है।

Solutions Collecting From Web of "SYSTEM_ALERT_WINDOW की अनुमति को कैसे प्रबंधित करें, कुछ पूर्व-मार्शमॉलो उपकरणों पर स्वत: अनुमति नहीं दी जा रही है"

1) पूर्व-एपीआई 23 पर, अनुमति पहले से ही दी गई है, क्योंकि उपयोगकर्ता ने इसे इंस्टॉल करने पर दिया था।

संपादित करें: ऐसा लगता है कि एंड्रॉइड 6 पर एक बग है (जो कि 6.0.1 पर तय हो जाएगा), यदि उपयोगकर्ता ने इस अनुमति से इनकार कर दिया है, तो ऐप सुरक्षाएक्सेप्शन के साथ क्रैश हो जाएगा। पता नहीं कैसे गूगल तय हालांकि यह।

2) इस तरह:

 public static void requestSystemAlertPermission(Activity context, Fragment fragment, int requestCode) { if (VERSION.SDK_INT < VERSION_CODES.M) return; final String packageName = context == null ? fragment.getActivity().getPackageName() : context.getPackageName(); final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + packageName)); if (fragment != null) fragment.startActivityForResult(intent, requestCode); else context.startActivityForResult(intent, requestCode); } 

इसके बाद, ऑन एक्टिवेटिव रिजल्ट में, आप देख सकते हैं कि अनुमति दी गई है या नहीं, जैसे:

 @TargetApi(VERSION_CODES.M) public static boolean isSystemAlertPermissionGranted(Context context) { final boolean result = VERSION.SDK_INT < VERSION_CODES.M || Settings.canDrawOverlays(context); return result; } 

संपादित करें: समय के लिए, यदि आप Play Store में किसी ऐप को प्रकाशित करते हैं, तो आपका ऐप इस अनुमति के साथ स्वत: प्राप्त किया जाएगा। आप इसके बारे में यहां पढ़ सकते हैं। जब मैंने इसके बारे में पूछा, तो मैंने सोचा कि यह एंड्रॉइड का एक हिस्सा था, जैसा कि मैंने सोचा था कि हम सभी को लक्ष्य एसडीकेवर्सन के लिए पर्याप्त मूल्य को लक्षित करना है। Google ने मुझे क्या लिखा ( यहाँ ) यह है कि वे लोकप्रिय ऐप्स पर समस्याओं से बचने के लिए चाहते थे

मैं सुझाव देता हूं कि इस अनुमति को सही तरीके से प्रबंधित करने के लिए भले ही आप इसे स्वयं-अनुदान प्राप्त कर सकें

अगर आपके पास ड्रॉवरले अनुमति है तो जांचना इस का उपयोग करने में सुरक्षित है:

 @SuppressLint("NewApi") public static boolean canDrawOverlayViews(Context con){ if(Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP){return true;} try { return Settings.canDrawOverlays(con); } catch(NoSuchMethodError e){ return canDrawOverlaysUsingReflection(con); } } public static boolean canDrawOverlaysUsingReflection(Context context) { try { AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); Class clazz = AppOpsManager.class; Method dispatchMethod = clazz.getMethod("checkOp", new Class[] { int.class, int.class, String.class }); //AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24 int mode = (Integer) dispatchMethod.invoke(manager, new Object[] { 24, Binder.getCallingUid(), context.getApplicationContext().getPackageName() }); return AppOpsManager.MODE_ALLOWED == mode; } catch (Exception e) { return false; } } 

कस्टम रोमों ने ओएस को बदल दिया हो सकता है ताकि सेटिंग्स.canDrawOverlays () उपलब्ध नहीं हो। यह ज़ियामी उपकरणों के साथ मेरे साथ हुआ और एप क्रैश हो गया।

अनुमति का अनुरोध करना:

 @SuppressLint("InlinedApi") public static void requestOverlayDrawPermission(Activity act, int requestCode){ Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + act.getPackageName())); act.startActivityForResult(intent, requestCode); } 

यह कैसे कदम उठाने के लिए कदम से कदम है:

सबसे पहले मैनिफ़ेस्ट फाइल में अनुमति नीचे दें:

 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 

या

 <uses-permission-sdk-23 android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 

फिर नीचे कोड का उपयोग करके बाकी चीजों को संभालना:

  public final static int REQUEST_CODE = 65635; public void checkDrawOverlayPermission() { /** check if we already have permission to draw over other apps */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (!Settings.canDrawOverlays(this)) { /** if not construct intent to request permission */ Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); /** request permission via start activity for result */ startActivityForResult(intent, REQUEST_CODE); } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { /** check if received result code is equal our requested code for draw permission */ if (requestCode == REQUEST_CODE) { // ** if so check once again if we have permission */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Settings.canDrawOverlays(this)) { // continue here - permission was granted goYourActivity(); } } } } 

केवल अपनी लॉन्चर checkDrawOverlayPermission() से या कहीं भी अपनी आवश्यकताओं के अनुसार checkDrawOverlayPermission() को कॉल करें

जब आप प्रोजेक्ट निष्पादित करते हैं तो आपको एक विंडो दिखाई देगी और अनुमति को सक्षम करने के लिए कहा जाएगा। अनुमति के बाद आप इस बारे में कुछ भी करने में सक्षम होंगे।

Xiaomi में समस्या के बारे में जानने के लिए, Meizu मुझे यह पता चला है। यह पूरी तरह से काम कर रहा है ..

 public static boolean isMiuiFloatWindowOpAllowed(@NonNull Context context) { final int version = Build.VERSION.SDK_INT; if (version >= 19) { return checkOp(context, OP_SYSTEM_ALERT_WINDOW); //See AppOpsManager.OP_SYSTEM_ALERT_WINDOW=24 /*@hide/ } else { return (context.getApplicationInfo().flags & 1<<27) == 1; } } public static boolean checkOp(Context context, int op, String packageName, int uid) { final int version = Build.VERSION.SDK_INT; if (version >= 19) { AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); try { return (AppOpsManager.MODE_ALLOWED == (Integer) ReflectUtils.invokeMethod(manager, "checkOp", op, uid, packageName)); } catch (Exception e) { e.printStackTrace(); } } else { Flog.e("Below API 19 cannot invoke!"); } return false; } 

ReflectUtils.java

 public static Object invokeMethod(@NonNull Object receiver, String methodName, Object... methodArgs) throws Exception { Class<?>[] argsClass = null; if (methodArgs != null && methodArgs.length != 0) { int length = methodArgs.length; argsClass = new Class[length]; for (int i=0; i<length; i++) { argsClass[i] = getBaseTypeClass(methodArgs[i].getClass()); } } Method method = receiver.getClass().getMethod(methodName, argsClass); return method.invoke(receiver, methodArgs); } 

संदर्भ