How can I control the media player with service? - java

I am new to coding and at this point, I made a media player that starts and pauses the audio, has a working seekbar, duration, etc. Now I faced a big issue. The audio can't be played in the background and I found out that I can do this with service but this changes things. I read all kinds of topics on how to control the audio in service with seekbar and all kinds of stuff but nothing helped me. The main problem I face is having the seekbar to control the audio and a text to read the time. If there is someone to help me find a code for this it would be much appreciated.
The layout:
<SeekBar
android:id="#+id/seekBarMusic1"
android:layout_width="match_parent"
android:layout_height="#dimen/_20sdp"
android:layout_marginTop="#dimen/_12sdp"
android:layout_marginLeft="#dimen/_20sdp"
android:layout_marginRight="#dimen/_20sdp"
app:layout_constraintTop_toBottomOf="#+id/cardView"
tools:layout_editor_absoluteX="10dp" />
<TextView
android:id="#+id/playerPositionMusic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00"
android:textColor="#color/remain_black"
android:textSize="25dp"
android:layout_marginBottom="#dimen/_80sdp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="#+id/cardView"
app:layout_constraintTop_toBottomOf="#+id/seekBarMusic1" />
<TextView
android:id="#+id/text_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/_80sdp"
android:text="15:00"
android:textColor="#color/remain_black"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#+id/cardView"
app:layout_constraintTop_toBottomOf="#+id/seekBarMusic1" />
<ImageView
android:id="#+id/btPlayMusic"
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.9"
android:background="#drawable/play"
android:theme="#style/Button.White"
app:layout_constraintEnd_toStartOf="#+id/text_time"
app:layout_constraintStart_toEndOf="#+id/playerPositionMusic"
app:layout_constraintTop_toBottomOf="#+id/seekBarMusic1"
app:tint="#color/remain_black" />
<ImageView
android:visibility="gone"
android:id="#+id/btPauseMusic"
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.9"
android:background="#drawable/pause"
android:theme="#style/Button.White"
app:layout_constraintEnd_toStartOf="#+id/text_time"
app:layout_constraintStart_toEndOf="#+id/playerPositionMusic"
app:layout_constraintTop_toBottomOf="#+id/seekBarMusic1"
app:tint="#color/remain_black" />
The code I used before:
public class m1 extends AppCompatActivity {
ImageView btPlay, btPause;
TextView playerPosition, playerDuration;
CircularSeekBar seekBar;
MediaPlayer mediaPlayer;
Handler handler = new Handler();
Runnable runnable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_m1);
findViewById(R.id.backm1).setOnClickListener(v -> onBackPressed());
playerPosition = findViewById(R.id.playerPosition);
playerDuration = findViewById(R.id.playerDuration);
replay = findViewById(R.id.replay);
forward = findViewById(R.id.forward);
seekBar = findViewById(R.id.seekBar);
btPause = findViewById(R.id.btPause);
btPlay = findViewById(R.id.btPlay);
mediaPlayer = MediaPlayer.create(this,R.raw.ding_dong);
runnable = new Runnable() {
#Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
handler.postDelayed(this,500);
}
};
int duration = mediaPlayer.getDuration();
String sDuration = convertFormat(duration);
playerDuration.setText(sDuration);
btPlay.setOnClickListener(v -> {
mediaPlayer.start();
btPlay.setVisibility(View.GONE);
btPause.setVisibility(View.VISIBLE);
seekBar.setMax(mediaPlayer.getDuration());
handler.postDelayed(runnable, 0)
});
btPause.setOnClickListener(v -> {
mediaPlayer.stop();
btPause.setVisibility(View.GONE);
btPlay.setVisibility(View.VISIBLE);
handler.removeCallbacks(runnable);
});
seekBar.setOnSeekBarChangeListener(new CircularSeekBar.OnCircularSeekBarChangeListener() {
#Override
public void onProgressChanged(CircularSeekBar circularSeekBar, float v, boolean b) {
if (b) {
mediaPlayer.seekTo((int) v);
}
playerPosition.setText(convertFormat(mediaPlayer.getCurrentPosition()));
}
#Override
public void onStopTrackingTouch(CircularSeekBar circularSeekBar) {
}
#Override
public void onStartTrackingTouch(CircularSeekBar circularSeekBar) {
}
});
mediaPlayer.setOnCompletionListener(mp -> {
btPause.setVisibility((View.GONE));
btPlay.setVisibility(View.VISIBLE);
mediaPlayer.seekTo(0);
});
}
}
#SuppressLint("DefaultLocale")
private String convertFormat(int duration) {
return String.format("%02d:%02d"
,TimeUnit.MILLISECONDS.toMinutes(duration)
,TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)));
}
#Override
public void onPause()
{
if(mediaPlayer != null && mediaPlayer.isPlaying())
{
mediaPlayer.stop();
}
super.onPause();
}
}
The code I am using now:
btPause = findViewById(R.id.btPauseMusic);
btPlay = findViewById(R.id.btPlayMusic);
btPlay.setOnClickListener(v -> {
startService(new Intent(this, BackgroundMusicService.class));
btPlay.setVisibility(View.GONE);
btPause.setVisibility(View.VISIBLE);
});
btPause.setOnClickListener(v -> {
stopService(new Intent(this, BackgroundMusicService.class));
btPause.setVisibility(View.GONE);
btPlay.setVisibility(View.VISIBLE);
});
}
And the service class:
public class BackgroundMusicService extends Service {
private MediaPlayer mediaPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer = MediaPlayer.create(this, R.raw.ding_dong);
mediaPlayer.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
}

You are using different MediaPlayer in the Activity from the one in the backgroundService
you don't need to initialize another mediaPlayer in the activity you have to control the one in the backgroundService with Broadcast receivers like this for example to pause a the mediaPlayer in the backgroundService you do something like this
private BroadcastReceiver pausePlayingAudio = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
pause();
updateMetaData();
buildNotification(PlaybackStatus.PAUSED);
playbackStatus = PlaybackStatus.PAUSED ;
}
};
private void register_pausePlayingAudio(){
IntentFilter intentFilter = new IntentFilter(SongAdapter.ACTION_PAUSE) ;
registerReceiver(pausePlayingAudio , intentFilter) ;
}
and you call register_pausePlayingAudio() in onCreate() of the backGroundService
now say when a user clicks on a button in the activity and you want to pause you use something like this
sendBroadcast(new Intent(SongAdapter.ACTION_PAUSE));
I have and old project not finished doesn't have a seekBar but the seekBar implementation will be similar just instead of pause() you call seekTo() so you can check it
the repo

This article Creating Media player service shows step by step on how you can implement a service to create a Mediaplayer application to run in the background.

Related

Why does my CountDownTimer seem to be going backward?

I'm trying to make an app that reminds you to charge your phone if it is not used for a while. It works like this: you enter how long the phone should be idle before it reminds you. Then it starts a timer and reminds you when it finishes.
Here's my MainActivity.Java:
public class MainActivity extends AppCompatActivity {
//Defining UI elements
public Button changeAppStateButton;
public TextView minsEditText;
//App variables
boolean isAppRunning = false;
public int secondsPhoneIsAsleep;
public int timerDuration = secondsPhoneIsAsleep * 1000; //multiplying seconds by 100 to get milliseconds
public int tickDuration = 60000; //multiplying seconds (1) by 100 to get milliseconds
//Called when button is pressed
public void changeAppState(View view) {
Button changeAppStateButton = (Button) view;
if (isAppRunning) { //If the app is running, stop app
isAppRunning = false;
changeAppStateButton.setBackgroundColor(getColor(R.color.colorPurple));
changeAppStateButton.setText("Start Reminder");
timer.cancel();
Log.i("TIMER", "Timer interrupted");
} else { //If the app is not running, start app
secondsPhoneIsAsleep = Integer.parseInt(minsEditText.getText().toString()) * 60;
isAppRunning = true;
changeAppStateButton.setBackgroundColor(getColor(R.color.colorRed));
changeAppStateButton.setText("Stop Reminder");
timer.start();
Log.i("TIMER", "Timer started");
}
}
public CountDownTimer timer = new CountDownTimer(timerDuration, tickDuration) {
#Override
public void onTick(long millisUntilFinished) {
Log.i("TIMER", "tick");
}
#Override
public void onFinish() {
isAppRunning = false;
changeAppStateButton.setBackgroundColor(getColor(R.color.colorPurple));
changeAppStateButton.setText("Start Reminder");
Log.i("TIMER", "Timer finished");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setting values for UI elements
changeAppStateButton = findViewById(R.id.changeAppStateButton);
minsEditText = findViewById(R.id.minEditText);
}
This is part of my XML:
<EditText
android:id="#+id/minEditText"
android:layout_width="59dp"
android:layout_height="42dp"
android:layout_marginTop="14dp"
android:ems="10"
android:foregroundTint="#FF0000"
android:inputType="number"
android:text="30"
android:textAlignment="center"
android:textColor="#000000"
android:textSize="20sp"
app:layout_constraintStart_toEndOf="#+id/whenUntouched"
app:layout_constraintTop_toBottomOf="#+id/numberEditText" />
<Button
android:id="#+id/changeAppStateButton"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="110dp"
android:background="#9C27B0"
android:fontFamily="#font/alegreya_sans_sc"
android:onClick="changeAppState"
android:text="Start Reminder"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="25sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
This is logcat when I press the button:
I/DEV_TIMER: Timer finished
I/DEV_TIMER: Timer started
Why does the timer seem to be going backward? Why isn't it logging a message every "tick"?
Some explanation would be highly appreciated. I'm not too experienced with Android and Java.
Since the code specified in MainActivity.java
Doesn't initialize variable secondsPhoneIsAsleep, so the default value will be 0.
So timerDuration will be 0.
So timer is created to count for a duration of 0.
So when the button is clicked, even though you read new value for secondsPhoneIsAsleep, invoking timer.start() will cause it to count only till 0 based on the earlier initialized value.
Hence onFinish() gets called logging Timer finished, then the Timer started gets logged as part of button click code.
Solution
If you create timer instance on button click then it should use the correct value of secondsPhoneIsAsleep and work properly. Like below:
MainActvity.java
public class MainActivity extends AppCompatActivity {
//Defining UI elements
public Button changeAppStateButton;
public TextView minsEditText;
//App variables
boolean isAppRunning = false;
public int secondsPhoneIsAsleep;
public CountDownTimer timer;
public int timerDuration;
public int tickDuration = 1000; //multiplying 1 second by 1000 to get milliseconds
//Called when button is pressed
public void changeAppState(View view) {
Button changeAppStateButton = (Button) view;
if (isAppRunning) { //If the app is running, stop app
isAppRunning = false;
changeAppStateButton.setBackgroundColor(getColor(R.color.colorPurple));
changeAppStateButton.setText("Start Reminder");
timer.cancel();
Log.i("TIMER", "Timer interrupted");
} else { //If the app is not running, start app
secondsPhoneIsAsleep = Integer.parseInt(minsEditText.getText().toString()) * 60;
timerDuration = secondsPhoneIsAsleep * 1000;
timer = getNewTimer(); // Creates a new timer.
isAppRunning = true;
changeAppStateButton.setBackgroundColor(getColor(R.color.colorRed));
changeAppStateButton.setText("Stop Reminder");
timer.start();
Log.i("TIMER", "Timer started");
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Setting values for UI elements
changeAppStateButton = findViewById(R.id.changeAppStateButton);
minsEditText = findViewById(R.id.minEditText);
}
private CountdownTimer getNewTimer() {
return new CountDownTimer(timerDuration, tickDuration) {
#Override
public void onTick(long millisUntilFinished) {
Log.i("TIMER", "tick");
}
#Override
public void onFinish() {
isAppRunning = false;
changeAppStateButton.setBackgroundColor(getColor(R.color.colorPurple));
changeAppStateButton.setText("Start Reminder");
Log.i("TIMER", "Timer finished");
}
};
}

Using the camera in android

I am trying to build an Android app that simply uses the camera to take a picture without launching the default camera app. In other words, I want to make a custom camera app. I can do this using the Camera hardware object class, however this is deprecated and I want to use some of the new features of camerax and not have to worry about the code not working after some time. I have also read the camera API documentation, however it is still unclear how to use the camera. Are there any very simple step by step tutorials or guides that might help me?
Thanks,
You can check my example about how to use AndroidX libraries and TextureView for camera customization.
https://github.com/icerrate/Custom-Camera-App
First at all, define your layout. This is my activity_main.xml file:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextureView
android:id="#+id/view_finder"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/take_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="#dimen/horizontal_margin"
app:layout_constraintStart_toStartOf="parent"
android:src="#drawable/ic_camera"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Remember that TextureView will receive the camera preview and the Floating Action Button works as a "Take Photo" button.
Then add your MainActivity.java file:
public class MainActivity extends AppCompatActivity implements LifecycleOwner {
private static final int RC_PERMISSIONS = 100;
private TextureView viewFinder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
viewFinder = findViewById(R.id.view_finder);
FloatingActionButton takePhotoFab = findViewById(R.id.take_photo);
//Check permissions
if (allPermissionGranted()) {
viewFinder.post(new Runnable() {
#Override
public void run() {
startCamera();
}
});
} else {
ActivityCompat.requestPermissions(this,
new String[] {Manifest.permission.CAMERA}, RC_PERMISSIONS);
}
takePhotoFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePhoto();
}
});
}
private void startCamera() {
Point screenSize = getScreenSize();
int width = screenSize.x;
int height = screenSize.y;
//Get real aspect ratio
DisplayMetrics displayMetrics = new DisplayMetrics();
Display display = getWindowManager().getDefaultDisplay();
display.getRealMetrics(displayMetrics);
Rational rational = new Rational(displayMetrics.widthPixels, displayMetrics.heightPixels);
//Build the camera preview
PreviewConfig build = new PreviewConfig.Builder()
.setTargetAspectRatio(rational)
.setTargetResolution(new Size(width,height))
.build();
Preview preview = new Preview(build);
preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {
#Override
public void onUpdated(Preview.PreviewOutput output) {
ViewGroup group = (ViewGroup) viewFinder.getParent();
group.removeView(viewFinder);
group.addView(viewFinder, 0);
viewFinder.setSurfaceTexture(output.getSurfaceTexture());
}
});
CameraX.bindToLifecycle(this, preview);
}
private void takePhoto() {
Toast.makeText(this, "Shot!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RC_PERMISSIONS) {
if (allPermissionGranted()) {
viewFinder.post(new Runnable() {
#Override
public void run() {
startCamera();
}
});
} else {
Toast.makeText(this, "Permission not granted",
Toast.LENGTH_SHORT).show();
finish();
}
}
}
private boolean allPermissionGranted() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
private Point getScreenSize() {
Display display = getWindowManager(). getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
}
In this class, you would be able to send the camera preview to the TextureView, with help of PreviewConfig.Builder() and binding it to the Activity lifeCycle using CameraX.bindToLifeCycle()
Also, don't forget to add Camera permission to the manifest and consider runtime permissions.
Screenshot:
Custom Camera preview
Hope this help you!

My countdown timer code not working properly

I am creating a simple countdown timer in android studio which has a start and a pause button. The timer countdown starts but does not pause instead it starts increasing and decreasing by clicking pause button. Here is my code.
<TextView
android:id="#+id/txtview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Counter"
android:textSize="75sp"
android:textColor="#ff0000"
/>
<Button
android:id="#+id/push_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Count Down"
android:onClick="perform_action"
android:textSize="35sp"
/>
<Button
android:id="#+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause Count Down"
android:onClick="perform_action"
android:textSize="35sp"
/>
Java code
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void perform_action(View view)
{
long totalMilliseconds = 90000;
long interval = 1;
Button b1 = (Button)findViewById(R.id.push_button);
String push = b1.getText().toString();
CountDownTimer timer;
timer = new CountDownTimer(40000, 1000) {
TextView t1 = (TextView)findViewById(R.id.txtview1);
#Override
public void onTick(long l) {
t1.setText(""+(l));
}
#Override
public void onFinish() {
t1.setText("Finish");
}
};
if(push.equals("Start Count Down")){
timer.start();
}
else if(push.equals("Pause Count Down")){
timer.cancel();
}
}
}
Please provide me some help
It looks like you're spawning a new timer every time you click the button, from the snippet you posted. You can just use an OnClickListener.
You can access it like so (example uses a boolean to switch states);
Boolean ButtonClicked = false;
b1.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//Perform your click logic to start and stop the timer
if (!ButtonClicked)) {
ButtonClicked = true;
timer.start();
} else {
ButtonClicked = false;
timer.cancel();
}
}
});

background music doesn't stop if app is onStop Android

I have created a service to play music through my activities. I Have 2 activities and a splashScreen. I start the service from the first acitivity and by clicking some items I go to the second activity. The music is played properly but when I put my app in background or I lock my phone or I'm in another app I still hear the sound. I cannot put stopService in onStop because if I go to my second activity, the music will stop.
Here's my service music class :
public class BackgroundMusicService extends Service {
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.game_music);
player.setLooping(true);
player.setVolume(10, 10);
player.start();
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
and :
public class Activity1 extends AppCompatActivity implements View.OnClickListener{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_1);
Intent backgSound = new Intent(Activity1.this, BackgroundMusicService.class);
startService(backgSound);
Button b1 = (Button) findViewById(R.id.b1);
b1.setOnClickListener(this);
}
#Override
public void onDestroy() {
super.onDestroy();
Intent backgSound = new Intent(Activity1.this, BackgroundMusicService.class);
stopService(backgSound);
}
#Override
public void onClick(View v) {
startActivity(new Intent(this,Activity2.class);
}
And the second activity is just a view (for test).
How could I keep the sound over these 2 activites and stop it when my app is in background or my phone is locked.
I've tried to stopService in onStop then startService in onResume, but it does not work between activities.
Judging by what you want you need a more fine grained control over the starting and stopping of your MediaPlayer object. An easy solution would be to add intent-filters and actions like so:
public class BackgroundMusicService extends Service {
public static final String ACTION_START_MUSIC = "package_name.action_start_music";
public static final String ACTION_STOP_MUSIC = "package_name.action_stop";
private MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.game_music);
player.setLooping(true);
player.setVolume(10, 10);
}
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent.getAction() != null){
switch (intent.getAction()){
case ACTION_START_MUSIC :
if(!player.isPlaying()){
player.start();
}
break;
case ACTION_STOP_MUSIC :
if(player.isPlaying()) {
player.stop();
}
break;
default: break;
}
}
return START_STICKY;
}
#Override
public void onDestroy() {
player.release();
}
#Override
public void onLowMemory() {
}
}
Update your manifest :
<service android:name=".BackgroundMusicService"
android:exported="false">
<intent-filter>
<action android:name="package_name.action_start_music" />
<action android:name="package_name.action_stop" />
</intent-filter>
</service>
To use:
startService(new Intent(BackgroundMusicService.ACTION_START_MUSIC));
startService(new Intent(BackgroundMusicService.ACTION_STOP_MUSIC));
It is well known that onDestroy() is not always calling, moving your onDestroy actions to the onPause() method will work:
Note: do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here. This method is usually implemented to free resources like threads that are associated with an activity, so that a destroyed activity does not leave such things around while the rest of its application is still running. There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.
More info here.
You need to read more about the basics of Android.
Regards.

Android - Need to Pause playing mediafile at particular instance

I have a page consisting of three different Buttons PLAY | PAUSE | STOP.
PLAY | STOP is working fine, but i'm not able to pause at particular instance. I want to pause playing at an instance, by pressing pause button. And then resume it from saved instance by again pressing Play button.
Below is the code from Sound.java file
public class Sound extends Activity {
MediaPlayer mp = null;
String play = "Play!";
String stop = "Stop!";
String pause = "Pause";
int length;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sound);
final ImageButton play = (ImageButton) findViewById(R.id.idplay);
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound("play");
Toast toast_play = Toast.makeText(getBaseContext(),
"Playing First", Toast.LENGTH_SHORT);
toast_play.show();
} // END onClick()
});
final ImageButton pause = (ImageButton) findViewById(R.id.idpause);
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
managerOfSound("pause");
Toast toast_pause = Toast.makeText(getBaseContext(),
"Pausing Morning Bhajan-Aarati", Toast.LENGTH_SHORT);
toast_pause.show();
} // END onClick()
});
final ImageButton stop = (ImageButton) findViewById(R.id.idstop);
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mp != null) {
mp.stop();
mp.reset();
Toast toast_stop = Toast.makeText(getBaseContext(),
"Stopping First",
Toast.LENGTH_SHORT);
toast_stop.show();
}
} // END onClick()
});
/** Manager of Sounds **/
protected void managerOfSound(String theText) {
if (mp != null){
mp.reset();
mp.release();
}
if (theText == "play")
mp = MediaPlayer.create(this, R.raw.goodbye);
else if (theText == "pause" && mp.isPlaying())
mp.pause();
length = mp.getCurrentPosition();
mp.seekTo(length);
mp.start();
}
Here is my sound.xml file,
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageButton
android:id="#+id/idplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="65dp"
android:layout_marginTop="20dp"
android:background="#drawable/image_play" />
<!-- android:text="#string/idplay" /> -->
<ImageButton
android:id="#+id/idpause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_toLeftOf="#+id/idstop"
android:background="#drawable/image_pause" />
<ImageButton
android:id="#+id/idstop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_toRightOf="#+id/idplay"
android:background="#drawable/image_stop" />
</RelativeLayout>
Your Help is Appreciated..!!
I think your problem is this line:
if (theText == "play")
mp = MediaPlayer.create(this, R.raw.goodbye);
else if (theText == "pause" && mp.isPlaying())
mp.pause();
length = mp.getCurrentPosition();
mp.seekTo(length);
mp.start();ยด
You are setting the length by clicking the pause button, but you will start it again directly in this if clause.
You should check if the play button is clicked if the media was playing befor, something like
if(length > 0)
and then start the player at the specified position.
Edit:
In addition, you should not use the operator == to compare strings. You should better use string1.equals(string2)
Hope it helps
Best wishes

Categories