我的问题改变了一点,请看看下面的EDIT 2
我正在学习如何在Android上使用服务和录音。
我想创建一个应用程序,除了启动服务什么也不做:在请求权限(RECORD_AUDIO
,INTERNET
)后,应用程序只从Mainactive
调用start Service()
。
然后,该服务将录制音频并将其传输到给定的IP地址。我从这个问题的答案中获得了对音频流服务器和客户端的灵感。到目前为止,我正在Android Studio Emulator上测试Android 6.0上的应用程序。
这是我服务的onStartCommand()
方法。我创建了一个新线程,等待用户在“权限请求”对话框中单击“允许”。当我收到权限时,我初始化录音
,然后在的同时
循环读取并发送数据。
@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()
中创建的线程中的循环终止。然后我释放记录器
,这样它就可以初始化并再次使用。
@Override
public void onDestroy(){
status = false;
recorder.stop();
recorder.release();
super.onDestroy();
}
这个程序的工作原理只有部分:
当我启动计算机上的监听服务器和模拟器中的应用程序时,我可以正常听到音频。
- 当我最小化应用程序(点击主页按钮)时,音频流仍然正常。
- 我的问题是,当我杀死应用程序(在运行的应用程序屏幕中滑动它),音频停止。在Logcat中,我可以看到服务已经重新启动,并像往常一样运行(初始化
Audio记录
和一切,没有抛出异常),只有我什么也听不到。当我再次运行应用程序(因此再次调用start Service()
)时,我在Logcat中看到一个异常,告诉我AudioBook
start失败,错误代码为-38(这意味着麦克风正在被服务的上一个实例)。
我做错了什么?为什么在我关闭应用程序时,服务正在运行,但音频没有流媒体?
非常感谢你的回答。
编辑:
我知道这种方法在较新的Android版本上不起作用。这个应用程序只是出于私人目的,将在我的旧手机上运行,无论是Android5.1.1还是6.0。
在我阅读了这篇回答中的文章后,我将之前在
onDestroy
中的内容移动到了onTaskRemoved
。然而,一切都没有改变。
服务重启后,显然仍在发送一些数据包。我在Wireshark中查看了它们,数据包仍在离开设备,服务器仍在接收它们。数据包的有效负载为非零,每个数据包都是唯一的。
编辑2:
我将缓冲区大小改为
AudioRecord。Android应用程序中的getMinBufferSize(sampleRate、channelConfig、audioFormat)*10和AudioRecord。服务器应用程序中的getMinBufferSize(sampleRate、channelConfig、audioFormat)*20
。现在,当我滑动应用程序时,服务
重新启动,然后我可以听到一些音频。但是重启后声音很粗,我不知道为什么。当我卸载应用程序,保持服务器运行,然后再次安装并运行应用程序时,它也会变得笨重。
所以问题可能出在服务器端。服务器可能有什么问题?我是否正确使用
源数据线
?服务器代码如下所示(取自此处):
...
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 (...) {...}
}
...
服务器的采样率与Android应用相同。格式是
AudioFormat。ENCODING_PCM_16BIT
。
阅读本文:当你从最近的应用列表中滑动一个Android应用时,运行服务会发生什么?
在你的情况下,服务停止工作,在娱乐中,因为启动粘性,似乎你有一个问题,录音失败,我不知道这是什么。在改善服务的意义上,使用IntentService或前台服务来解决问题。
顺便说一句,如果你想在android 8或更高版本中使用你的应用程序,你可能只需要使用ForeGrounService,因为如果应用程序在后台,IntentService将在几分钟后被系统终止。阅读以下内容:后台执行限制
所以在测试了所有的解决方案之后,你可能会同意我使用前台服务:Android前台服务示例
问题内容: 我正在使用背景音乐创建游戏应用程序。我使用Android Service播放背景音乐是因为我想在更改活动时运行BGM。我的问题是,我在每个活动的onPause方法中都声明了finish()(我不想让用户返回并想杀死该活动)。 因此,当我打算进行其他活动时,它将调用onDestroy并停止该服务。我想停止该服务以完全退出应用程序(按下主页按钮),并想要通过onPause()中的BGM
当用户使用后退按钮退出应用程序时,Android中的后台服务将停止运行。如果应用程序在前台或后台(点击HOME按钮),同样的服务工作得很好。 有3个案例: null MainActivity.java SimpleService
我试图重新创建Connect四,我成功了。但我想通过频繁地切换颜色,给玩家一个获胜的四张光盘在哪里的指示。我对线程和编程中的时间概念是新的。 我也成功地给了用户这个指示,但是在关闭应用程序之后,控制台仍然会给出输出,也是在使用SetonCloserEquest时。 代码如下:
问题内容: 我有一个媒体播放器服务,可在整个应用程序的后台播放音乐,例如: 问题在于,当用户更改应用程序或进入手机主屏幕(应用程序在后台运行)时,音乐仍在播放。 我试图停止它和方法,但是当我更改活动时这会停止音乐,这是我不希望的(我希望音乐在用户浏览活动时继续播放)。 更新资料 我尝试了广播: 我加了 在音乐服务的onCreate和接收事件的方法中: 在应用程序类中,我这样做: 但是音乐不会恢复
提前致谢