I'm working on an app that needs to play the system notification at different volume levels and have some issues with getting setVolume to work properly.
To debug this, I prepared a sample app with two buttons that allows me to play the system notification at a low or a high volume. So far, the app works, and the sound comes out of the speaker.
However, no matter in which sequence I press the low and high volume buttons, once I have played the notification at a low volume, it stays low, I can't get it to play at the higher volume again.
Below is my code. I used an oncompletion callback to increment a counter and sound the notification 3 times.
public class MainActivity extends AppCompatActivity {
int soundsCounter = 0; // Counts how many times the notification has sounded
double playbackVolume = 1.0; // Playback volume of the notification
AudioManager audioManager;
MediaPlayer thePlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setup the media player
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
thePlayer = MediaPlayer.create(getApplicationContext(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
// Initialize listener using setOnCompletionListener for mediaPlayer object
// and declare new method OnComletionListener as an argument.
thePlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// Override onCompletion method to apply desired operations.
#Override
public void onCompletion(MediaPlayer mediaPlayer){
soundsCounter++;
if (soundsCounter < 3){ // Sound the notification 3 times
playNotification();
}
}
} );
}
// Plays system notification at the selected volume
private void playNotification() {
try {
thePlayer.setVolume(((float) (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) * playbackVolume)),
(float) (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) * playbackVolume));
}
thePlayer.start();
}
// Called when the user taps the HighV button
public void playHighV(View view) {
soundsCounter = 0;
playbackVolume = 1.0;
playNotification();
}
// Called when the user taps the LowV button
public void playLowV(View view) {
soundsCounter = 0;
playbackVolume = 0.02;
playNotification();
}
Any ideas where to look? Thanks!
Thanks to Oemel09 I realized I was making some mistakes in the parameters passed to setVolume.
Here's the new code that works fine:
public class MainActivity extends AppCompatActivity {
int soundsCounter = 0; // Counts how many times the notification has sounded
float playbackVolume = 1; // Playback volume of the notification
AudioManager audioManager;
MediaPlayer thePlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setup the media player
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
thePlayer = MediaPlayer.create(getApplicationContext(), RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
// Initialize listener using setOnCompletionListener for mediaPlayer object
// and declare new method OnComletionListener as an argument.
thePlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
// Override onCompletion method to apply desired operations.
#Override
public void onCompletion(MediaPlayer mediaPlayer){
soundsCounter++;
if (soundsCounter < 3){ // PLay sound 3 times
playNotification();
}
}
} );
}
// Plays system notification at the selected volume
private void playNotification() {
thePlayer.setVolume(playbackVolume, playbackVolume);
thePlayer.start();
}
// Called when the user taps the HighV button
public void playHighV(View view) {
soundsCounter = 0;
playbackVolume = 1f;
playNotification();
}
// Called when the user taps the LowV button
public void playLowV(View view) {
soundsCounter = 0;
playbackVolume = 0.1f;
playNotification();
}
}
Related
I am searching for a long time on net, and many answers advised to use the setVolume in MediaPlayer.OnPreParedListener, it works when I use it before MediaPlayer.start().
But now there is a button, I want to control mute or unmute when the video is playing, so how to resolve it?
Use this code
private static int aux = 0;
private Button mMuteButton;
private static int aux = 0;
private AudioManager mAudioManager;
//set the Mute button on clickListener inside the class android cycle where needed
mMuteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
if(aux % 2 == 0){
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 100, 0);
aux++;
} else {
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
aux++;
}
}
});
public class PlayerScreen extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
private MediaPlayer mp;
private Button buttonplaypause;
private int count;
private SeekBar seekbar;
private int curpos, prevpos;
private Bundle b;
private String title;
private final Handler handler = new Handler();
private Runnable updatePositionRunnable = new Runnable() {
public void run() {
seekbar.setProgress(mp.getCurrentPosition());
handler.postDelayed(this, 6000);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_screen);
title = b.getString("title");
mp = new MediaPlayer();
try {
Log.d("message", "message");
mp.setDataSource(Environment.getExternalStorageDirectory().getPath()+"/Music/"+title);
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//mp = MediaPlayer.create(this, R.raw.audio);
buttonplaypause = (Button) findViewById(R.id.buttonPlayPause);
seekbar = (SeekBar) findViewById(R.id.seekBar);
seekbar.setMax(mp.getDuration());
buttonplaypause.setBackgroundResource(R.drawable.play);
seekbar.setOnSeekBarChangeListener(this);
handler.postDelayed(updatePositionRunnable, 6000);
}
public void onProgressChanged(SeekBar mySeekBar, int progress, boolean fromUser) {
if (mp.isPlaying()) {
mp.seekTo(progress);
}
}
public void onStartTrackingTouch(SeekBar mySeekBar) {
}
public void onStopTrackingTouch(SeekBar mySeekBar) {
}
public void toPlayPause(View v) {
if (count % 2 == 0) {
buttonplaypause.setBackgroundResource(R.drawable.pause);
curpos = mp.getCurrentPosition();
prevpos = curpos;
mp.seekTo(curpos);
mp.start();
count++;
buttonplaypause.setBackgroundResource(R.drawable.play);
mp.pause();
count++;
}
}
}
What i'm trying to do is build a music player which displays the list of song in one activity in a List View and when the user taps on an item that particular song should be played in another intent (which is provided by play and pause button). The code provided above is the code for the second activity (the first part i.e. listing the songs is done). The first Activity passes the song title in a bundle which is received by this activity. I am new to android and don't know a lot about it. I don't know how to pass the song from one intent to another so that it is played. The problem I think is in the line setDataSource().
When the second Intent (i.e the code provided above) is opened on tapping item in the List View, the seek bar reaches it's end and no song is played
If there is any other, better way to pass the song from one intent to another feel free to describe it in detail.
I'm using a MediaPlayer to play my sound effects but after a certain point (28 playbacks to be exact) the MediaPlayer does not play anymore. This is how I create the MediaPlayer:
if(noteManager.rep.get((layer)).notes[j] == 0){
MediaPlayer mp;
switch (j){
case 0:
mp = MediaPlayer.create(InGame.this, R.raw.one);
break;
...
}}
Right after I call:
mp.start();
Also, this code gets executed a couple times a second. It all works fine until the 29th sound effect, after which it stops working (there's no sound). I'm using short wav files. Any thoughts?
Use MediaPlayer outside the click event
public class MainActivity extends AppCompatActivity {
private ImageView Reload;
private TextView Label;
private MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Reload = (ImageView)findViewById(R.id.iv_Reload);
Label = (TextView)findViewById(R.id.tv_appname);
mp = MediaPlayer.create(getApplicationContext(),R.raw.reloadsound);
Reload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.startAnimation(AnimationUtils.loadAnimation(getApplicationContext(), R.anim.iv_anim));
mp.start();
}
});
}
I have problem with my application
I have a main layout: main.xml, it includes a button named "Setting"
When I click the Setting button,
I use setContentView(R.layout.setting); to go to the setting.xml
In setting.xml, I have a seekbar to control the volume of app
I have followed this post "Using SeekBar to Control Volume in android?"
I do like this in my activity_main, but nothing happens when i change the seekbar
Here is the code:
//control volume using seek bar in Setting
private AudioManager audiomanager = null;
private SeekBar seekbar = null;
// SoundStatus
private TextView soundstatus = null;
// check Sound on
private boolean soundon = true;
// control Background Sound
private MediaPlayer mp = null;
// Sound icon
private ImageView sound = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
setContentView(R.layout.activity_main);
// Background music when the app launch
// music in raw folder
mp = MediaPlayer.create(this, R.raw.backgroundsound);
mp.start();
mp.setLooping(true);
// Control volume
ControlVolume();
}
...
...
...
public void ControlVolume()
{
seekbar = (SeekBar)findViewById(R.id.seekBar);
audiomanager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
seekbar.setMax(audiomanager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
seekbar.setProgress(audiomanager
.getStreamVolume(AudioManager.STREAM_MUSIC));
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
{
#Override
public void onStopTrackingTouch(SeekBar arg0)
{
}
#Override
public void onStartTrackingTouch(SeekBar arg0)
{
}
#Override
public void onProgressChanged(SeekBar arg0, int progress, boolean arg2)
{
audiomanager.setStreamVolume(AudioManager.STREAM_MUSIC,
progress, 0);
}
});
}
this is MainActivity.java
main layout include button setting
and the seekbar is in setting layout
I'm new to Android programming and am building a simple app that plays a sound from a local file when you flip the phone over, using a SensorListener for the accelerometer. Additionally, there's an image with a click listener that also plays the same sound when touched.
My code has the following sequence:
onCreate and onRestart - call MediaPlayer.create() for the local file.
onDestroy - call MediaPlayer.release and set the reference to null.
I'm debugging the app on my phone since the emulator doesn't support accelerometers.
When I click the image, I get a start called in state 64 error in Logcat, and when I flip the phone, the app FCs with a NullPointerException when mp.start() is called.
My understanding of how it works, from the MediaPlayer documentation is that you have to call create(), which in turn calls prepare() before you can start or stop the player. Is there a problem with the sequence of steps?
I've also tried releasing the media player in onStop, to no avail.
I have the following sensor listener for the accelerometer (mp is the MediaPlayer object) -
private final SensorEventListener accelerometerListener = new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent arg0) {
float z_value = arg0.values[2];
if (z_value < 0 && playerReady) {
mp.start(); // <-- NullPointerException thrown here.
} else {
mp.stop();
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
..and the following click listener for the button -
private final View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (playerReady) {
mp.start();
}
}
};
I also wrote an onPreparedListener for the media player (which sets the playerReady seen above)
private final OnPreparedListener opl = new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
playerReady = true;
}
};
Edit Here's onCreate() and onRestart() -
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mp = MediaPlayer.create(Moo.this, R.raw.moo);
mp.setOnPreparedListener(opl);
ImageView im = (ImageView) findViewById(R.id.imageView1);
im.setOnClickListener(onClickListener);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager
.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (sensorList.size() > 0) {
accelerometerPresent = true;
accelerometerSensor = sensorList.get(0);
sensorManager.registerListener(accelerometerListener,
accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
#Override
protected void onRestart() {
super.onRestart();
mp = MediaPlayer.create(Moo.this, R.raw.moo);
}