我正在使用以下代码在我的应用程序中播放声音。在ICS之前一切都很好。但在ics和更新版本上,虽然没有出现错误,但听不到声音。
编辑:注意,下面的代码是由Broadcase接收器触发的。广播接收器调用异步任务。在asycn任务的后处理方法中,调用以下方法。
此错误仅发生在特定的移动模型(如Nexus)上,在某些模型上,用户能够播放Stock OS附带的声音,但不能播放他们放置在Rigtones文件夹中的自己的声音。
我不知道具体手机上发生了什么问题
可能是什么错误?
public static void playSound(final Context context, final int volume,
Uri uri, final int stream, int maxTime, int tickTime) {
//stopPlaying();
/*
if (stream < 0 || stream > 100) {
throw new IllegalArgumentException(
"volume must be between 0 and 100 .Current volume "
+ volume);
}*/
final AudioManager mAudioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
int deviceLocalVolume = getDeviceVolume(volume,
mAudioManager.getStreamMaxVolume(stream));
Log.d(TAG,
"device max volume = "
+ mAudioManager.getStreamMaxVolume(stream)
+ " for streamType " + stream);
Log.d(TAG, "playing sound " + uri.toString()
+ " with device local volume " + deviceLocalVolume);
final int oldVolume = mAudioManager.getStreamVolume(stream);
// set the volume to what we want it to be. In this case it's max volume
// for the alarm stream.
Log.d(Constants.APP_TAG, "setting device local volume to " + deviceLocalVolume);
mAudioManager.setStreamVolume(stream, deviceLocalVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
final MediaPlayer mediaPlayer = new MediaPlayer();
golbalMMediaPlayer = mediaPlayer;
try {
final OnPreparedListener OnPreparedListener = new OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mp) {
Log.d(TAG, "onMediaPlayercompletion listener");
mp.start();
countDownTimer.start();
}
};
mediaPlayer.setDataSource(context.getApplicationContext(), uri);
mediaPlayer.setAudioStreamType(stream);
mediaPlayer.setLooping(false);
mediaPlayer.setOnPreparedListener(OnPreparedListener);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(Constants.APP_TAG, "Entered onCompletion listener of mediaplayer");
mAudioManager.setStreamVolume(stream, oldVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
try{
if(mediaPlayer != null && mediaPlayer.isPlaying()){
mediaPlayer.release();
}
}catch(Exception ex){
Log.e(Constants.APP_TAG, "error on oncompletion listener" ,ex);
}
}
});
CountDownTimer timer = new CountDownTimer(maxTime*1000, tickTime*1000) {
@Override
public void onTick(long millisUntilFinished) {
Log.d(TAG, "tick while playing sound ");
}
@Override
public void onFinish() {
Log.d(TAG, "timer finished");
stopPlaying();
}
};
countDownTimer = timer;
mediaPlayer.prepareAsync();
} catch (Exception e) {
Log.e(TAG, "problem while playing sound", e);
} finally {
}
}
原木
:07-01 00:00:00.030: D/beephourly(9500): device max volume = 7 for streamType 5
07-01 00:00:00.030: D/beephourly(9500): playing sound content://media/internal/audio/media/166 with device local volume 7
07-01 00:00:00.030: D/beephourly(9500): setting device local volume to 7
07-01 00:00:00.080: D/beephourly(9500): vibrating with pattern = [J@428bae20
07-01 00:00:00.090: D/beephourly(9500): will show normal notification
07-01 00:00:00.100: D/beephourly(9500): notification is enabled
07-01 00:00:00.100: D/usersettings(9500): hr = 0
07-01 00:00:00.110: D/beephourly(9500): onMediaPlayercompletion listener
07-01 00:00:00.451: D/beephourly(9500): tick while playing sound
07-01 00:00:20.460: D/beephourly(9500): timer finished
07-01 00:00:20.460: D/beephourly(9500): got request to stop playing
07-01 00:00:20.460: D/beephourly(9500): cancelling countdowntimer
07-01 00:00:20.460: D/beephourly(9500): releasing mediaplayer now
这个问题是我之前问的问题的后续问题:
sound not playing in android > icecream sandwich
最佳答案
你应该请求音频焦点,即使是通知。在你的情况下,它看起来像这样:
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//request a transient lock on the notification stream
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_NOTIFICATION,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// could not get audio focus.
}
我怀疑设备上运行了其他一些应用程序,这些应用程序给您带来了请求音频焦点的问题。如果其他应用程序请求音频聚焦,而您不请求,则您的应用程序可能不会播放到最终流。自己请求焦点将确保没有其他进程干扰您的通知声音。虽然这是在一段时间前引入的,但较新版本的android对使用这种机制的应用程序更为敏感,特别是在后台。
正确地说,完成通知后,可以释放焦点:
audioManager.abandonAudioFocus(this);