title: Android Service stops recording audio when app is killed
body: <p><strong>My problem changed a bit, please take a look at the EDIT 2 below</strong></p>
  
  <p>I am learning how to work with Services and audio recording on Android.</p>
  
  <p>I want to create an app, that will do nothing except starting a service: after requesting permissions (<code>RECORD_AUDIO</code>, <code>INTERNET</code>) the app only calls <code>startService()</code> from the <code>MainActivity</code>. </p>
  
  <p>The service will then record audio and stream it to given IP address. I took my inspiration for the audio streaming server and client from the answers to <a href="https://stackoverflow.com/questions/15349987/stream-live-android-audio-to-server">this question</a>. I am testing the app on Android 6.0 in the Android Studio Emulator so far. </p>
  
  <p>This is the <code>onStartCommand()</code> method of my service. I create a new thread where I wait until the user has clicked "Allow" in the permissions request dialog. When I receive the permissions I initialize the <code>AudioRecord</code> and then I read from it in a <code>while</code>-loop and send the data away.</p>
  
  <pre><code>@Override
  public int onStartCommand(Intent intent, int flags, int startId) {
      Thread streamThread = new Thread(new Runnable() {
  
          @Override
          public void run() {
              waitForPermissions();
              try {
                  DatagramSocket socket = new DatagramSocket();
                  byte[] buffer = new byte[minBufSize];
                  DatagramPacket packet;
                  final InetAddress destination = InetAddress.getByName(address);
                  recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, minBufSize * 10);
                  recorder.startRecording();
                  while (status == true) {
                      minBufSize = recorder.read(buffer, 0, buffer.length);
                      packet = new DatagramPacket(buffer, buffer.length, destination, port);
                      socket.send(packet);
                  }
              } catch (...) {...}
          }
      });
      streamThread.start();
      return START_STICKY;
  }
  </code></pre>
  
  <p>In <code>onDestroy()</code> I set the flag <code>status</code> to <code>false</code> so that the loop in the thread created in <code>onStartCommand()</code> terminates. Then I release the <code>recorder</code> so that it can be initialized and used again.</p>
  
  <pre><code>@Override      
  public void onDestroy(){
      status = false;
      recorder.stop();
      recorder.release();
      super.onDestroy();
  }
  </code></pre>
  
  <p>This app works works only partially:</p>
  
  <ul>
  <li>When I launch the listening server on the computer and the app in the emulator, I can hear the audio normally. </li>
  <li>When I minimize the app (tap Home button), the audio stream is still OK.    </li>
  <li><strong>My problem is</strong> that when I kill the app (swipe it right in the running apps screen), the audio stops. In the Logcat I can see that the service has been restarted and runs as usual (initializes the <code>AudioRecord</code> and everything, no exceptions thrown), only I can't hear anything. When I run the app again (and therefore call the <code>startService()</code> again), I see an exception in the Logcat telling me that the <code>AudioRecord</code> start failed with an error code -38 (meaning that the microphone is in use by the previous instance of the service).</li>
  </ul>
  
  <p>What am I doing wrong here? Why is the service running, but audio not streaming when I kill the app?</p>
  
  <p>Many thanks for your answers.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I know this approach won't work on newer Android versions. This app is just for private purposes and will be run on one of my old phones, either with Android 5.1.1 or 6.0.</p>
  
  <p>After I read the article in <a href="https://stackoverflow.com/a/58461878/6136143">this answer</a> I moved what was previously in <code>onDestroy</code> to <code>onTaskRemoved</code>. However, nothing changed. </p>
  
  <p>The Service is apparently <strong>still sending some packets</strong> after it is restarted. I looked at them in Wireshark and the packets are still leaving the device and the Server is still receiving them. The payload of the packets is nonzero, unique for every packet. </p>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>I changed the buffer size to <code>AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) * 10</code> in the Android app and <code>AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) * 20</code> in the Server application. Now when I swipe the app, the <code>Service</code> restarts and then I can hear some audio. But the sound is very chunky after the restart and I don't know why. It also gets chunky when I uninstall the app, keep the server running and then install and run the app again.</p>
  
  <p>So the problem is probably on the Server side. What could be the problem with the server? Am I working correctly with the <code>SourceDataLine</code>? The Server code looks like this (taken from <a href="https://stackoverflow.com/questions/15349987/stream-live-android-audio-to-server">here</a>):</p>
  
  <pre class="lang-java prettyprint-override"><code>...
  static int sampleRate = 8000;
  static int bufferLen = minBufSize * 20;
  
  public static void main(String args[]) throws Exception {
  
      DatagramSocket serverSocket = new DatagramSocket(port);
      byte[] receiveData = new byte[bufferLen];
      format = new AudioFormat(sampleRate, 16, 1, true, false);
      dataLineInfo = new DataLine.Info(SourceDataLine.class, format);
      sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
      sourceDataLine.open(format);
      sourceDataLine.start();
  
      FloatControl volumeControl = (FloatControl) sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN);
      volumeControl.setValue(volumeControl.getMaximum());
  
      while (status == true) {
          DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
          serverSocket.receive(receivePacket);
          toSpeaker(receivePacket.getData(), receivePacket.getLength());
      }
      sourceDataLine.drain();
      sourceDataLine.close();
  }
  public static void toSpeaker(byte soundbytes[], int length) {
      try {
          sourceDataLine.write(soundbytes, 0, length);
      } catch (...) {...}
  }
  ...
  </code></pre>
  
  <p>The sample rate of the server is identical to the Android app. Format is <code>AudioFormat.ENCODING_PCM_16BIT</code>.</p>