7

首先,感谢您提供这个很棒的网站,通过搜索此处回答的问题,我找到了很多信息。不过,我有一个问题,我只发现了一次提到(没有答案)。

我正在编写一个应用程序,它使用 AudioTrack 通过耳机插孔循环运行时生成的正弦波(以控制其他电子设备)。它以定时间隔执行此操作(使用 Handler.postDelayed),并且它工作得很好 - 除非您碰巧强制关闭应用程序。在这种情况下,即使应用程序本身早已消失,正弦波仍会继续播放,而实际上我唯一能阻止它的就是重新启动手机。

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

我努力了:

  • 创建一个 onDestroy() 方法来停止和释放 AudioTrack 实例,但不幸的是,它甚至没有被调用。
  • 为声音循环使用较大的音频缓冲区(希望较小的缓冲区大小导致错误);没有不同。
  • 再次启动我的应用程序:现在我有两个可怕的正弦波!
  • 完全卸载(!)该应用程序:正弦波仍然在那里困扰着我。
  • 将手机置于静音模式:没有区别。(我不希望这种情况发生在我的用户身上。)
  • 将媒体音量一直调低,然后等待 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。

4

1 回答 1

1

即使我很确定这个错误是在 Android 本身

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

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

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

我没有找到解决方案,即使我知道这是可能的

不,不是。

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

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

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

你为什么要费心写一个Service来播放正弦波?我可以看到在您的活动处于前台时播放它,但是您应该在 中停止正弦波onPause(),因此当您不在前台时,噪音会停止。

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

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

于 2011-07-03T16:07:32.003 回答