强制关闭后音频继续播放

时间:2011-07-03 13:54:15

标签: android audio taskkill

首先,谢谢你们这个伟大的网站,我通过搜索这里回答的问题找到了大量的信息。但是我有一个问题,我只发现了一个(没有回答)。

我正在编写一个应用程序,它使用AudioTrack通过耳机插孔循环运行时生成的正弦波(以控制其他电子设备)。它以定时间隔(使用Handler.postDelayed)执行此操作,并且它工作正常 - 除非您碰巧强制关闭应用程序。在这种情况下,即使在应用程序本身已经过去之后,正弦波也会继续播放,而我唯一可以做的就是重启手机。

如果应用程序正确关闭,声音会停止,即使它崩溃了。

我试过了:

  • 创建一个onDestroy()方法来停止和释放AudioTrack实例,但不幸的是,它甚至都没有被调用。
  • 为声音循环使用更大的音频缓冲区(希望小缓冲区大小导致错误);没有区别。
  • 再次启动我的应用程序:现在我有两个正常的正弦波!
  • 完全卸载(!)应用程序:正弦波仍在那里困扰着我的坟墓。
  • 将手机置于静音模式:没有区别。 (我不希望这发生在我的用户身上。)
  • 将Media Volume完全关闭,等待15分钟以上:没有区别。
  • 将采样率更改为11,22或44.1 kHz:无差异。
  • 一次又一次地开始和杀死应用程序:我实际上可以通过这种方式让8种不同的不朽正弦波相互干扰。实际上非常酷。 :P

我知道在Android上使用任务杀手并不“健康”,但很多人仍然这样做,而且我不希望我的用户的手机变成不可阻挡的噪音发生器,以防我的应用程序碰巧挂起并获得它屁股谁。

以下是生成正弦波的代码:

int bufSize = (int)(11025.0 / 60.0); // the number of samples needed for a seamless loop at 60Hz
AT = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO,
    AudioFormat.ENCODING_PCM_8BIT, bufSize, AudioTrack.MODE_STATIC);

byte buffer[] = new byte[bufSize];

float angle = 0.0f;
for (int i=0; i < bufSize; i++){
    buffer[i] = (byte)(Math.sin(angle) * 255);
    angle += (float)(2*Math.PI) * 60 / 11025;
}

if (AT.write(buffer, 0, bufSize) != bufSize){
    log("Error: Couldn't write audio buffer!");
} else {
    AT.setLoopPoints(0, bufSize, -1);
    AT.play();
}

即使我非常确定这个错误是在Android本身,我一直在拼命寻找一种方法来检测一个强制关闭,以便运行最后一行代码,以便在我的应用程序死亡之前阻止这种情况发生。我找不到任何解决方案,即使我知道这有可能以某种方式(我有一个邪恶的警报应用程序,即使你用任务杀手杀死它也会恢复生命)。如果有人能够启发我,我将非常感激!

我还注意到,当我的应用程序在后台运行并返回时(从“最近的应用程序”菜单或通过任何其他方式),似乎每次都会创建一个新实例。这意味着你无法阻止在后台播放的其他实例 - 除非你使用任务杀手......我确信这一定是一些琐碎的初学者我犯的错误,但我想知道它是否可能是相关的死亡的正弦波。

在Xperia X10 mini pro上运行Android 2.1.1。

1 个答案:

答案 0 :(得分:1)

  

即使我非常确定这个错误在Android本身中

看起来确实如此。我有没有机会说服你发布一个证明这个问题的完整项目?此外,您尝试过哪些Android操作系统版本?

  

我一直在拼命寻找一种检测力关闭的方法,以便在我的应用程序死亡之前运行最后一行代码来阻止这种情况发生。

根据定义,这是不可能的。

  

我找不到任何解决方案,即使我知道这有可能以某种方式

不,不是。

  

(我有一个邪恶的警报应用程序,即使你用任务杀手杀死它也会恢复生命)。

这并不意味着强行关闭的“邪恶警报应用”实例发现了这一事实。这意味着“邪恶警报应用程序”正在使用其他技术在事件之后找出它已经死亡并开始一个新的副本。并且,即使你自己尝试这样做,正如你所指出的那样,它也无济于事 - 你得到的最好的就是你的“8种不同的不朽正弦波”场景。

  

我也注意到我的应用程序在后台运行时

为什么还要写Service来播放正弦波?我可以看到你的活动在前景时播放它,但你应该在onPause()中停止正弦波,所以当你不在前景时,噪音就会停止。

  

然后我回到它(从“最近的应用程序”菜单或通过任何其他方式),似乎每次都创建一个新实例

根据“在后台运行”的含义以及如何进入“背景”,这是正常的。例如,按BACK按钮将破坏活动;通过任何方式回到它将创建一个新的活动实例。