본문 바로가기
Development/Android

[android] 다른앱 위에 뷰(floating view) 띄우기

by Sonagiya 2021. 4. 1.
반응형

 

시연영상

 

  • manifest 에 퍼미션 추가하기
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission>

 

  • 다른앱위에 그리기 권한 획득하기
    • 권한요청을 위해 startActivityForResult 를 사용하지만 앞으로 사용을 권장하는 registerForActivityResult 를 사용

아직 안정화버전에 배포되지 않아 알파 또는 베타버전을 활용해야 한다.

https://developer.android.com/jetpack/androidx/releases/appcompat?hl=ko#version_130_2

    private val overlayActivityResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        if (Settings.canDrawOverlays(this)) {
            if (floatingView.parent == null) windowManager.addView(floatingView, param)
        }
    }
    
    private fun show() {
        if (Settings.canDrawOverlays(this)) {
            if (floatingView.parent == null) windowManager.addView(floatingView, param)
        } else {
            val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                "package:$packageName".toUri()
            )

            overlayActivityResult.launch(intent)
        }
    }

 

  • 뷰 터치이벤트로 이동시키기
    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {

        when(event?.action) {
            MotionEvent.ACTION_DOWN -> {
                dx = wLayoutParams.x - event.rawX
                dy = wLayoutParams.y - event.rawY
            }
            MotionEvent.ACTION_MOVE -> {
                wLayoutParams.x = (dx + event.rawX).toInt()
                wLayoutParams.y = (dy + event.rawY).toInt()

                windowManager.updateViewLayout(this@FloatingView, layoutParams)
            }
            MotionEvent.ACTION_UP -> {

            }
        }

        return super.onTouchEvent(event)
    }

 

  • 뷰 추가/제거 하기
    private fun show() {
        if (Settings.canDrawOverlays(this)) {
            if (floatingView.parent == null) windowManager.addView(floatingView, param)
        } else {
            val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                "package:$packageName".toUri()
            )

            overlayActivityResult.launch(intent)
        }
    }

    private fun hide() {
        if (floatingView.parent != null) windowManager.removeView(floatingView)
    }

 

 

반응형

댓글