Android: विंडो जोड़ने में असमर्थ। इस विंडो प्रकार के लिए अनुमति से इनकार किया गया


85

मैं एक ऐसे ऐप पर काम कर रहा हूं, जहां मुझे फोन को अनलॉक किए बिना लॉक स्क्रीन (KeyGuard) पर कुछ जानकारी के साथ एक विंडो प्रदर्शित करने की आवश्यकता है। मुझे लगा कि मैं शायद WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG के साथ कर सकता हूँ

लेकिन हर बार मेरा ऐप निम्न त्रुटि के साथ क्रैश हो जाता है:

android.view.WindowManager $ BadTokenException: विंडो जोड़ने में असमर्थ android.view.ViewRootImpl WoW@40ec8528 - इस विंडो प्रकार के लिए अनुमति अस्वीकृत

ये पद ( यहां , यहां और यहां ) सभी एक ही उत्तर देते हैं। मेनिफेस्ट फ़ाइल में निम्नलिखित अनुमति जोड़ने के लिए।

android.permission.SYSTEM_ALERT_WINDOW

समाधान जो मैंने लागू किया है लेकिन मुझे अभी भी वही त्रुटि मिल रही है। कोई भी विचार जो मैं गलत कर रहा हूँ?

यहां मेरी मैनिफ़ेस्ट फ़ाइल में अनुमतियाँ हैं:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.droidpilot.keyguardwindow" >

<uses-sdk
    android:minSdkVersion="16"
    android:targetSdkVersion="21" />

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />

और यह वह कोड है जिसका उपयोग मैं विंडो को लॉक स्क्रीन में जोड़ने के लिए करता हूं

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    mView = mInflater.inflate(R.layout.lock_screen_notif, null);

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
            PixelFormat.TRANSLUCENT
    );

    wm.addView(mView, params);

किसी को कोई विचार आया?

PS मैं Android 4.4.2 पर चलने वाले HTC Desire 620 DS पर परीक्षण कर रहा हूं

जवाबों:


30

क्या पूरी तरह से स्पष्ट कारणों के लिए होना चाहिए, साधारण ऐप्स को लॉक स्क्रीन के शीर्ष पर मनमानी खिड़कियां बनाने की अनुमति नहीं है । आपको क्या लगता है कि अगर मैं आपके लॉकस्क्रीन पर एक ऐसी खिड़की बना सकता हूं जो वास्तविक लॉकस्क्रीन की पूरी तरह से नकल कर सकती है तो आप अंतर नहीं बता सकते?

आपकी त्रुटि का तकनीकी कारण TYPE_KEYGUARD_DIALOGध्वज का उपयोग है - इसके लिए android.permission.INTERNAL_SYSTEM_WINDOWहस्ताक्षर-स्तरीय अनुमति की आवश्यकता होती है। इसका मतलब यह है कि केवल सर्टिफिकेट उसी सर्टिफिकेट के साथ साइन किए जाते हैं, जिस तरह से अनुमति के निर्माता इसका इस्तेमाल कर सकते हैं।

का निर्माता android.permission.INTERNAL_SYSTEM_WINDOWस्वयं Android सिस्टम है, इसलिए जब तक आपका ऐप OS का हिस्सा नहीं है, तब तक आप एक मौका नहीं देते हैं।

लॉकस्क्रीन से सूचना के उपयोगकर्ता को सूचित करने के अच्छी तरह से परिभाषित और अच्छी तरह से प्रलेखित तरीके हैं । आप अनुकूलित सूचनाएं बना सकते हैं जो लॉकस्क्रीन पर दिखाई देती हैं और उपयोगकर्ता उनके साथ बातचीत कर सकता है।


2
व्यक्तिगत रूप से मैं फेसबुक ऐप के लॉक स्क्रीन नोटिफिकेशन जैसी किसी चीज़ की तलाश में था। मुझे पहले से ही नए लॉक स्क्रीन नोटिफिकेशन के बारे में पता था लेकिन ये अभी के लिए एंड्रॉइड 22 में काम करते हैं। मुझे एक समाधान की आवश्यकता है जो एंड्रॉइड 16 और ऊपर पर काम करेगा। लेकिन आपका जवाब सही समझ में आता है और मैं इसे इस तरह से स्वीकार करूंगा। मैंने लॉक स्क्रीन पर एक विंडो प्रदर्शित करने का प्रबंधन किया था, लेकिन इसकी आवश्यकता नहीं थी, मैं नीचे दिए गए समाधान को पोस्ट करूंगा।
DroidPilot

1
यदि ऐप्स को उस अनुमति की आवश्यकता होती है, जो इसे स्थापित और खोलने के बाद दी जा सकती है।
स्कोर्पेन

मुझे लगता है कि Oreo के बाद से यह सही उत्तर है stackoverflow.com/a/48481628/504179
ATom

107

यदि आप उपयोग apiLevel >= 19करते हैं , तो उपयोग न करें

WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 

जो निम्नलिखित त्रुटि प्राप्त करता है:

android.view.WindowManager $ BadTokenException: विंडो जोड़ने में असमर्थ android.view.ViewRootImpl WoW@40ec8528 - इस विंडो प्रकार के लिए अनुमति अस्वीकृत

इसके बजाय इसका उपयोग करें:

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

3
मैंने TYPE_SYSTEM_ALERTएंड्रॉइड 5.1 पर android.permission.SYSTEM_ALERT_WINDOWमैनिफ़ेस्ट में दिए गए काम के साथ ठीक काम किया है।
सैम

मुझे किसके android.permission.SYSTEM_ALERT_WINDOWसाथ उपयोग करना है LayoutParams.TYPE_TOAST?
t0m

1
मैंने LayoutPamsams.TYPE_TOAST की कोशिश की। लॉलीपॉप और मार्शमैलो दोनों एपीआई स्तर 6.0.1 पर मेरे लिए काम कर रहा है। इससे पहले मैं WindowManager.LayoutParams.TYPE_SYSTEM_ALERT का उपयोग कर रहा था, जो केवल लॉलीपॉप के लिए काम कर रहा था।
प्रशांत

दुर्भाग्य से यह "स्क्रीन ओवरले का पता लगाने" का कारण बनता है, अगर कुछ एप्लिकेशन अनुरोध अनुमति संवाद (यदि आपका दृश्य सक्रिय है)
Siarhei

यदि आप किसी सेवा या प्रसारण रिसीवर से खिड़की दिखाने की कोशिश कर रहे हैं तो यह काम नहीं करेगा
FindOutIslamNow

78

मुझे लगता है कि आपको लक्ष्य (ओरेओ से पहले और बाद में) में अंतर करना चाहिए

int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}

params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    LAYOUT_FLAG,
    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
    PixelFormat.TRANSLUCENT);

मैं एक समान तकनीक का उपयोग करने की कोशिश कर रहा हूं, लेकिन एंड्रॉइड स्टूडियो पहचानने में असमर्थ है Build.VERSION_CODES.O& WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY। मेरा लक्ष्यडासवर्क्स 26 है
गाबे ओ'लेरी

मेरी तरफ से आपकी सहायता +1 की सराहना करें।
सेविंग

@ GabeO'Leary मैं एक ही मुद्दे का सामना कर रहा हूं, क्या आपके पास इसके लिए समाधान है?
सागर

49

मैंने इस मुद्दे के लिए उपलब्ध सभी उदाहरणों को आज़माने की पूरी कोशिश की। अंत में मुझे इस बात का जवाब मिला कि मुझे पता है कि यह कितना विश्वसनीय है, लेकिन मेरा ऐप अब क्रैश नहीं हो रहा है।

windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
    //here is all the science of params
    final LayoutParams myParams = new LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            LayoutParams.TYPE_SYSTEM_ERROR,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
            PixelFormat.TRANSLUCENT
    );

अपनी मैनिफ़ेस्ट फ़ाइल में केवल अनुमति दें

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

इसके अलावा आप एपीआई स्तर के लिए भी जांच कर सकते हैं अगर उसका = = 23 है

 if(Build.VERSION.SDK_INT >= 23) {
    if (!Settings.canDrawOverlays(Activity.this)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, 1234);
    }
}
            else
{
    Intent intent = new Intent(Activity.this, Service.class);
    startService(intent);
}

मुझे उम्मीद है कि यह कहीं न कहीं किसी की मदद करता है। पूर्ण उदाहरण https://anam-android-codes.blogspot.in/?m=1


13

8.0.0 के एंड्रॉइड एपीआई स्तर के लिए, आपको उपयोग करना चाहिए

WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

के बजाय

LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL

या SYSTEM_ALERT


TYPE_APPLICATION_OVERLAY Android Studio में प्रस्तुत विकल्पों की सूची में नहीं है। मुझे "प्रतीक प्रकार को हल नहीं किया जा सकता है"। मैं क्या खो रहा हूँ?
फिल्क्रूज २१'१

11

पूरी तरह से काम कर रहे इस कोड का प्रयास करें

int layout_parms;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 

    {  
         layout_parms = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

    }

     else {

            layout_parms = WindowManager.LayoutParams.TYPE_PHONE;

    }

    yourparams = new WindowManager.LayoutParams(       
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            layout_parms,
            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

आपने मेरी जान बचाई
Fo Nko

@BakaWaii जहाँ आप इस कोड डाल करने के लिए विजेट दिखाना चाहते हैं वहाँ से कार्य करेंगे
shakirullah Orakzai

6

खोज

अन्य ऐप्स पर ड्रा करें

अपनी सेटिंग में और अपने ऐप को सक्षम करें। Android 8 ओरियो के लिए, प्रयास करें

सेटिंग्स> एप्लिकेशन और सूचनाएं> ऐप जानकारी> अन्य एप्लिकेशन पर प्रदर्शित करें> सक्षम करें


1
आप एक जीवन रक्षक हैं
नूर हुसैन

5

सबसे पहले आप यह सुनिश्चित करें कि आपने मैनिफ़ेस्ट फ़ाइल में अनुमति दी है।

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

जांचें कि क्या एप्लिकेशन ने अन्य एप्लिकेशन की अनुमति दी है या नहीं? यह अनुमति API <23 के लिए डिफ़ॉल्ट रूप से उपलब्ध है। लेकिन API> 23 के लिए आपको रनटाइम में अनुमति मांगनी होगी।

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {

    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 1);
} 

इस कोड का उपयोग करें:

public class ChatHeadService extends Service {

private WindowManager mWindowManager;
private View mChatHeadView;

WindowManager.LayoutParams params;

public ChatHeadService() {
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

    Language language = new Language();
    //Inflate the chat head layout we created
    mChatHeadView = LayoutInflater.from(this).inflate(R.layout.dialog_incoming_call, null);


    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        params.x = 0;
        params.y = 100;
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mChatHeadView, params);

    } else {
        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                PixelFormat.TRANSLUCENT);


        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
        params.x = 0;
        params.y = 100;
        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mWindowManager.addView(mChatHeadView, params);
    }

    TextView tvTitle=mChatHeadView.findViewById(R.id.tvTitle);
    tvTitle.setText("Incoming Call");

    //Set the close button.
    Button btnReject = (Button) mChatHeadView.findViewById(R.id.btnReject);
    btnReject.setText(language.getText(R.string.reject));
    btnReject.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //close the service and remove the chat head from the window
            stopSelf();
        }
    });

    //Drag and move chat head using user's touch action.
    final Button btnAccept = (Button) mChatHeadView.findViewById(R.id.btnAccept);
    btnAccept.setText(language.getText(R.string.accept));


    LinearLayout linearLayoutMain=mChatHeadView.findViewById(R.id.linearLayoutMain);



    linearLayoutMain.setOnTouchListener(new View.OnTouchListener() {
        private int lastAction;
        private int initialX;
        private int initialY;
        private float initialTouchX;
        private float initialTouchY;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:

                    //remember the initial position.
                    initialX = params.x;
                    initialY = params.y;

                    //get the touch location
                    initialTouchX = event.getRawX();
                    initialTouchY = event.getRawY();

                    lastAction = event.getAction();
                    return true;
                case MotionEvent.ACTION_UP:
                    //As we implemented on touch listener with ACTION_MOVE,
                    //we have to check if the previous action was ACTION_DOWN
                    //to identify if the user clicked the view or not.
                    if (lastAction == MotionEvent.ACTION_DOWN) {
                        //Open the chat conversation click.
                        Intent intent = new Intent(ChatHeadService.this, HomeActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);

                        //close the service and remove the chat heads
                        stopSelf();
                    }
                    lastAction = event.getAction();
                    return true;
                case MotionEvent.ACTION_MOVE:
                    //Calculate the X and Y coordinates of the view.
                    params.x = initialX + (int) (event.getRawX() - initialTouchX);
                    params.y = initialY + (int) (event.getRawY() - initialTouchY);

                    //Update the layout with new X & Y coordinate
                    mWindowManager.updateViewLayout(mChatHeadView, params);
                    lastAction = event.getAction();
                    return true;
            }
            return false;
        }
    });
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (mChatHeadView != null) mWindowManager.removeView(mChatHeadView);
}

}


क्या आप अपने xml कोड को साझा कर सकते हैं और github में देख सकते हैं या कुछ और यह मेरे लिए उपयोगी होगा।
पावेल

4

Android O के साथ संगत बनाने के लिए अपने प्रोजेक्ट में अपने झंडे Windowmanger का झंडा "TYPE_SYSTEM_OVERLAY" को "TYPE_APPLICATION_OVERLAY" में बदलें

WindowManager.LayoutParams.TYPE_PHONE सेवा WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY


3

मैंने अंततः लॉक स्क्रीन पर एक विंडो प्रदर्शित करने का प्रबंधन किया TYPE_SYSTEM_OVERLAYबजाय इसके उपयोग के साथTYPE_KEYGUARD_DIALOG । यह उम्मीद के मुताबिक काम करता है और लॉक स्क्रीन पर विंडो को जोड़ता है।

इसके साथ समस्या यह है कि खिड़की को संभवतः यह सब कुछ के शीर्ष पर जोड़ा जाता है यही है, विंडो भी सुरक्षित लॉक स्क्रीन के मामले में आपके कीपैड / पैटर्न लॉक के ऊपर दिखाई देगी। असुरक्षित लॉक स्क्रीन के मामले में, यह अधिसूचना ट्रे के शीर्ष पर दिखाई देगा यदि आप इसे लॉक स्क्रीन से खोलते हैं।

मेरे लिए, वह अस्वीकार्य है। मुझे उम्मीद है कि यह किसी और को इस समस्या का सामना करने में मदद कर सकता है।


समाधान के लिए बहुत बहुत धन्यवाद। क्या इसे खारिज करने का कोई तरीका है? जब मैं इसे जोड़ता हूं तो मैं संवाद को खारिज नहीं कर सकता TYPE_SYSTEM_OVERLAY। AlertDialog पर मेरा setOnDismissListener नहीं मिल रहा है।
टॉम टेलर

3

मैंने बस WindowManagerनिम्नलिखित चरणों के साथ सरल दृश्य जोड़ा :

  1. दिखाने के लिए एक लेआउट फ़ाइल बनाएँ (मेरे मामले में dummy_layout)
  2. प्रकट और गतिशील रूप से अनुमति जोड़ें।
// 1. Show view
private void showCustomPopupMenu()
{
    windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
    // LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // View view = layoutInflater.inflate(R.layout.dummy_layout, null);
    ViewGroup valetModeWindow = (ViewGroup) View.inflate(this, R.layout.dummy_layout, null);
    int LAYOUT_FLAG;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
    } else {
        LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
    }
    WindowManager.LayoutParams params=new WindowManager.LayoutParams(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        LAYOUT_FLAG,
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
        PixelFormat.TRANSLUCENT);

    params.gravity= Gravity.CENTER|Gravity.CENTER;
    params.x=0;
    params.y=0;
    windowManager.addView(valetModeWindow, params);
}

// 2. Get permissions by asking
if (!Settings.canDrawOverlays(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 1234);
}

इससे आप WM में एक दृश्य जोड़ सकते हैं।

पाई में परीक्षण किया गया।


2

लेआउटपार्म्स .YPE_PHONE को हटा दिया गया है। मैंने अपना कोड इस तरह से अपडेट किया है।

parameters = if (Build.VERSION.SDK_INT > 25) {
        LayoutParams(
                minHW * 2 / 3, minHW * 2 / 3,
                LayoutParams.TYPE_APPLICATION_OVERLAY,
                LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT)
    }else {
        LayoutParams(
                minHW * 2 / 3, minHW * 2 / 3,
                LayoutParams.TYPE_PHONE,
                LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT)
    }

LayoutParams.TYPE_APPLICATION_OVERLAY को 26 या उससे अधिक के स्तर की आवश्यकता है।


0

अनुमति देने से इनकार करने का मुख्य कारण यह है कि हमारे पास किसी अन्य एप्लिकेशन को खींचने की अनुमति नहीं है, हमें अन्य एप्लिकेशन पर ड्राइंग के लिए अनुमति प्रदान करनी होगी जो निम्नलिखित कोड द्वारा किया जा सकता है

अनुमति के लिए अनुरोध कोड

    public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;

इसे अपने MainActivity में जोड़ें


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
            askPermission();
}


private void askPermission() {
        Intent intent= new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:"+getPackageName()));
        startActivityForResult(intent,ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
}

इसे भी जोड़ें

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE){
            if(!Settings.canDrawOverlays(this)){
                askPermission();
            }
        }
    }


0

मैं के साथ काम कर रहे समाधान खोजने के लिए संघर्ष किया ApplicationContextऔर TYPE_SYSTEM_ALERTऔर समाधान भ्रमित पाया, मामले में आप चाहते हैं संवाद किसी भी गतिविधि से खोला जाना चाहिए भी संवाद है एक आप उपयोग करने के लिए है सिंगलटन getApplicationContext(), और अगर चाहते हैं संवाद होना चाहिएTYPE_SYSTEM_ALERT तो आप निम्न चरणों की आवश्यकता होगी :

पहले सही विषय के साथ संवाद का उदाहरण प्राप्त करें, आपको संस्करण संगतता का प्रबंधन करने की आवश्यकता है जैसा कि मैंने अपने निम्नलिखित स्निपेट में किया था:

AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext(), R.style.Theme_AppCompat_Light);

शीर्षक, संदेश और बटन सेट करने के बाद आपको डायलॉग बनाना होगा:

AlertDialog alert = builder.create();

अब typeयहां मुख्य रोल निभाता है, क्योंकि यह दुर्घटना का कारण है, मैंने निम्नलिखित के रूप में संगतता को संभाला:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        alert.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY - 1);

    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        alert.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    }

नोट : यदि आप AppCompatDialogनीचे के रूप में एक कस्टम संवाद का उपयोग कर रहे हैं:

AppCompatDialog dialog = new AppCompatDialog(getApplicationContext(), R.style.Theme_AppCompat_Light);

आप AppCompatDialogनिम्न प्रकार से सीधे अपने प्रकार को परिभाषित कर सकते हैं :

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY - 1);

    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    }

प्रकट अनुमति जोड़ना न भूलें:

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

0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.START | Gravity.TOP;
    params.x = left;
    params.y = top;
    windowManager.addView(view, params);

} else {
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            PixelFormat.TRANSLUCENT);


    params.gravity = Gravity.START | Gravity.TOP;
    params.x = left;
    params.y = top;
    windowManager.addView(view, params);
}

0

सुनिश्चित करें कि WindowManager.LayoutParams.TYPE_SYSTEM_ERRORओएस संस्करण <Oreo के लिए जोड़ा गया है क्योंकि यह पदावनत किया गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.