programing

시스템 오버레이 창 만들기(항상 맨 위에 있음)

powerit 2023. 8. 11. 22:42
반응형

시스템 오버레이 창 만들기(항상 맨 위에 있음)

항상 모든 창 위에 있는 항상 작동식 버튼/클릭 가능한 이미지를 만들려고 합니다.

개념 증명은.

저는 성공적이었고 지금은 서비스를 실행하고 있습니다.이 서비스는 화면 왼쪽 상단에 항상 일부 텍스트를 표시하고 사용자는 일반적인 방식으로 나머지 앱과 자유롭게 상호 작용할 수 있습니다.

제가하일는하클다니입래스입니다.ViewGroup window manager에 추가합니다.TYPE_SYSTEM_OVERLAY이제 이 텍스트 대신 터치 이벤트를 수신할 수 있는 버튼/클릭 가능 이미지를 추가하려고 합니다.는 전체 "onTouchEvent"에 ".ViewGroup이벤트를 수신하지 않습니다.

항상 표시되는 보기 그룹의 특정 부분에서만 이벤트를 수신하려면 어떻게 해야 합니까?제안해 주세요.

public class HUD extends Service {
    HUDView mView;

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

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
        mView = new HUDView(this);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                0,
//              WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//                      | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.RIGHT | Gravity.TOP;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mView, params);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show();
        if(mView != null)
        {
            ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
            mView = null;
        }
    }
}

class HUDView extends ViewGroup {
    private Paint mLoadPaint;

    public HUDView(Context context) {
        super(context);
        Toast.makeText(getContext(),"HUDView", Toast.LENGTH_LONG).show();

        mLoadPaint = new Paint();
        mLoadPaint.setAntiAlias(true);
        mLoadPaint.setTextSize(10);
        mLoadPaint.setARGB(255, 255, 0, 0);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText("Hello World", 5, 15, mLoadPaint);
    }

    @Override
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //return super.onTouchEvent(event);
        Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
        return true;
    }
}

이것은 어리석은 해결책일 수도 있습니다.하지만 그것은 효과가 있다.당신이 개선할 수 있다면 저에게 알려주시기 바랍니다.

서비스 생성 시:사용한 적이 있습니다.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCHflag.service.flag의 입니다. 이것이 서비스의 유일한 변경 사항입니다.

@Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
        mView = new HUDView(this);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.RIGHT | Gravity.TOP;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mView, params);
    }

이제 클릭 이벤트가 하나씩 표시됩니다.따라서 이벤트 핸들러를 수정해야 합니다.

View Group 터치 이벤트에서

@Override
public boolean onTouchEvent(MotionEvent event) {

    // ATTENTION: GET THE X,Y OF EVENT FROM THE PARAMETER
    // THEN CHECK IF THAT IS INSIDE YOUR DESIRED AREA


    Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
    return true;
}

또한 이 권한을 매니페스트에 추가해야 할 수도 있습니다.

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

@에 따라 4의 외부 하지만, @Sam Lu의 Android 4.x와 유형의 경우에는 외부 이벤트를 들을 수 없습니다.TYPE_SYSTEM_ALERT여전히 그 일을 합니다.

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);

    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    View myView = inflater.inflate(R.layout.my_view, null);
    myView.setOnTouchListener(new OnTouchListener() {
       @Override
       public boolean onTouch(View v, MotionEvent event) {
           Log.d(TAG, "touch me");
           return true;
       }
     });

    // Add layout to window manager
    wm.addView(myView, params);

권한

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

.x부터 은 새로운 Android 4.x를 했습니다.adjustWindowParamsLw()그것이 추가될 것입니다.FLAG_NOT_FOCUSABLE,FLAG_NOT_TOUCHABLE 거제를 제거합니다.FLAG_WATCH_OUTSIDE_TOUCH의 깃발TYPE_SYSTEM_OVERLAY창문들.

즉, a입니다.TYPE_SYSTEM_OVERLAY에서 터치 사용하기 는 ICS 플랫폼에서 이벤트를 받지 않습니다.TYPE_SYSTEM_OVERLAYICS 및 향후 장치에 사용할 수 있는 솔루션이 아닙니다.

저는 Toolliap SDK 개발자 중 한 명입니다.우리는 또한 개발자가 항상 상단 창과 버튼에 표시할 수 있는 방법을 제공하며 유사한 상황에 대처했습니다.

여기서 답이 다루지 않은 한 가지 문제는 안드로이드 "보안 버튼"입니다.

에는 보버에는다있다니습이음튼이 있습니다.filterTouchesWhenObscured속성은 창 아래에 배치된 경우 해당 창이 터치를 받지 않더라도 상호 작용할 수 없음을 의미합니다.Android 설명서 인용:

뷰의 창이 다른 보이는 창에 가려질 때 터치를 필터링할지 여부를 지정합니다.true로 설정하면 보기 창 위에 토스트, 대화 상자 또는 기타 창이 나타날 때마다 보기에 터치가 표시되지 않습니다.{@link Android.view를 참조하십시오.자세한 내용은 보안 설명서를 참조하십시오.

이러한 버튼의 예로는 타사 앱을 설치하려고 할 때의 설치 버튼이 있습니다.보기 레이아웃에 다음 줄을 추가하면 모든 앱에서 이러한 버튼을 표시할 수 있습니다.

android:filterTouchesWhenObscured="true"

보안 단추 위에 항상 표시되는 창을 "보안 단추" 위에 표시하면 오버레이가 있는 모든 보안 단추 부분은 해당 오버레이를 클릭할 수 없는 경우에도 터치를 처리하지 않습니다.따라서 이러한 창을 표시하려면 사용자가 창을 이동하거나 해제할 수 있는 방법을 제공해야 합니다.오버레이의 일부가 투명한 경우 사용자가 기본 앱의 특정 버튼이 갑자기 작동하지 않는 이유를 혼동할 수 있다는 점을 고려하십시오.

항상 상단 이미지 버튼에서 작업

우선 제 영어실력에 대해 죄송합니다.

나는 당신의 코드를 편집하고 그의 터치 이벤트를 듣는 작동 이미지 버튼이 그의 배경 요소에 터치 컨트롤을 주지 않도록 합니다.

또한 그것은 다른 요소들 중에서 청취자들에게 터치를 줍니다.

버튼 정렬이 아래쪽과 왼쪽입니다.

정렬을 변경할 수 있지만 if 요소의 터치 이벤트에서 코디나트를 변경해야 합니다.

import android.annotation.SuppressLint;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;

public class HepUstte extends Service {
    HUDView mView;

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

        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();

        final Bitmap kangoo = BitmapFactory.decodeResource(getResources(),
                R.drawable.logo_l);


        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                kangoo.getWidth(), 
                kangoo.getHeight(),
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                 PixelFormat.TRANSLUCENT);






        params.gravity = Gravity.LEFT | Gravity.BOTTOM;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);



        mView = new HUDView(this,kangoo);

        mView.setOnTouchListener(new OnTouchListener() {


            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                // TODO Auto-generated method stub
                //Log.e("kordinatlar", arg1.getX()+":"+arg1.getY()+":"+display.getHeight()+":"+kangoo.getHeight());
                if(arg1.getX()<kangoo.getWidth() & arg1.getY()>0)
                {
                 Log.d("tıklandı", "touch me");
                }
                return false;
            }
             });


        wm.addView(mView, params);



        }



    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

}



@SuppressLint("DrawAllocation")
class HUDView extends ViewGroup {


    Bitmap kangoo;

    public HUDView(Context context,Bitmap kangoo) {
        super(context);

        this.kangoo=kangoo;



    }


    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);


        // delete below line if you want transparent back color, but to understand the sizes use back color
        canvas.drawColor(Color.BLACK);

        canvas.drawBitmap(kangoo,0 , 0, null); 


        //canvas.drawText("Hello World", 5, 15, mLoadPaint);

    }


    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
    }

    public boolean onTouchEvent(MotionEvent event) {
        //return super.onTouchEvent(event);
       // Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();

        return true;
    }
}

TYPE_SYSTEM_OVERLAY상수가 API 레벨 26 이후로 더 이상 사용되지 않습니다. 사용TYPE_APPLICATION_OVERLAY대신.

Android 8 이하 및 그 이상의 사용자:

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

이거 먹어봐요.ICS에서 잘 작동합니다.서비스를 중지하려면 상태 표시줄에 생성된 알림을 클릭하십시오.

 public class HUD extends Service
 {
    protected boolean foreground = false;
    protected boolean cancelNotification = false;
    private Notification notification;
    private View myView;
    protected int id = 0;
    private WindowManager wm;
    private WindowManager.LayoutParams params;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
       // System.exit(0);
        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_SHORT).show();
        params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
        params.gravity=Gravity.TOP|Gravity.LEFT;
    wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    inflateview();
    foregroundNotification(1);
    //moveToForeground(1,n,true);
    }     
   @Override
    public void onDestroy() {
        super.onDestroy();
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(0);
        Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_SHORT).show();
        if(myView != null)
        {
            ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(myView);
            myView = null;
        }
    }
    protected Notification foregroundNotification(int notificationId) 
   {    
    notification = new Notification(R.drawable.ic_launcher, "my Notification", System.currentTimeMillis());    
        notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_ONLY_ALERT_ONCE;   
        notification.setLatestEventInfo(this, "my Notification", "my Notification", notificationIntent());          
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(id, notification);            
        return notification;
    }
    private PendingIntent notificationIntent() {
        Intent intent = new Intent(this, stopservice.class);    
        PendingIntent pending = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);    
        return pending;
    }
    public void inflateview()
    {
         LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            myView = inflater.inflate(R.layout.activity_button, null);
            myView.setOnTouchListener(new OnTouchListener() {
               @Override
               public boolean onTouch(View v, MotionEvent event) {
                   Toast.makeText(getBaseContext(),"onToasttt", Toast.LENGTH_SHORT).show();
                   return false;
               }
             });
            // Add layout to window manager
            wm.addView(myView, params); 
    }
}

갱신하다

여기 샘플

오버레이 보기를 만들려면 LayoutParams를 설정할 때 유형을 TYPE_SYSTEM_OVERLAY로 설정하지 마십시오.

Instead set it to TYPE_PHONE.

Use the following flags:

FLAG_NOT_TOUCH_MODAL

FLAG_WATCH_OUTSIDE_TOUCH

실제로 WindowManager를 사용해 볼 수 있습니다.레이아웃 매개 변수.TYPE_SYSTEM_OVERLAY 대신 TYPE_SYSTEM_ERROR.해킹처럼 들릴 수도 있지만 모든 것 위에 보기를 표시하고 터치 이벤트를 받을 수 있습니다.

바로 그런 기능을 하는 라이브러리를 찾았습니다. https://github.com/recruit-lifestyle/FloatingView

루트 폴더에 샘플 프로젝트가 있습니다.제가 실행했고 필요에 따라 작동합니다.다른 앱이라도 배경을 클릭할 수 있습니다.

enter image description here

여기 간단한 해결책이 있습니다. 목록 어댑터에서처럼 XML 레이아웃을 부풀리기만 하면 됩니다. XML 레이아웃을 부풀리기만 하면 됩니다.여기 당신이 필요한 코드가 있습니다.

 public class HUD extends Service {
    View mView;

    LayoutInflater inflate;
    TextView t;
    Button b;

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

        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();


        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);

        Display display = wm.getDefaultDisplay();  get phone display size
        int width = display.getWidth();  // deprecated - get phone display width
        int height = display.getHeight(); // deprecated - get phone display height 


        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                width, 
                height,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                 PixelFormat.TRANSLUCENT);


        params.gravity = Gravity.LEFT | Gravity.CENTER;
        params.setTitle("Load Average");

        inflate = (LayoutInflater) getBaseContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        mView = inflate.inflate(R.layout.canvas, null);

        b =  (Button) mView.findViewById(R.id.button1);
        t = (TextView) mView.findViewById(R.id.textView1);
        b.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            t.setText("yes you click me ");
        }
       });

        wm.addView(mView, params);

        }



    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

}

권한 "안드로이드"를 사용합니다.허가.시스템_경보_이 링크에 대한 WINDOW" 전체 튜토리얼: http://androidsrc.net/facebook-chat-like-floating-chat-heads/

이것은 오래된 질문이지만 최근 안드로이드는 버블을 지원합니다.버블은 곧 출시될 예정이지만 현재 개발자들이 사용을 시작할 수 있습니다.사용의 대안이 되도록 설계되었습니다.SYSTEM_ALERT_WINDOW(Facebook Messenger 와 MusiXMatch 와동념을사니합용다앱개같은는일한와▁mus▁(book앱ichx와mface같은)▁messenger는)

Bubbles

알림 API를 통해 버블이 생성되면 알림을 정상적으로 전송합니다.버블링을 하려면 추가 데이터를 첨부해야 합니다.버블에 대한 자세한 내용은 버블에 대한 공식 Android 개발자 가이드를 참조하십시오.

제 코드를 사용해 보세요. 적어도 오버레이로 문자열을 제공합니다. 버튼이나 이미지로 매우 잘 대체할 수 있습니다.너는 이것이 나의 첫 안드로이드 앱이라는 것을 믿지 못할 것입니다. 하하.어쨌든 당신이 나보다 안드로이드 앱에 경험이 많다면 시도해 보세요.

  • 새 창 관리자에서 매개 변수 2와 3을 변경합니다.레이아웃 매개변수"
  • 다른 이벤트 접근법을 시도합니다.

아직 이 스레드를 읽고 있지만 작동하지 않는 사람이 있다면 안드로이드 >=4.2에서 모션 이벤트를 가로채는 방법이 버그 및 수정으로 간주된다는 점을 알려드리게 되어 매우 유감입니다.

ACTION_OUTSIDENT로 동작하지만 getX와 getY에서 0을 반환합니다.이는 화면에서 모든 모션 위치를 볼 수 없고 아무것도 할 수 없다는 것을 의미합니다.의사가 x와 y를 얻을 것이라고 말한 것은 알지만, 사실은 그렇지 않을 것입니다.이것은 키 로거를 차단하기 위한 것으로 보입니다.

해결 방법이 있는 사람이 있으면 의견을 남겨 주십시오.

ref: ACTION_OUTOSIDE는 KitKat 4.4.2에서 매번 0을 반환합니까?

https://code.google.com/p/android/issues/detail?id=72746

서비스를 사용하면 다음과 같은 이점을 얻을 수 있습니다.

public class PopupService extends Service{

    private static final String TAG = PopupService.class.getSimpleName();
    WindowManager mWindowManager;
    View mView;
    String type ;

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        registerOverlayReceiver();
        type = intent.getStringExtra("type");
        Utils.printLog("type = "+type);
        showDialog(intent.getStringExtra("msg"));
        return super.onStartCommand(intent, flags, startId);
    }

    private void showDialog(String aTitle)
    {
        if(type.equals("when screen is off") | type.equals("always"))
        {
            Utils.printLog("type = "+type);
            PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
            WakeLock mWakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "YourServie");
            mWakeLock.acquire();
            mWakeLock.release();
        }

        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mView = View.inflate(getApplicationContext(), R.layout.dialog_popup_notification_received, null);
        mView.setTag(TAG);

        int top = getApplicationContext().getResources().getDisplayMetrics().heightPixels / 2;

        LinearLayout dialog = (LinearLayout) mView.findViewById(R.id.pop_exit);
//        android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) dialog.getLayoutParams();
//        lp.topMargin = top;
//        lp.bottomMargin = top;
//        mView.setLayoutParams(lp);

        final EditText etMassage = (EditText) mView.findViewById(R.id.editTextInPopupMessageReceived);

        ImageButton imageButtonSend = (ImageButton) mView.findViewById(R.id.imageButtonSendInPopupMessageReceived);
//        lp = (LayoutParams) imageButton.getLayoutParams();
//        lp.topMargin = top - 58;
//        imageButton.setLayoutParams(lp);
        imageButtonSend.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Utils.printLog("clicked");
//                mView.setVisibility(View.INVISIBLE);
                if(!etMassage.getText().toString().equals(""))
                {
                    Utils.printLog("sent");
                    etMassage.setText("");
                }
            }
        });

        TextView close = (TextView) mView.findViewById(R.id.TextViewCloseInPopupMessageReceived);
        close.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                hideDialog();   
            }
        });

        TextView view = (TextView) mView.findViewById(R.id.textviewViewInPopupMessageReceived);
        view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                hideDialog();   
            }
        });

        TextView message = (TextView) mView.findViewById(R.id.TextViewMessageInPopupMessageReceived);
        message.setText(aTitle);

        final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
        WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
//                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ,
        PixelFormat.RGBA_8888);

        mView.setVisibility(View.VISIBLE);
        mWindowManager.addView(mView, mLayoutParams);
        mWindowManager.updateViewLayout(mView, mLayoutParams);

    }

    private void hideDialog(){
        if(mView != null && mWindowManager != null){
            mWindowManager.removeView(mView);
            mView = null;
        }
    }
}

@Sarwar Erfan의 대답은 Android가 Window Manager로 보기를 추가하는 것을 허용하지 않기 때문에 더 이상 작동하지 않습니다.레이아웃 매개 변수.TYPE_SYSTEM_OVERLAY를 창 관리자조차 사용하지 않고 더 이상 터치할 수 있습니다.레이아웃 매개 변수.플래그_WATCH_OUTCH_OUTCH.

저는 이 문제에 대한 해결책을 찾았습니다.다음 질문에서 확인할 수 있습니다.

WindowManager를 사용하여 창에 보기를 추가할 수 있습니다.레이아웃 매개 변수.TYPE_SYSTEM_OVERLAY, 터치 이벤트를 수신하지 않습니다.

TYPE_SYSTEM_OVERLAY더 이상 사용되지 않으며 권한 거부 오류가 발생합니다. 사용WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY대신.

WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL당신이 찾고 있는 것일 수도 있습니다.

Window 플래그: 이 창이 포커스 가능한 경우에도(그것의FLAG_NOT_FOCUSABLEis not set), 창 밖의 포인터 이벤트를 뒤의 창으로 보낼 수 있습니다.그렇지 않으면 창 내부에 있는지 여부에 관계없이 모든 포인터 이벤트 자체를 사용합니다.

문서

시행하다View.OnClickListener또는View.onTouchListener터치 이벤트를 청취합니다.

언급URL : https://stackoverflow.com/questions/4481226/creating-a-system-overlay-window-always-on-top

반응형