Sitemap

[링크] MediaProjection — ForegroundService 이용하기(요약편)

4 min readMay 1, 2020

2016년에 작성한 MediaProjection 프로젝트를 수정하여, 수정하면서 달라진 부분과 MediaProjection 사용 시 달라진 점들을 살펴본다.

안드로이드 화면 캡쳐 API — MediaProjection 사용해보기 MediaProjection Example — MVP 패턴 적용

크게 달라진 부분을 제외하고, API는 위 2개의 글을 통해 확인이 가능하다.

MediaProjection 사용하기

MediaProjection, VirtualDisplay는 MediaProjectionManager를 이용하여 접근하고, 활용할 수 있다. MediaProjection 실시간으로 Display에 출력하는 데이터를 그대로 보여주는 역할을 하는데, 내부적으로 VirtualDisplay를 이용하여 화면 갱신을 돕는다.

실제 Display로 보내진느 데이터와 동일한 데이터를 VirtualDisplay에 올려주고 이를 개발자가 Surface를 이용하여 확인할 수 있는데, 보통 녹화할 때는 EGL을 이용하여 녹화하지만, 본 글에 사용한 샘플 코드는 Surface를 실제 화면에 노출하는 형태로 접근한다. 어디까지나 화면에 보이는지를 확인하기 위한 샘플 코드이다.

참고로 이와 동일한 화면은 개발자 옵션 > 보조 디스플레이 시뮬레이션에서 볼 수 있는것과 동일하다.

테스트 코드 주소

테스트 코드는 Android Studio 3.6.3+에서 동작합니다.

  • gradle : 3.6.3
  • kotlin : 1.3.72
  • targetSdk : 29
  • minSdk : 24
  • ViewBinding 활용

GitHub Example : MediaProjection example

MediaProjection 달라진 점

Google 내부의 MediaProjectionDemo를 통해 MediaProjectionDemo을 볼 수 있으나, 2016년에는 이 코드로 동작하는데 문제가 없었다.

하지만 Android 10/11이 나온 이 시점에서는 아래의 코드를 그대로 사용할때는 동작에 문제가 발생한다.

getMediaProjection 권한을 받으려면

위 샘플 코드와 과거 필자가 작성한 코드에서는 Activity에서 권한을 요청하고, onActivityResult로 이벤트를 받아 projectionManager.getMediaProjection()을 통해 MediaProjection을 생성하였었다.

하지만 Android 10부터는 foreground service가 아니라면 아래와 같은 오류가 발생하여 수정이 필요하다.

Caused by: java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION

이에 따른 전체 구조를 새로 작업 해보았다.

과거에는 Activity에서 MediaProjection의 권한을 획득하고, 그 권환을 이용하여 MediaProjection을 생성할 수 있었다.

이젠 foreground Service가 없다면 동작하지 않는 형태가 되어, Foreground Service를 먼저 생성하고, Activity에서는 권한을 획득하는 형태로 변경하였다.

마무리

추가로 작성한 글에서는 foregroundService 처리방법이 가장 중요하다. 그 부분 덕에 전체적인 구조가 변경되었다.

Activity의 용도는 권한을 받는 정도로 만 필요하게 되었고, 서비스 중심으로 동작하도록 변경되었다.

자세한 건 https://thdev.tech/androiddev/2020/05/01/Android-MediaProjection-New/에서 확인 가능하다.

GitHub Example : MediaProjection example

--

--

No responses yet