title: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
body: <p>I have an application for recording a screen, it does not work on android version 10. As I understand it, this is due to privacy changes in force in Android 10. I added the permission <code>&lt;uses-permission android:name="android.permission.FOREGROUND_SERVICE" /&gt;</code> to my manifest file, added the <code>android:foregroundServiceType="mediaProjection"</code> tag to the service and call the <code>startForeground()</code> method</p>
  
  <pre><code>Notification.Builder builder = new Notification.Builder(getApplicationContext(), "333")
                  .setContentTitle(getString(R.string.app_name))
                  .setContentText("Record")
                  .setAutoCancel(true);
  
          Notification notification = builder.build();
  
          startForeground(123, notification);
  </code></pre>
  
  <p>before calling the <code>.getMediaProjection()</code> method, but my application still throws an error exactly</p>
  
  <pre><code>E/AndroidRuntime: FATAL EXCEPTION: main
      Process: com.example.screen_recording, PID: 9572
      java.lang.RuntimeException: Unable to start service com.example.screen_recording.service.RecordService@bb31978 with Intent { cmp=com.example.screen_recording/.service.RecordService (has extras) }: java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
          at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4105)
          at android.app.ActivityThread.access$1800(ActivityThread.java:219)
          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
          at android.os.Handler.dispatchMessage(Handler.java:107)
          at android.os.Looper.loop(Looper.java:214)
          at android.app.ActivityThread.main(ActivityThread.java:7356)
          at java.lang.reflect.Method.invoke(Native Method)
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
       Caused by: java.lang.SecurityException: Media projections require a foreground service of type ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION
          at android.os.Parcel.createException(Parcel.java:2071)
          at android.os.Parcel.readException(Parcel.java:2039)
          at android.os.Parcel.readException(Parcel.java:1987)
          at android.media.projection.IMediaProjection$Stub$Proxy.start(IMediaProjection.java:231)
          at android.media.projection.MediaProjection.&lt;init&gt;(MediaProjection.java:58)
          at android.media.projection.MediaProjectionManager.getMediaProjection(MediaProjectionManager.java:104)
          at com.example.screen_recording.service.RecordService.onStartRecord(RecordService.java:117)
          at com.example.screen_recording.service.RecordService.onStartCommand(RecordService.java:106)
          at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4087)
          at android.app.ActivityThread.access$1800(ActivityThread.java:219) 
          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
          at android.os.Handler.dispatchMessage(Handler.java:107) 
          at android.os.Looper.loop(Looper.java:214) 
          at android.app.ActivityThread.main(ActivityThread.java:7356) 
          at java.lang.reflect.Method.invoke(Native Method) 
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
       Caused by: android.os.RemoteException: Remote stack trace:
          at com.android.server.media.projection.MediaProjectionManagerService$MediaProjection.start(MediaProjectionManagerService.java:476)
          at android.media.projection.IMediaProjection$Stub.onTransact(IMediaProjection.java:135)
          at android.os.Binder.execTransactInternal(Binder.java:1021)
          at android.os.Binder.execTransact(Binder.java:994)
  </code></pre>
  
  <p>Here is the service code</p>
  
  <pre><code>public class RecordService extends Service {
      @Override
      public IBinder onBind(Intent intent) {
          // TODO: Return the communication channel to the service.
          throw new UnsupportedOperationException("Not yet implemented");
      }
  
      SharedPreferences p;
      WindowManager window;
  
      private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
      private boolean isRecord = false;
      private String videoUri = "";
  
      private MediaProjectionManager mediaProjectionManager;
      private MediaProjection mediaProjection;
      private VirtualDisplay virtualDisplay;
      private MediaRecorder mediaRecorder;
  
      private int mScreenDensity;
      private static int DISPLAY_WIDTH;
      private static int DISPLAY_HEIGHT;
      private int resultCode;
      private Intent resultData;
  
      static {
          ORIENTATIONS.append(Surface.ROTATION_0, 90);
          ORIENTATIONS.append(Surface.ROTATION_90, 0);
          ORIENTATIONS.append(Surface.ROTATION_180, 270);
          ORIENTATIONS.append(Surface.ROTATION_270, 180);
      }
  
      @RequiresApi(api = Build.VERSION_CODES.O)
      @Override
      public void onCreate() {
          super.onCreate();
  
          Notification.Builder builder = new Notification.Builder(getApplicationContext(), "333")
                  .setContentTitle(getString(R.string.app_name))
                  .setContentText("Record")
                  .setAutoCancel(true);
  
          Notification notification = builder.build();
  
          startForeground(123, notification);
  
          p = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
          window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
  
          DisplayMetrics metrics = new DisplayMetrics();
          window.getDefaultDisplay().getMetrics(metrics);
          mScreenDensity = metrics.densityDpi;
          DISPLAY_WIDTH = metrics.widthPixels;
          DISPLAY_HEIGHT = metrics.heightPixels;
  
  
          mediaRecorder = new MediaRecorder();
          mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
  
      }
  
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
  
          if (intent.getAction() == null) {
              resultCode = intent.getIntExtra("code", 1337);
              resultData = intent.getParcelableExtra("data");
          }
  
          onStartRecord();
          return (START_NOT_STICKY);
      }
  
      @Override
      public void onDestroy() {
          onStopRecord();
          super.onDestroy();
      }
  
      private void onStartRecord() {
          mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, resultData);
  
          int quality = p.getInt("quality", 1080);
          boolean micro = p.getBoolean("micro", false);
          int fps = p.getInt("FPS", 60);
  
          initRecorder(quality, micro, fps);
          virtualDisplay = createVirtualDisplay();
  
          isRecord = true;
          p.edit().putBoolean("isRecord", isRecord).apply();
          mediaRecorder.start();
      }
  
      private void onStopRecord() {
          mediaRecorder.stop();
          mediaRecorder.reset();
  
          stopRecordScreen();
  
  
          isRecord = false;
          p.edit().putBoolean("isRecord", isRecord).apply();
      }
  
      private VirtualDisplay createVirtualDisplay() {
          return mediaProjection.createVirtualDisplay("MainFragment", DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
                  DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                  mediaRecorder.getSurface(), null, null);
      }
  
      private void initRecorder(int QUALITY, boolean isMicro, int fps) {
          try {
              int bitrateVideo = 0;
  
              switch (QUALITY) {
                  case 1080:
                      bitrateVideo = 7000000;
                      break;
                  case 720:
                      bitrateVideo = 4000000;
                      break;
                  default:
                      bitrateVideo = 2000000;
                      break;
              }
  
              if (isMicro) {
                  mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
              }
  
              mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
              mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  
              if (isMicro) {
                  mediaRecorder.setAudioSamplingRate(44100);
                  mediaRecorder.setAudioEncodingBitRate(16 * 44100);
                  mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
              }
  
  
              videoUri = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
                      + new StringBuilder("/FreeRecord_").append(new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss")
                      .format(new Date())).append(".mp4").toString();
  
              mediaRecorder.setOutputFile(videoUri);
              mediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
              mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
              mediaRecorder.setVideoEncodingBitRate(bitrateVideo);
              mediaRecorder.setCaptureRate(fps);
              mediaRecorder.setVideoFrameRate(fps);
  
              int rotation = window.getDefaultDisplay().getRotation();
              int orientation = ORIENTATIONS.get(rotation + 90);
              mediaRecorder.setOrientationHint(orientation);
              mediaRecorder.prepare();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  
      private void stopRecordScreen() {
          if (virtualDisplay == null) {
              return;
          }
          virtualDisplay.release();
          destroyMediaProject();
      }
  
      private void destroyMediaProject() {
          if (mediaProjection != null) {
              mediaProjection.stop();
              mediaProjection = null;
          }
      }
  }
  
  </code></pre>