Android MediaPlayer pause - java

The problem I am having at the moment is that my pause is not always working.
What I have is an MediaPlayer in main activity that is operated via ActionBarSherlock and onClick listeners. MediaPlayer is using ArrayList with URLs of MP3 files(some of them 1sec long).
Pause code:
if (player.isPlaying()) {
if (player != null) {
player.pause();
swapPlayIcon(1);
isPaused = true;
pauseMenuButt.setVisible(false);
playMenuButt.setVisible(true);
}
}
swapPlayIcon(int) handles only visibility and drawable swaps.
Start code:
Iterator<Uri> iterUri = tracks.iterator();
while (iterUri.hasNext()) {
Uri tmpUri = iterUri.next();
try {
player.reset();
player.setDataSource(String.valueOf(tmpUri));
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
EDIT
After more testing I have found out that the problem appear in "in between" state.
What I mean is that when my MP3 file is 2sec long and I click pause its not stopping becouse it just have ended reading one file and now moved on to the next one.
I have added:
} else {
pauseLocked = true;
}
to pause if statment and it does not land in it at all while testing.
So im not sure about the "in between" problem that I have found out previously.

Your pause button is not working because there's no way for its message to ever reach the MediaPlayer until you've started the last URL. You are entirely blocking the thread your MediaPlayer is running on (I'm assuming it's the UI thread since the MediaPlayer is in your main activity). If you're creating your MediaPlayer on the same thread as your UI, you should use the asynchronous version of prepare: prepareAsync. You need to respond once you receive the onMediaPrepared callback and then start the media. Once that happens you must do nothing and wait for the media to finish, only then should you load another url.

Related

How do I get the flashlight on my phone to flash accurately?

I am currently coding an Android application on android studio with Java. This one is simple, when the button is clicked, a series of flashing of the phone's torch is launched. I need each flash to be regulated, and last the same time, but it's not the case, each flash does not last the same.
For this code, for example, we have 150 loops of 400 milliseconds, so we should have 150*0.4=60 seconds of operation, but by timing, I have about 65 seconds, certainly because of the inprecision of the duration of each flash.
I wanted to know if anyone has an idea, how to solve this problem,
Thanks in advance.
private void switchOn(){ // Function that is called each time the user presses the button (Onclick )
for (int i=0; i<150; i++){
flash(); // It calls the function that turns the torch on or off
try {
Thread.sleep(200); // process that puts a delay and allows the torch to work 200 milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
flash();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void flash(){ // function that turns the torch on or off according to its state
try {
CameraManager cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
for (String id : cameraManager.getCameraIdList()) {
if (cameraManager.getCameraCharacteristics(id)
.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
cameraManager.setTorchMode(id, !flashState);
flashState = !flashState;
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}

Can not play music from http server for over 3 seconds

I am trying to make a music streaming app. For the music I use a URL, and for some reason, the music is playing for 3 seconds and then automatically stops. pls help me fix it.
I also get a message in the Run says: "MediaPlayer finalized without being released".
Thanks.
the code:
String url = "https://radio.streamgates.net/stream/1036kh"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
try {
mediaPlayer.setDataSource(url);
} catch (IOException e) {
Toast.makeText(this,"failed", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
try {
mediaPlayer.prepare(); // might take long! (for buffering, etc)
} catch (IOException e) {
Toast.makeText(this,"failed", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
mediaPlayer.start();

android camera click continous shots

I am trying to make camera application which takes 3 continuous shots.
i have tried to call "takePicture" several times by putting it in a loop.
but no success.
please help on this matter.
a little help will be appreciated.
You never should call PictureCallback.onPictureTaken() from your code; this callback receives data from the system when it is ready, as response to Camera.takePicture().
The latter call will only succeed if the camera is opened and preview is started. Therefore, simply calling Camera.takePicture() in a loop will not work (see e.g. Android 2.3.1 Camera takePicture() Multiple images with one button click). The correct way to handle this is to keep a counter of shots processed in your onPictureTaken(), and if it is less than 3, then restart camera preview and issue (synchroneously) another Camera.takePicture(). After this, onPictureTaken() should return, to allow processing of the next captured frame.
I use it like this when doing a PhotoBurst. It is also handling the FRameLayout holding the preview to start the PhotoBurst:
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
Parameters param = camera.getParameters();
param.setPictureSize(640, 480);
camera.setParameters(param);
// Or write to sdcard
outStream = new FileOutputStream(String.format(
Environment.getExternalStorageDirectory().getPath()+"/foto%d.jpg",
System.currentTimeMillis()));
outStream.write(data);
outStream.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.fromFile(Environment.getExternalStorageDirectory())));
Log.i(TAG, "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Log.d(TAG, "onPictureTaken - jpg");
try {
stillCount++;
camera.startPreview();
if (stillCount < 10) {
preview.mCamera.takePicture(shutterCallback, rawCallback,
jpegCallback);
if (stillCount == 9) {
frameLayout.setClickable(true);
}
} else {
stillCount = 0;
takePictureButton.setEnabled(true);
frameLayout.setClickable(true);
}
} catch (Exception e) {
Log.d(TAG, "Error starting preview: " + e.toString());
}
}
};
I got the solution.
i was calling mCamera.startPreview(); out of my loop.
preview is must to take shots, and not including mCamera.startPreview(); was blocking my execution.

toast line is never called

When I press an image on the screen, it calls the powerButton.OnClickListener() like it's supposed to and, after a few seconds of buffering, the stream plays just fine. However, the folks would like a brief toast popup to display to notify the user "Radio Stream Connecting, Please Wait..."
This is where the problem is, no matter what I've tried and where I've placed the line to create the toast popup, it simply will not display before it goes into buffering.
Any help would be greatly appreciated and I've added most of the code and will provide more if necessary.
// run on powerButton click
powerButton.setOnClickListener(new OnClickListener()
{
public void onClick(View view)
{
// check if the player is started or stopped
if (isPlaying) // player is streaming
{
// stop the stream and set isPlaying to false
mediaPlayer.stop();
// release the media player
releaseMediaPlayer();
// update notification
mNotificationManager.cancel(SIMPLE_NOTFICATION_ID);
// set power button to "powered off" image
powerButton.setImageResource(R.drawable.power_off);
}
else // player not streaming
{
// notify the user that the stream is loading
final Toast streamLoading = toast.makeText(getBaseContext(), "Radio Stream Connecting, Please Wait...", Toast.LENGTH_SHORT);
streamLoading.show();
// try catch block to attempt connecting to radioUrl
try
{
// create new instance of media player
mediaPlayer = new MediaPlayer();
// set media player to handle audio streams
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
// connect to radio stream and fill buffer
mediaPlayer.setDataSource(radioUrl);
mediaPlayer.prepare(); // might take long depending on buffering speed
// start the media player and set isPlaying to true
mediaPlayer.start();
isPlaying = true;
// update notification, clear stream message
createNotification();
// set power button to "powered on" image
powerButton.setImageResource(R.drawable.power_on);
}
catch (IllegalArgumentException e) // cannot connect to stream
{
// clear streaming text and notify user of failure
final Toast streamError1 = Toast.makeText(MainMenu.this, "Failed to load: Unable to connect to stream!", Toast.LENGTH_SHORT);
streamError1.show();
// release the media player and display error
releaseMediaPlayer();
mNotificationManager.cancel(SIMPLE_NOTFICATION_ID);
e.printStackTrace();
}
catch (IllegalStateException e) // stream cannot play audio
{
// clear streaming text and notify user of failure
final Toast streamError2 = Toast.makeText(getBaseContext(), "Failed to load: cannot play stream!", Toast.LENGTH_SHORT);
streamError2.show();
// release the media player and display error
releaseMediaPlayer();
mNotificationManager.cancel(SIMPLE_NOTFICATION_ID);
e.printStackTrace();
}
catch (IOException e) // general connection issue
{
// clear streaming text and notify user of failure
final Toast streamError3 = Toast.makeText(getBaseContext(), "Failed to Load: Connection issue!", Toast.LENGTH_SHORT);
streamError3.show();
// release the media player and display error
releaseMediaPlayer();
mNotificationManager.cancel(SIMPLE_NOTFICATION_ID);
e.printStackTrace();
}
}
}
});
That's because the toast won't show until you return from the onClick because that is the UI thread. I You won't do that until after the buffering is started. I think to get the effect you want, you check the AsynchTask to do the buffering in a background thread and return right away from the onClick.
As a matter of fact the way you are doing it, if the buffering takes too long your app will get flagged as non responsive by android.
Try using an AsyncTask where the first thing the AsyncTask does is display the toast before falling into the buffering procedure.

Android media player stop playing while in background

I'm making music player app with simple functionality. But when I listen music on my phone with Android 6, sometimes music stops playing until I turn on display again with power button. Then next song is playing, so it seems like it's problem with loading next song. I tried to write new app just to test it out, for this purpose I used this tutorial:
https://code.tutsplus.com/tutorials/background-audio-in-android-with-mediasessioncompat--cms-27030
To this example I added ArrayList with paths to songs. In mediaPlayer onCompletionListener I increase track counter and load new song to media player.
My code:
private void initMediaPlayer() {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setVolume(1.0f, 1.0f);
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer)
{
onTrackCompletion();
}
});
private void onTrackCompletion()
{
NextTrack();
Play();
}
private void NextTrack()
{
playlistPosition++;
if (playlistPosition == playlists.get(playlistCurrent).size){
playlistPosition = 0;
}
sendAction(ACTION_TRACK_NEXT);
if(mMediaPlayer.isPlaying()){
Pause();
}
loadSong();
Play();
}
private void loadSong()
{
String path = playlists.get(playlistCurrent).getPath(playlistPosition);
if(path == null || path == "")
{
return;
}
try
{
try
{
mMediaPlayer.setDataSource(path);
} catch( IllegalStateException e ) {
mMediaPlayer.release();
initMediaPlayer();
mMediaPlayer.setDataSource(path);
}
initMediaSessionMetadata();
} catch (IOException e) {
return;
}
try {
mMediaPlayer.prepare();
} catch (IOException e) {}
sendTrackData();
}
I don't know anymore why this doesn't work. In manifest I have WAKE_LOCK permission. I also set wake lock for Media player.
Edit:
Today I tried to move loading song into onPlayFromMediaId. I made broadcast from AutoActivity where is Media player to Main Activity and send back onPlayFromMediaId with path to song. But seems like this doesn't work either.I also find out that changing volume with buttons also wake up app.
Edit2:
I made many tests and added debug string in many places in code. And I found out that app stops at mediaplayer.prepare() until I trigger any action on phone (turn on display, volume up/down, click headset button). But I don't know how to fix this bug. I tried to use prepareAsync, but didn't help.
Unless you use foreground service, the system will kill your process and mediaplayer will stop.
below is a part from from a foreground service ( notification example).
builder.setContentTitle(aMessage) // required
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText(this.getString(R.string.app_name)) // required
.setAutoCancel(false)
.setContentIntent(pendingIntent)
.setVibrate(new long[]{0L})
.setPriority(Notification.PRIORITY_HIGH);
int mId = 1489;
startForeground(mId, builder.build());
The above code is tested and working fine.

Categories

Resources