[Android Service在应用被杀死时停止录制音频

问题描述 投票:0回答:1

我正在学习如何在Android上使用服务和音频记录。

我想创建一个应用程序,除了启动服务之外什么也不会做:在请求权限(RECORD_AUDIOINTERNET)之后,该应用程序仅从startService()调用MainActivity

然后该服务将录制音频并将其流式传输到给定的IP地址。我从this question的答案中获得了音频流服务器和客户端的灵感。到目前为止,我正在Android Studio Emulator上的Android 6.0上测试该应用程序。

这是我的服务的onStartCommand()方法。我创建一个新线程,等待用户在权限请求对话框中单击“允许”。收到权限后,我将初始化AudioRecord,然后在while循环中从中读取并发送数据。

@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;
}

onDestroy()中,我将标志status设置为false,以便终止在onStartCommand()中创建的线程中的循环。然后,我松开recorder,以便可以对其进行初始化并再次使用。

@Override      
public void onDestroy(){
    status = false;
    recorder.stop();
    recorder.release();
    super.onDestroy();
}

此应用程序只能部分运行:

  • 当我在计算机上启动监听服务器并在模拟器中启动应用程序时,我可以正常听到音频。
  • 当我最小化应用程序时(点击“主页”按钮,音频流仍然可以。
  • 我的问题是,当我杀死该应用程序(在正在运行的应用程序屏幕中将其滑动)时,音频停止。在Logcat中,我可以看到该服务已重新启动并照常运行(初始化AudioRecord和所有内容,没有引发异常),只有我听不到任何声音。当我再次运行该应用程序(并因此再次调用startService())时,我在Logcat中看到一个异常,告诉我AudioRecord启动失败,错误代码为-38(这意味着前一个麦克风正在使用中)服务实例)。

我在这里做错了什么?为什么该服务正在运行,但是当我终止该应用程序时,音频却没有流过?

非常感谢您的回答。

编辑:

我知道这种方法不适用于较新的Android版本。这个应用程式仅供私人使用,可以在我的一部旧手机上执行(搭载Android 5.1.1或6.0)。

[阅读完this answer中的文章后,我将以前在onDestroy中的内容移至了onTaskRemoved。但是,什么都没有改变。

重新启动后,

该服务显然是仍在发送一些数据包。我在Wireshark中看着它们,数据包仍在离开设备,服务器仍在接收它们。数据包的有效载荷非零,对于每个数据包都是唯一的。

服务器可能有问题吗?它的代码看起来像这样(取自here):

...
static int sampleRate = 8000;

public static void main(String args[]) throws Exception {
    DatagramSocket serverSocket = new DatagramSocket(port);
    byte[] receiveData = new byte[512];
    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());

    DatagramPacket receivePacket = new DatagramPacket(receiveData,
                receiveData.length);
    while (status == true) {
        ByteArrayInputStream baiss = new ByteArrayInputStream(
                    receivePacket.getData());
        serverSocket.receive(receivePacket);
        ais = new AudioInputStream(baiss, format, receivePacket.getLength());
        toSpeaker(receivePacket.getData());
    }
    sourceDataLine.drain();
    sourceDataLine.close();
}

public static void toSpeaker(byte soundbytes[]) {
    try {
        sourceDataLine.write(soundbytes, 0, soundbytes.length);
    } catch (Exception e) {
        System.out.println("Not working in speakers...");
        e.printStackTrace();
    }
}
...

服务器的采样率和缓冲区大小与Android应用程序相同。格式为AudioFormat.ENCODING_PCM_16BIT

java android audio android-service audio-recording
1个回答
0
投票

阅读本文:What exactly happens to running services when you swipe an android app from recent app list ?

在您的情况下,该服务停止工作,由于开始发粘,因此在娱乐中似乎出现了录制失败的问题,我不知道这是什么。在改善服务的意义上,请使用IntentService或前台服务来解决问题。

BTW,如果您想在android 8或更高版本中使用您的应用,则可能仅需使用ForeGrounService,因为如果应用在后台运行,几分钟后IntentService将被系统杀死。阅读此:Background Execution Limits

因此,在测试了所有解决方案之后,您可能会同意我使用前台服务:Android Foreground Service Example

© www.soinside.com 2019 - 2024. All rights reserved.