I'm building a simple button app which plays an mp3 player file while changing the backround color and image. The problem is, once the file starts playing the audio clip, nothing else can be done. I can't even change the volume of the audio until after the clip has finished. Any tips on how to fix this would be greatly appreciated.
public void onClick(View v) {
current_image++;
current_image=current_image%images.length;
imgview.setImageResource(images[current_image]);
appMP.start();
{
try {
Thread.sleep(7500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
}
Do not sleep on the main thread. Ever. It causes the app to stop responding to UI events and redrawing, because the main thread never returns to the looper to process messages. That's what's causing all your problems. Remove it and you'll be fine. If you need to do something when it finishes, use an OnCompletionListener.
Related
I try to play some music for my activity but "sometimes" it throws exceptions below :
android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
This is my code that might be related on this error.
...
Thread thread = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bgm.start();
});
thread.start();
...
This code is in onCreate method and rest part is just make some animations with Handler or get 3 String intent values and five int intent values from previous activity.
It doesn't even tell me which line of my code it happened.
Thanks for reading my question.
Possible Solutions:
Override your service's onDestroy() method and watch what event flow leads to it. If you catch DeadObjectException without going through this method, your service should have been killed by the OS.
by removing Typeface, this might be because of ttf which I was using from the assets folder Please try comment the typeface and test it hope it will work for sure
put all your code inside the onCreate. From there you will see what is the culprit like a NullPointerException for example but your code will run smoothly already.
DeadObjectException: The object you are calling has died, because its
hosting process no longer exists.
Let's say I have async tasks that when finished, lock the vibrator and send it a pattern. In a nutshell, that's the kind of code I'm dealing with:
lock(vib);
vib.vibrate(pattern);
release(vib);
return;
The problem is, the vibration starts and just immediately stops due to the task's returning and I could use some help in changing that.
I have tried
lock(vib);
long duration = getDuration(pattern);
vib.vibrate(pattern);
synchronized(this){
try {
wait(duration);
} catch (InterruptedException e) {
...
}
}
release(vib);
return;
but that doesn't seem to actually do anything.
Since I have not found a way to determine whether or not the phone is currently vibrating, any suggestions on how I should best resolve the issue?
I am making and recording application. And the big problem for me is that when user click the record button( i am using custom recorder, not default intent) and if they hit it again quickly or MediaRecorder is going to throw exception or video file will be corrupted. I tried to setEnabled() on buttons but that doesn't seems to work...i don't know why, it seems like they are not disabled for some reason...
Can somebody please help me with this?
It doesn't hurt to have more than one layer of validation. In addition to setEnabled(false) on your record button, try adding some logic to prevent a dirty write. Code assumes you're operating on a single thread.
boolean inProgress;
onClick()
{
inProgress = true;
record();
}
public boolean record()
{
if(!inProgress)
{
// record sound
// don't forget to reset inProgress if record success/fail
}
}
The Google Voice Search comes with a significant delay from the moment you call it via startActivityForResult() until its dialog box is displayed, ready to take your speech.
This requires the user to always look at the screen, waiting for the dialog box to be displayed, before speaking.
So I was thinking of generating an audible signal instead of the dialog box by implementing RecognitionListener and sounding a DTMF tone in onReadyForSpeech() as in the following snippet:
#Override
public void onReadyForSpeech(Bundle params) {
Log.d(LCTAG, "Called when the endpointer is ready for the user to start speaking.");
mToneGenerator.startTone(ToneGenerator.TONE_DTMF_1);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
Log.e(LCTAG, "InterruptedException while in Thread.sleep(50).");
e.printStackTrace();
} // SystemClock.sleep(50);
mToneGenerator.stopTone();
}
The tone sounds beautifully but... it is also "heard" by the microphone, arriving to the voice recognition service and always generating a recognition error ERROR_NO_MATCH.
Is there a way to work around this?
Here is a random idea, and it may very well not work.
Can you try disabling the microphone (maybe via AudioManager.setMicrophoneMute) while the tone is played?
Here's my code that's working for me, put into the onReadyForSpeech() callback of the RecognitionListener.
private void playSpeechReadyTone(){
audioManager.setMicrophoneMute(true);
MediaPlayer mediaPlayer = MediaPlayer.create(JarvisService.this, R.raw.doublebeep);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer arg0) {
audioManager.setMicrophoneMute(false);
}
});
mediaPlayer.start();
}
I'm afraid that there isn't an easy&clean way to do that. As srf appointed, you shouldn't rely on AudioManager.setMicrophoneMute(boolean), so, AFAIK, the possibles are:
Play an audio file before call SpeechRecognizer.startListening(intent):
final MediaPlayer mediaPlayer = MediaPlayer.create(JarvisService.this, R.raw.doublebeep);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer player) {
player.release();
// Safety start Speech Recognizer
mSpeechRecognizer.startListening(getSpeechRecognizerIntent());
}
});
mediaPlayer.start();
However, this solution has a problem... If may receive an RecognitionListener.onError(int error) before RecognitionListener.onReadyForSpeech being called and, in that case, you are still playing a beep sound every time (this will happen, for example, if you are not connected to the Internet and Speech Recognition is configured to work online)!
Besides, you should manage the case of cancelling the speech recognition process during audio (doublebeep) play.
Play the audio in the onReadyForSpeech callback (read original question) but use RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS with an appropriate value. In my case, my beep sound is really short (1 second max) and I set RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS to 4/5 seconds.
Also note that, as Google doc says:
Note also that certain values may cause undesired or unexpected results - use judiciously! Additionally, depending on the recognizer implementation, these values may have no effect.
My first post here. This website has been very useful for learning Android programming, thanks to everyone.
I have a simple app that loads an MP3 stream and plays it. It works fine on 1.6 and 2.1 but on 2.2 it doesn't quite work right. It seems my service is having a problem starting, it's giving my an ANR and the dialog where I have to tap "Wait", and then finally the service starts. Why is the service taking a long time to start up?
Here's my simple code that sets the source and plays the audio:
public class MyActivityService extends Service {
MediaPlayer player = new MediaPlayer();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
try {
player.setDataSource("URL OF MUSIC FILE");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
player.prepare();
player.setVolume(1, 1);
player.setLooping(true);
player.start();
Toast.makeText(getApplicationContext(), "Audio Service Started.", Toast.LENGTH_SHORT).show();}
ADDENDUM:
Turns out it wasn't my service not starting, it's the audio that's not starting quickly enough in 2.2...
I got rid of the ANRs when my service started and stopped by putting the onCreate() and onDestroy() methods of my service in their own threads, which is probably how it should have been from the beginning? Sorry, just learning.
But the delay that's the real problem remains, to clarify --
For example, my code, as it is right now, works fine and dandy and just how I want it to in 2.1 AND 2.2 when I set the data source to an MP3 file like this: http://dl.dropbox.com/u/6916184/TestSongStream.mp3
BUT when I set the data source to an audio stream location like this: http://d.liveatc.net/kjfk_twr or this: http://relay.radioreference.com:80/192236577 it works correctly ONLY in 2.1.
In 2.2 the sound does start playing eventually, but it takes "StagefrightPlayer" about 25 seconds or so after setting the data source until the audio starts as shown here:
07-31 02:54:30.176: INFO/StagefrightPlayer(34): setDataSource('http://relay.radioreference.com:80/192236577')
07-31 02:54:55.228: INFO/AwesomePlayer(34): calling prefetcher->prepare()
07-31 02:54:56.231: INFO/Prefetcher(34): [0x2cc28] cache below low water mark, filling cache.
07-31 02:54:56.337: INFO/AwesomePlayer(34): prefetcher is done preparing
07-31 02:54:56.347: DEBUG/AudioSink(34): bufferCount (4) is too small and increased to 12
07-31 02:54:57.337: ERROR/AwesomePlayer(34): Not sending buffering status because duration is unknown.
It also takes the same amount of time, about 25 seconds, to stop the media player after player.stop() is called in the onDestroy() method of my service, and the onDestroy() method continues on to Toast a message and cancel a notification.
Is that just the way it is with 2.2? If so, I can work around the delays, that's not a problem. Or more likely is it something I am doing wrong? But it works exactly as I want in 1.6 and 2.1!
Would posting more code help?
My code is very simple. There are no audio controls or anything like that. Simply a start audio button and stop audio button that start and stop a service that plays an audio stream.
Thank you for any help!
Do not call prepare() from the main application thread, particularly for a stream, because that may take much longer than you're allowed before an ANR. Use prepareAsync() instead. I have no idea if that is the root of your particular problem, but it would certainly be one cause of an ANR in your current implementation.