My audio isn't playing...I've been stuck on this for around 7 hours (ALL DAY!), and have cannot figure out the issue. I am trying to have the volume mute when user clicks mute and unmute when user clicks it again.
I want to be able to have the user unmute the app to the same volume that the user was originally on. userVolumeOnStart.userVolume is where the users original volume is stored in. I use this value in the unMute, to set their volume to what it used to be.
For example:
If your volume was 7 and you used my mute button:
Open app->Mute (Volume=0)->Unmute(Volume = 7 again) etc.
Here is the listener to the mute button:
public void mute(View view) {
mutebutton = (ImageButton) findViewById(R.id.mutebutton);
if ((variableForMute.x % 2) != 0) { //If it's odd UNMUTE
Log.v(TAG, "Use this volume to unmute " +userVolumeOnStart.userVolume +"");
Toast.makeText(Main_Menu.this, "UNMUTED", Toast.LENGTH_SHORT).show();
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, userVolumeOnStart.userVolume, 0);
variableForMute.x++;
} else { //If its even MUTE
userVolumeOnStart.userVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
Log.v(TAG, "Right Before Mute " +userVolumeOnStart.userVolume +"");
mAudioManager.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
Toast.makeText(Main_Menu.this, "MUTED", Toast.LENGTH_SHORT).show();
variableForMute.x++;
}
}
userVolumeOnStart.userVolume is a variable that I defined in a seperate class, to use it globally. Here is where the audio actually runs. I can assure you the issue is not here (as I have not messed with the code in this class today) , but I will still provide the code anyway:
cdt = new CountDownTimer(20000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.v(TAG, millisUntilFinished + "left");
millisUntilFinishedRounded = ((500 + millisUntilFinished) / 1000) * 1000;
if (millisUntilFinishedRounded == 10000) { //TEN SECONDS
ten = MediaPlayer.create(TwentySeconds.this, R.raw.tenmoreseconds);
ten.start();
}
if (millisUntilFinishedRounded == 3000) {
three = MediaPlayer.create(TwentySeconds.this, R.raw.threetwoone);
three.start();
}
}
This is a service that runs in the background when the app starts.
Here is my log after changing ringer volume on my phone while app is running and pressing the mute button. It shows that userVolumeOnStart.userVolume is doing what it's supposed to be doing:
I am desperate now, so I would really appreciate any feedback (negative or positive!)
Thanks so much,
{Rich}
By the way, my question is not a duplicate of The audio volume is zero?. I have changed the audio stream since that question, and have figured out the problem there. There, there was an issue with AudioManager.STREAM_MUSIC where userVolumeOnStart.userVolume would always be 0. I have changed STRAM_MUSIC to STREAM_RING. That is not the issue now, as userVolumeOnStart.userVolume successfully changes based on user volume. The problem now is that the Media Players are not effectively working for an unknown reason.
I found the answer after 2 days!
MediaPlayer mp = MediaPlayer.create(this, R.raw.MYAUDIO);
I shouldn't break it up into declaration and instantiation:
Mp.create will call the static method which is an instance that won't get stored. When I call start() I am starting the original MediaPlayer, not the instance! So basically, I am satrting something that I never even stored, and that's why the audio wasn't playing!
Related
I am making an app in Android Studio in Java and one of the codes is when volume up button triggered(action key up) device should vibrate.
It works if I hold volume button for like 500 milliseconds and then release it, but on quick press on volume button it doesn't work.
I use volume up trigger. if I hold the volume button down for like 500 millisecond and then release it vibration works, but If I just quickly push volume button other things works but vibration doesn't.
the code:
switch (keycode) {
case `your text`KeyEvent.KEYCODE_VOLUME_UP:
if `your text`(KeyEvent.ACTION_UP == action) {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
count++;
String num = String.valueOf(count);
Number.setText(num);
{
if (count == 1) {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
final long[] pattern1 = {0, 200, 0,};
vibrator.vibrate(pattern1, -1);
Changing action up to action down causes another problem which if I hold the button the code continuously runs.
I tried changing action up to action down but caused another problem. I don't want the code to constantly run if volume key is hold down.
I'm trying to develop an app that detects a fall and so far the accuracy of a fall is in an acceptable range but the problem is the "OnSensorChanged" gets invoked way too frequently causing the toast to appear on my screen constantly.
I think the problem is that during a free fall, the "OnSensorChanged" keeps on getting called for the duration of the fall (since the values correspond to a fall) which is whats causing the toast spam on my screen.
A solution i tried is to unregister the listener after a fall so that it only appears once but the problem is that it wont detect a fall again unless i restart the app (because obviously the listener stopped working).
Is there any solution to this issue?
Thanks
private void checkFall(SensorEvent xyzValues) {
float[] values = xyzValues.values;
double rootSquare = Math.sqrt(Math.pow(values[0],2)+Math.pow(values[1],2)+Math.pow(values[2],2));
if (rootSquare < 1.5){
Toast toast = Toast.makeText(this, "The Phone Fell!", Toast.LENGTH_LONG);
toast.show();
sensorManager.unregisterListener(this);
sensorManager = null;
}
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
checkFall(event);
}
}
You can make use of a member boolean variable, mFallen that keeps track of when a fall has just occurred. You might also want to define some threshold value to indicate when the phone is back to a normal "standing" state. Try the following:
if (rootSquare < 1.5 && !mFallen){
Toast toast = Toast.makeText(this, "The Phone Fell!", Toast.LENGTH_LONG);
toast.show();
mFallen = true;
} else if (rootSquare > STANDING_THRESHOLD) {
mFallen = false;
}
Better Standing Detection Algorithm
Once the state of mFallen has changed from false to true, the magnitude of the device's acceleration vector (as you've calculated and stored in rootSquare) should be very close to 0. This is because when the device is in free-fall (falling all by itself), its acceleration will be that of gravity from the reference frame of a standing person. But in theory, the accelerometer would only be measuring values relative to free-fall, and therefore it would be exactly 0.
Since the acceleration of gravity is approximately 9.81 m/s^2, to detect when the device is not moving again, you'd need to check when the magnitude of acceleration is close to that. This is because while still, the sensor will be detecting the force that is preventing it from falling (canceling the acceleration due to gravity) which are the forces of whatever is keeping it still. The overall magnitude of the accelerations due to these forces must sum up exactly to the magnitude of the acceleration due to gravity in this case.
You could define a constant GRAVITY to be 9.81, and GRAVITY_THRESHOLD to be a tolerance value, which you can try setting to 0.1 and then refining later on. Try replacing your code with the following:
if (rootSquare < 1.5 && !mFallen){
Toast toast = Toast.makeText(this, "The Phone Fell!", Toast.LENGTH_LONG);
toast.show();
mFallen = true;
} else if (Math.abs(rootSquare - GRAVITY) < GRAVITY_THRESHOLD) {
mFallen = false;
}
Just to emphasize, the standing state here is defined as only when the device has stopped moving, so it won't be able to detect when the phone has reached a certain height with respect to the ground.
Please see https://developer.android.com/reference/android/hardware/SensorEvent.html#values, as it may help you understand the problem better.
I am giving the user the choice to mute my app using AudioManager. I want to be able to have the user unmute the app to the same volume that the user was originally on. So, I created a variable that can be accessed from all of my activities by creating a separate java class. This variable gets the original volume:
public class userVolumeOnStart {
static AudioManager mAudioManager;
public static int userVolume = setVolume(); //Setting it equal to the return value of method setVolume
public static int setVolume() {
userVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
return userVolume;
}
}
I call this from a different activity to unmute it like so:
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, userVolumeOnStart.userVolume, 0);
Toast.makeText(Main_Menu.this, "UNMUTED", Toast.LENGTH_SHORT).show();
For some reason, I am getting exceptions when I try to unmute it to the users original volume:
ExceptionInInitializationError
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, userVolumeOnStart.userVolume, 0);
NullPointerException
userVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
public static int userVolume = setVolume(); //Setting it equal to the return value of method setVolume
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, userVolumeOnStart.userVolume, 0);
I have been stuck trying to fix this for many hours now, and I have looked through the internet with no luck. Please help me unmute the app to the same volume that the user was originally on. I would appreciate your help and feedback (positive or negative!)
Thanks,
{Rich}
You are doing lot of redundant things in your code for userVolumeOnStart(), you shouldn't need to set the variable userVolume all you need to do is use the function, userVolumeOnStart.setVolume() I dont know why you decided to call a function that actually returns the volume as setVolume you should probably rename to getVolume() anyways try changing this line
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, userVolumeOnStart.userVolume, 0);
to this
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, userVolumeOnStart.setVolume(), 0);
I'm looking to play a sound when a CountDownTimer expires. I can't seem to get it working as I want. I've looked at some sample code using the ToneGenerator but it is not working as I'm expecting it to and because I'm new to android and java, not really sure how to get it working better.
Here is what I have:
- Countdown timer works. It starts and stops when I click on it and resumes when I click on it again. Everything is perfect here.
I have managed to play some sounds out of my device but it will actually repeat for some reason. Not sure why.
Here is what I want:
- onFinish() of the CountDownTimer, I would like to generate a tone around 2800Hz for a period of 2 or maybe 2.5 seconds.
- after I get it working, I would like to play with the idea of making it an alternating tone at say 2800Hz and 2000Hz for 50ms each or something and for a period of 2 to 2.5 seconds.
** EDIT **
public void soundBuzzer() {
ToneGenerator toneGen;
int type1, type2;
toneGen = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
type1 = ToneGenerator.TONE_DTMF_6;
type2 = ToneGenerator.TONE_DTMF_8;
toneGen.startTone(type2, 2000);
}
The ToneGenerator will generate a tone that sounds like the tone on a telephone when you hold down a number. I was unable to get the buzzer to sound using that class and making it sound good. As a result I ended up playing an MP3 for sound.
Here's the code:
// function to generate a tone for 3 seconds
public void soundBuzzer( boolean shortBuzzer ) {
MediaPlayer mp;
if( !shortBuzzer )
mp = MediaPlayer.create(appContext, R.raw.buzzer_2s);
else
mp = MediaPlayer.create(appContext, R.raw.buzzer_short);
mp.start();
}
I'm begining on android and java.
I try to make a simon game but have some problems.
I wrote this to show the simon buttons sequence or the button pushed by the player:
if (but_num == 1) {
ib1.setImageResource(R.drawable.bullet_square_green);
MediaPlayer sound = MediaPlayer.create(this, R.raw.tone_green);
sound.start();
for (int x = 1; x < 10000000; x++) { };
ib1.setImageResource(R.drawable.bullet_ball_green);
} else if (but_num == 2) {
It should change the image of each imagebutton, play a sound, wait some time (for {}) and then
change the image again....
But it doesn't work well... it plays the sound and really changes the image by bullet_square_xxx, but the eye can't see the image change, the change is only visible if the image is not changed back again by the bullet_ball_xxx :-(
I think this is my fault because I wrote the code different than java really works... I'm a
beginner and don't think in java... I have the visual basic program structure on my mind yet.
Thank You and sorry for my English !
This is probably caused by a delay on the event dispatch thread and the fact that the empty loop might be even ignored by the compiler since it is static, it is easily predicted to have no effect on the program. My suggestion is first force a repaint/update on the GUI and use Thread.sleep. Something like this:
if (but_num == 1) {
ib1.setImageResource(R.drawable.bullet_square_green);
updateUI(); // if you are somewhere in a class extending any Frame/Panel
//If you are in other class use mainFrame.repaint();
MediaPlayer sound = MediaPlayer.create(this, R.raw.tone_green);
sound.start();
try{
Trhead.sleep(3000);
} catch (InterruptedException e) {}
ib1.setImageResource(R.drawable.bullet_ball_green);
updateUI(); //only if this effect is delayed too
} else if (but_num == 2) {
ok....I think delay is the problem in your code. Since nowadays there are highspeed processors available that can count to 10000000 in a few ms, mine does. So instead of using the old-school for loop to introduce a delay use
Thread.sleep(5000);
this causes a delay of 5 sec, the argument is the time in milliseconds.
there is another thread which talks about introducing a delay:
How to pause / sleep thread or process in Android?
you could try this [i have copied pasted from that thread]:
if (but_num == 1) {
ib1.setImageResource(R.drawable.bullet_square_green);
MediaPlayer sound = MediaPlayer.create(this, R.raw.tone_green);
sound.start();
// SLEEP 2 SECONDS HERE ...
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
ib1.setImageResource(R.drawable.bullet_ball_green);
}
}, 2000);
} else if (but_num == 2) {