toast line is never called - java

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.

Related

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();

Attempting to record mic input over Bluetooth

I have an Arduino which broadcasts via Bluetooth, input from a mic.
I want to connect the phone so that it'll record and save the input from the Arduino mic via Bluetooth.
When I run the following code, I have a few issues.
I can't seem to find the file I saved.
File file=new File(mFilePath2,"test.txt");
On Logcat I'm getting the following errors when I run Bluetooth_Test()
ACDB-LOADER - Error: ACDB AudProc vol returned = -19
MediaPlayer - Error (1, -1004)
When I run stop() I get:
MPEG4Writer - Stop() called but track is not started
MediaPlayer-JNI QCMediaPlayer mediaplayer NOT present
MediaPlayer - Should have subtitle controller already set
I'm not sure what is happening and I'm not sure how to figure it out.
References:
Sony - Use Bluetooth for audio I/O
Media Player called in state 0, error (-38,0) (it solved one error, not listed above)
Code:
public void Bluetooth_Test (){
Toast.makeText(getActivity(), "weee", Toast.LENGTH_LONG).show();
maudioManager = (AudioManager) getActivity().getSystemService(getActivity().AUDIO_SERVICE);
// Switch to headset
maudioManager.setMode(AudioManager.MODE_IN_CALL); // to use headset's I/O and not phone's
// Start audio I/O operation (in background)
maudioManager.startBluetoothSco();
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // set source to current mic (should be Bluetooth)
mFilePath = Environment.getExternalStorageDirectory().getAbsolutePath();
String mFilePath2 = mFilePath;
mFilePath += "/youraudiofile.mp3";
File file=new File(mFilePath2,"test.txt");
// Set file extension for the recorded audio file
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// Set a file path for the recorded audio file
mRecorder.setOutputFile(mFilePath);
// Set encoding of the audio
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
}
catch (IOException e){
Log.e("Starting mRecorder", "IO Exception");
}
// Start recording
mRecorder.start();
}
public void stop () {
mRecorder.stop();
mRecorder.reset();
mRecorder.release();
mRecorder = null;
final MediaPlayer mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFilePath);
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mPlayer.start(); // Start playing audio file
}
});
// Audio file to be played
mPlayer.prepareAsync();
} catch (IOException e){
Log.e("Stop Function", "IO Exception");
}
}

MediaRecorder not saving files

I've had a look through the other people's encounters with this problem and have not found an adequate solution.
Like them, I followed the tutorial on camera functionality at: http://developer.android.com/guide/topics/media/camera.html.
Everything listed below works perfectly to the point where I assume that the program has recorded video as I had intended. However, upon reviewing the video in the gallery, it has not appeared. I'm confused as there are no IOExceptions or other bugs present when connected for USB debugging. Strangely, upon removing the USB and plugging it in again, whenever that may be, either immediately or at some point days in the future, all of the previously recorded videos appear in the gallery. Clearly there something I have missed or some aspect of recording video that I am not aware of. Would appreciate any help or guidance, thank you.
Pertinent code is as follows, I'll post more if someone needs it.
Camera Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
mCamera = MainActivity.getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
button_capture = (Button) findViewById(R.id.button_capture);
button_capture.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isRecording) {
// stop recording and release camera
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
button_capture.setText("Capture");
isRecording = false;
} else {
// initialize video camera
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
// inform the user that recording has started
button_capture.setText("Stop");
isRecording = true;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
}
}
});
}
private boolean prepareVideoRecorder(){
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
mMediaRecorder.setOutputFile(MediaCapture.getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
Media Capture:
public static Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(MEDIA_TYPE_VIDEO));
}
/**
* Create a File for saving an image or video
*/
public static File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES), "MyApplication");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyApplication", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HH:mm:ss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}
I too was very perplexed by this behaviour until I realised unplugging the USB was causing the files to appear. This appears to be a bug in Android, possibly related to this one :
https://code.google.com/p/android/issues/detail?id=195362
Clearly, the file has been written correctly, but for some reason the new file is not visible. In any case, the solution/workaround offered in the link above is to force a media scan of your file. e.g.
MediaScannerConnection.scanFile(getContext(), new String[]{this.mediaFile.getAbsolutePath()}, null, null);
Where 'mediaFile' is the file your mediaRecorder has just finished writing. With this in place I do not need to unplug the USB cable to see the file and it appears immediately after recording has finished.
I am running Android 5.0.2 on a Samsung Galaxy A5. This feels more of a workaround than a fix and I can't be sure it will work on other devices or Android versions, but I hope it helps someone.

Android MediaPlayer pause

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.

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