How to stop activity in Android? - java

I have created an activity which includes media player in it.When I start activity, the music begins to play.But when the song is complete and when i click on back button on the emulator, it displays an error of (IllegellStateException).
Here is my code:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.audio);
init();
imgVw.setImageResource(R.raw.teddy_two);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
mp=MediaPlayer.create(Audio_Activity.this,R.raw.ennamo_yadho);
Log.e("Song is playing","in Mediya Player ");
Log.e("Current ","Position -> " + length);
mp.setLooping(false);
mp.start();
btnChapter.setEnabled(false);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
// TODO Auto-generated method stub
mp.stop();
mp.release();
btnChapter.setEnabled(true);
System.out.println("Music is over and Button is enable !!!!!!");
}
});
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onPause()
{
super.onStop();
SharedPreferences. Editor prefsEdit = prefs.edit();
int position = mp.getCurrentPosition();
prefsEdit.putInt("mediaPosition", position);
prefsEdit.commit();
}
#Override
protected void onResume()
{
super.onResume();
System.out.println("Activity is Resume !!!");
int position = prefs.getInt("mediaPosition", 0);
mp.seekTo(position);
mp.start();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
if(mp!= null)
{
mp.pause();
}
//finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}

Use finish(); in Activity class to stop Activity and return.

Try this
MediaPlayer player;
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "service started", 100).show();
if(player.isPlaying())
player.stop();
else
player.start();
return super.onStartCommand(intent, flags, startId);}

I think the problem is here:
#Override
public void onPause()
{
super.onPause();//should be onPause and not onStop
SharedPreferences. Editor prefsEdit = prefs.edit();
int position = mp.getCurrentPosition();
prefsEdit.putInt("mediaPosition", position);
prefsEdit.commit();
}
For more info read here.

Here's an implementation of onStop() that saves the contents of a draft note to persistent storage:
#Override
protected void onStop() {
super.onStop(); // Always call the superclass method first
// Save the note's current draft, because the activity is stopping
// and we want to be sure the current note progress isn't lost.
ContentValues values = new ContentValues();
values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());
getContentResolver().update(
mUri, // The URI for the note to update.
values, // The map of column names and new values to apply to them.
null, // No SELECT criteria are used.
null // No WHERE columns are used.
);
}
Although the onPause() method is called before onStop(), you should use onStop() to perform larger, more CPU intensive shut-down operations, such as writing information to a database.
from android developer page: http://developer.android.com/training/basics/activity-lifecycle/stopping.html

if(mp!= null)
{
mp.pause();
}
The above code snippet inside if ((keyCode == KeyEvent.KEYCODE_BACK)) seems to be the problem. You should check whether the player is playing or not. If it is playing then only pause should be called.

You get (IllegelStateException) on the onPause().
To resolve this problem you need to put,
mp = null;
after,
mp.stop();
mp.release();
because when you check mp!=null that time MediaPlayer already release but not null.
so, if condition is correct and goto mp.pause() but mp already release that's why you get error.
Also you need to change name of MediaPlayer instance in onCompletion().
public void onCompletion(MediaPlayer mp)
because it is used mp of onCompletion() for stop() and release().
so, change mp to other(like: mp1).
check this is helpfull for you.

Related

When multiple clicks on activity navigation click, why 2nd activity lifecycle methods calling double times

When i multiple taps on a activity passing button, it takes activity1 has been pause state and after a few seconds activity2 has been come to foreground/visible to the user state.
my problem is , when we are moving on activities with multiple taps, it takes few seconds to user has been wait for next activity come to the visible state. it's really a bad practice.
Here is Call Logs of acticity lifecycle methods:
calling pause - Activity1
call: calling noti create - Activity2
call: calling noti start - Activity2
call: calling noti resume- Activity2
call: calling noti pause- Activity2
//2nd time calls of lifecycle methods
calling noti create- Activity2
call: calling noti start- Activity2
call: calling noti resume- Activity2
Here is Button click of activity navigation:
#OnClick({R.id.card_notification})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.card_notification:
startActivity(new Intent(context, NotificationsActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
break;
}
}
if i remove setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), activity2 opens multiple times when multiple taps on button click.
I tried with set launch mode in the manifest file.
<activity android:launchMode=”singleTop” />
in this case also activity 2 takes few mill seconds to come to visible state.
Note: When single tap/click everything works fine.
Please help me, what's going wrong in this scenario.
Here 2nd activity code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_noti_detail);
Log.e("call", "noti create");
context = this;
ButterKnife.bind(this);
setToolbar();
callApi("");
etSearchh.setOnEditorActionListener((v, actionId, event) ->
{
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
isSearch = true;
//membersList = null;
callApi(etSearchh.getText().toString().trim());
CommonUtils.hideKeyboard(this);
return true;
}
return false;
});
etSearchh.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.toString().length() > 0) {
iv_clearSearch.setVisibility(View.VISIBLE);
} else {
iv_clearSearch.setVisibility(View.INVISIBLE);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
iv_clearSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
iv_clearSearch.setVisibility(View.GONE);
etSearchh.setText("");
//membersList = null;
callApi("");
}
});
}
private void callApi(String searchBy) {
new NotificationController(apiCallBack, context, searchBy).callTokenAPI();
}
private void setToolbar() {
toolbarTitle.setText(MyApplication.getLabelModel().getLabels().getTT_NOTIFICATIONS());
etSearchh.setHint(MyApplication.getLabelModel().getLabels().getSEARCH_NOTIFICATION());
}
private void setRecycler(List<Notifications> notifications) {
mAdapter = new NotificationAdapter(notifications, context);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
}
#OnClick(R.id.iv_back)
public void onViewClicked() {
onBackPressed();
}
#Override
protected void onStart() {
Log.e("Call", "calling noti start");
super.onStart();
}
#Override
protected void onResume() {
Log.e("Call", "calling noti resume");
super.onResume();
}
#Override
protected void onStop() {
Log.e("Call", "calling noti stop");
super.onStop();
}
#Override
protected void onPause() {
Log.e("Call", "calling noti pause");
super.onPause();
}
To prevent multiple executions of button presses, you need to add a boolean variable that you use to remember that the button has been clicked and ignore the button click as "noise" if you see it again. Using your example, do this:
Add a boolean member variable to your class:
private boolean buttonClicked;
In onViewClicked() method, set the variable buttonClicked and ignore the click if it was already set:
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.card_notification:
// Ignore if already clicked
if (buttonClicked) {
return;
}
startActivity(new Intent(context, NotificationsActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
// Remember that the button was clicked
buttonClicked = true;
break;
}
This will prevent multiple clicks from starting multiple copies of NotificationsActivity. When the user returns to this Activity, you will want to reset buttonClicked in onResume() so that the user can again click the button (otherwise the user will only be able to click the button once!).

How to stop the sound/audio when you press the back button in the phone

how can i stop the audio from playing when i press the back button in my phone. when i go to another activity the audio is still playing unless i close the app. here's my code:
FloatingActionButton fab7 = (FloatingActionButton) this.findViewById(R.id.fab7);
final MediaPlayer mp = MediaPlayer.create( this, R.raw.cebu);
fab7.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {;
if(mp.isPlaying()){
mp.pause();
} else {
mp.start();
}
}
});
1.) declare MediaPlayer mp; outside onCreate
2.) override onStop and apply the same logic of click listener inside onStop
why onStop not onBackPress?
Because you want to pause the player when you go outside app as well as when you go to another activity
MediaPlayer mp;
onCreate(..){
mp = MediaPlayer.create( this, R.raw.cebu);
fab7.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {;
pausePlayer();
}
});
}
#Override
public void onStop(){
super.onStop()
pausePlayer();
}
void pausePlayer(){
if(mp.isPlaying()){
mp.pause();
} else {
mp.start();
}
}
#Override
public void onBackPress() {
pausePlayer();
mp.stop();
}
Use this to detect and pause the Mediaplayer
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
Log.d(this.getClass().getName(), "Back button pressed Song paused");
mp.pause();
}
return super.onKeyDown(keyCode, event);
}
write mediaplayer.stop();
on start of back activity when u gone
Override Activity#onBackPress() method to stop your player when pressing Back button:
#Override
public void onBackPress() {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
}
If you want to stop your player when your Activity finish, and don't care why (may be Back press, another Activity started, app crashed,..), you can override Activity#onStop() so you will make sure your music is immediately stop whenever your Activity gone!
#Override
public void onStop() {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
super.onStop();
}
Btw, note that you should use mp.stop() instead of mp.pause() then mp.release() to avoid memory/resources leak!

onBackPressed with Fragments Android

I am trying to implement onBackPressed on an activity with 3 Fragments. My issue is I implemented a "press again to exit" after some time method however when back button is clicked twice it returns to the previous fragment, not quitting. This happens when that fragment is called (i.e if I open the game and exit straight away it works like a charm). My onBackPressed method on MainActivity looks like this;
#Override
public void onBackPressed() {
if(getSupportFragmentManager().getBackStackEntryCount()!=0) {
getSupportFragmentManager().popBackStack();
}
this.findViewById(R.id.linearLayout1).setVisibility(View.VISIBLE);
if(mBackPressed + TIME_INTERVAL > System.currentTimeMillis() && getSupportFragmentManager().getBackStackEntryCount()==0){
super.onBackPressed();
System.exit(0);
this.finish();
}
else { Toast.makeText(getBaseContext(), "Press back once more to exit", Toast.LENGTH_SHORT).show(); }
mBackPressed = System.currentTimeMillis();
}
I basically want to check if the user is in the mainActivity layout so I could evade using popBackStack. Any solution would be appreciated, I could provide more information if this is not enough.
Thanks,
Bektaş
If you really want to quit, ignore the back stack altogether. Use this code.
#Override
public void onBackPressed() {
this.findViewById(R.id.linearLayout1).setVisibility(View.VISIBLE);
if(mBackPressed + TIME_INTERVAL > System.currentTimeMillis()){
this.finish();
return;
}
else {
Toast.makeText(getBaseContext(), "Press back once more to exit", Toast.LENGTH_SHORT).show();
}
mBackPressed = System.currentTimeMillis();
}
I think you might find this link useful
http://developer.android.com/training/implementing-navigation/temporal.html
it says that you can add the reference to the stack using this paturn
// Works with either the framework FragmentManager or the
// support package FragmentManager (getSupportFragmentManager).
getSupportFragmentManager().beginTransaction()
.add(detailFragment, "detail")
// Add this transaction to the back stack
.addToBackStack()
.commit();
#Override
public void onBackPressed() {
int count = getSupportFragmentManager().getBackStackEntryCount();
if (count == 0) {
getSupportFragmentManager().popBackStack(getSupportFragmentManager().getBackStackEntryCount(), getSupportFragmentManager().POP_BACK_STACK_INCLUSIVE);
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(context);
builder.setCancelable(false);
builder.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
(Main Activity Name).super.onBackPressed();
}
}).create().show();
} else {
super.onBackPressed();
}
}

Android: button is not changing to pause state when i click

i have coded for media player and it is playing song .In the front end only image button is used and hardcoded as play button
when i click again it has to change image to pause state but the button which i have used is playing the song two times simultaneously whenever i click on it which is wrong
but i need the song to be paused so whereever i used
mp.start();
function which will be start to play the music from the url i added the code as
if(!mp.isPlaying()){
mp.start();
buttonPlayPause.setBackgroundResource(R.drawable.pause);
}else {
mp.pause();
buttonPlayPause.setBackgroundResource(R.drawable.play);}
but when i click the play button it starts playing and again if i click the button again it starts playing two times simultaneously
please help me how should i start and pause the mp3 file which i have displayed it in url it is not going to else block itself should i use different function
the full code of the project is
public class MainActivity5 extends Activity implements OnClickListener,
OnPreparedListener, OnErrorListener, OnCompletionListener {
MediaPlayer mp;
ProgressDialog pd;
Button bt;
ImageButton iv;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main5);
iv = (ImageButton)findViewById(R.id.play);
iv.setOnClickListener(this);}
#Override
public void onPrepared(MediaPlayer mp)
{
Log.i("StreamAudioDemo", "prepare finished");
//pd.setMessage("Playing.....");
//mp.start();
/*if(mp.isPlaying()== true)
{
mp.start();
iv.setImageResource(R.drawable.pause);
}
else
{
mp.pause();
mp.release();
iv.setImageResource(R.drawable.play);
}*/
}
#Override
public void onClick(View v) {
try
{
pd = new ProgressDialog(this);
pd.setMessage("Buffering.....");
//pd.show();
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setOnPreparedListener(this);
mp.setOnErrorListener(this);
mp.setDataSource("http://192.168.1.138/Android/music/vande.mp3");
mp.prepareAsync();
mp.setOnCompletionListener(this);
}
catch(Exception e)
{
Log.e("StreamAudioDemo", e.getMessage());
}
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
pd.dismiss();
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
pd.dismiss();
Toast.makeText(getApplicationContext(), "Completed", Toast.LENGTH_LONG).show();
}}
thanks for your help in advance
i have commented some code above i have to re correct it
you can have a try at your onclickListener,when this player is playing,if you want to pause it ,you should to call MediaPlayer.pause() ,if you want to release it data,you can call MediaPlayer.release(),then ,you can play next music.
use this
public void onPrepared(MediaPlayer mp)
{
Log.i("StreamAudioDemo", "prepare finished");
//pd.setMessage("Playing.....");
// mp.start(); - this should be removed
if(mp.isPlaying()== true)
{
mp.pause();
iv.setImageResource(R.drawable.pause);
}
else
{
mp.start();
mp.release();
iv.setImageResource(R.drawable.play);
}
}

Android Activity: Listener for outside touch event

I have an Activity shown as a Dialog:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setTheme(android.R.style.Theme_Dialog);
setFinishOnTouchOutside(true);
}
When the user closes the Activity-Dialog by touching outside the Activity-Dialog window, the Activity finishes.
How can I set a Listener on this event?
This is important because I want to be able to call
setResult(intResultCode, intent);
right before finishing.
Calling setResult() in onPause() can be too late already.
why to struggle that much? just override finish() method in Avtivity...
#Override
public void finish() {
setResult(int resultCode, Intent data);
super.finish();
}
first put
dialog.setCanceledOnTouchOutside(true)
and after that use
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
// Tapped outside so we finish the activity
this.finish();
}
return super.dispatchTouchEvent(ev);
}
It's possible. You can override onTouchEvent()
#Override
public boolean onTouchEvent(MotionEvent event) {
if (MotionEvent.ACTION_OUTSIDE == event.getAction()) {
// Your logic
// return true if you don't want to pass event further
}
return super.onTouchEvent(event);
}
If you don't get ACTION_OUTSIDE event, possibly you need to add FLAG_NOT_TOUCH_MODAL and FLAG_WATCH_OUTSIDE_TOUCH window flags. Works for me without it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
...
}

Categories

Resources