Is ToneGenerator sound smooth? - android

Does anyone have the same problem?
On Android's Phone app, whenever a number is pressed, the tone is always smooth.
But, when I used very similar code as the Phone app, the tone I get regularly isn't smooth...there are gaps. Is there a way to resolve this?
Some of my theories are that the emulator causes these breaks in sound as there are time lags in processing. The Phone app on the emulator is also more "compiled"/native than my code. Etc. Don't know what is the reason for these tones not being continuous.
Here's the code (literally the same as Phone app):
...
playTone(ToneGenerator.TONE_DTMF_1,150);
...
void playTone(int tone) {
// if local tone playback is disabled, just return.
if (!mDTMFToneEnabled) {
return;
}
// Also do nothing if the phone is in silent mode.
// We need to re-check the ringer mode for *every* playTone()
// call, rather than keeping a local flag that's updated in
// onResume(), since it's possible to toggle silent mode without
// leaving the current activity (via the ENDCALL-longpress menu.)
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int ringerMode = audioManager.getRingerMode();
if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
|| (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
return;
}
synchronized (mToneGeneratorLock) {
if (mToneGenerator == null) {
Log.w("test", "playTone: mToneGenerator == null, tone: " + tone);
return;
}
// Start the new tone (will stop any playing tone)
mToneGenerator.startTone(tone, TONE_LENGTH_MS);

Related

How to mic mute when recording video?

How to mute mic in android my code is working but in some device mic is not muted please give solution my code is:
private void setMicMuted(boolean state){
AudioManager myAudioManager = (AudioManager)con.getSystemService(Context.AUDIO_SERVICE);
// get the working mode and keep it
int workingAudioMode = myAudioManager.getMode();
myAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
// change mic state only if needed
if (myAudioManager.isMicrophoneMute() != state) {
myAudioManager.setMicrophoneMute(state);
}
// set back the original working mode
myAudioManager.setMode(workingAudioMode); }
If you are using MediaRecorder just use it without calling setAudio on it, this way it will only record video without audio.

Pause all the other media players and audios while Application media player starts playing

I am working on a push to talk App, where the receiver will get a live-streamed audio message from a sender if he is connected to the internet. Now everything's working all fine except one issue that is: whenever any other applications like google music or youtube are playing audios, that time if I am getting an audio notification or message through the application, both the audios are playing in a parallel manner. I am using VoiceLayer library for the app and to play a message audio, they use VoiceLayerMessagePlayer. Is there any way I can pause the other media players when I am getting a notification or voice message in my Application? I looked through the internet and found out that OnAudioFocusChangeListener might be helpful but didn't get a proper example regarding its implementation. Please do let me know if you need any more information. Thanks in advance.
You should use AudioManager service to receive notification whether you receive/lost audio focus (Managing audio focus). I've done similar thing in a project where when my app starts playing, Google Play pause and vice versa. Use the following code where you are controlling your media playback like (activity or service)
Stop MediaPlayer when an other app play music
Please check below code it's working fine.
AudioManager am = null;
// Request focus for music stream and pass
AudioManager.OnAudioFocusChangeListener
// implementation reference
int result = am.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if(result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED)
{
// Play
}
// Implements AudioManager.OnAudioFocusChangeListener
#Override
public void onAudioFocusChange(int focusChange)
{
if(focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)
{
// Pause
}
else if(focusChange == AudioManager.AUDIOFOCUS_GAIN)
{
// Resume
}
else if(focusChange == AudioManager.AUDIOFOCUS_LOSS)
{
// Stop or pause depending on your need
}
}
Hope this helps you and solved your problem.
please try this code. it work with me
val audioManager = requireActivity().getSystemService(Context.AUDIO_SERVICE) as AudioManager
val focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
setAudioAttributes(AudioAttributes.Builder().run {
setUsage(AudioAttributes.USAGE_GAME)
setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
setOnAudioFocusChangeListener({ }, object : Handler() {})
build()
})
setAcceptsDelayedFocusGain(true)
build()
}
audioManager.requestAudioFocus(focusRequest)

Cannot stop AudioTrack on Android 5

I cannot stop playback of an AudioTrack on a Nexus 4 running Android 5.0.1. Am I doing something wrong?
The code is very simple (it's actually just a test app) and it works perfectly on devices running 2.3.6 and 4.4. Here's the relevant portion:
mPlugReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())) {
boolean plugged = intent.getIntExtra("state", 0) == 1;
if(plugged) {
log.debug("audio device plugged");
boolean mic = intent.getIntExtra("microphone", 0) == 1;
if(mic) {
log.debug("microphone detected");
mPowerTone.play();
}
}
}
else if(AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
log.debug("stopping power tone");
mPowerTone.pause();
mPowerTone.flush();
mPowerTone.stop();
}
}
};
On 5.0.1, it logs "stopping power tone" but the track continues to play! It even continues to play after I exit the app. Sometimes it stops after a few seconds, and sometimes I have to force close the app.
I tried both with and without the calls to pause() and flush(), to no avail. It works without those calls on the older devices.
This unanswered question led me to a solution. If you call AudioTrack#stop() on Lollipop, even in conjunction with the methods that actually work, playback will not stop! You must use a condition like this:
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mPowerTone.pause();
mPowerTone.flush();
}
else {
mPowerTone.stop();
}
Keep up the good work, Google.

Detect when sound is playing through earpiece speaker

Background
I'm developing an app that monitors the proximity sensor. However, I don't want to monitor the sensor while the user is listening to something through the phone ear speaker. This is because the user will probably have his/her head against the handset to listen, which in turn triggers the proximity sensor, and I'm not trying to detect head proximity.
Question
How can I detect when sound is and isn't playing through the handset ear speaker? Callbacks are preferable, of course, but I'm willing to poll if it's the only way.
You can approximate this by regularly polling and making the following checks:
Check if the audio system is not in normal mode.
Check if the audio is being routed to the earpiece.
I tested this in Android 4.3, and it seemed to work fine with the system phone app, Viber and Skype. However, it doesn't seem to detect music or non-telephony sounds played through the earpiece. I don't think this is much of a problem, because the earpiece generally seems to only be used for telephony anyway.
Example
public class EarpieceSpeakerState {
private AudioManager audioManager;
public EarpieceSpeakerState(AudioManager audioManager) {
this.audioManager = audioManager;
}
public boolean usingEarpieceSpeaker() {
return playingSound()
&& routingToEarpiece();
}
private boolean playingSound() {
return audioManager.getMode() != AudioManager.MODE_NORMAL;
}
private boolean routingToEarpiece() {
return !(
audioManager.isSpeakerphoneOn()
|| audioManager.isBluetoothScoOn()
|| audioManager.isBluetoothA2dpOn()
|| audioManager.isWiredHeadsetOn()
);
}
}
I don't know if it is the right solution but i think you should at least give it a try, check out this link.
Teorically you will not receive focus if somebody else is using the speaker of your phone.
base solution, you can extend it link
private fun initOnAudioFocusChangeListener() {
val afChangeListener: AudioManager.OnAudioFocusChangeListener =
AudioManager.OnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> {
viewModel.isAppLostAudioFocusLiveData.value = false
}
else -> {
viewModel.isAppLostAudioFocusLiveData.value = true
}
}
}
val audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
audioManager.requestAudioFocus(
AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setOnAudioFocusChangeListener(afChangeListener).build()
)
} else {
audioManager.requestAudioFocus(
afChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN
)
}
}

Automatically silence the sound volume of Android Phone programmatically?

I'm developing an application that can turn off the sound of Android Phone automatically. How can I detect the volume of the sound and turn it off programmatically?
if (hour == myTime.getHour() && minute == myTime.getMinute()) {
if (Settings.getSetMyTime(this))
showNotificationAlarm(R.drawable.icon,
"It's time to work");
///so, i want to add the silet function here..help me, please?
}
Thanks in advance.
Have a look at the AudioManager, especially the getStreamVolume and setStreamVolume methods
EDIT
You can also use the method Nikola Despotoski provided with setRingerMode
A Service is a child of a Context so you can call directly getSystemService
See the updated code below (untested):
if (hour == myTime.getHour() && minute == myTime.getMinute()) {
if (Settings.getSetMyTime(this))
showNotificationAlarm(R.drawable.icon,"It's time to work");
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
am.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
Register for AUDIO_SERVICE and then use the AudioManager to control the volume up/down or set profiles.
Or if you want to listen for changes in the Audio focus then make your Activity implements AudioManager.OnAudioFocusChangeListener. Override unimplemented method. Create switch that will take care of types of changes.
Like:
#Override
public void onAudioFocusChange(int focusChange) {
switch(focusChange)
{
case AudioManager.AUDIOFOCUS_GAIN:
//do something
break;
case AudioManager.AUDIOFOCUS_LOSS:
break;
}
Or if you want to listen for changes on the audio output, like unplugging the headphones (switching to phone speaker) use ACTION_AUDIO_BECOMING_NOISY sticky broadcast
http://developer.android.com/reference/android/media/AudioManager.html#ACTION_AUDIO_BECOMING_NOISY
http://developer.android.com/reference/android/media/AudioManager.html#RINGER_MODE_SILENT
See here
Edit: This is the solution. There was no need to handle AudioFocus but just set different ringer profile or adjusting volume
if (hour == myTime.getHour() && minute == myTime.getMinute()) {
if (Settings.getSetMyTime(this))
showNotificationAlarm(R.drawable.icon,
"It's time to work");
AudioManager audiomanager =(AudioManager)YourActivityName.this.getSystemService(Context.AUDIO_SERVICE);
audiomanager.setRingerMode(AudioManager.RINGER_MODE_SILENT); //or adjust volume here instead setting silent profile for the ringer
}

Categories

Resources