In my app my first activity to launch is a login activity (A). When the login is successful another activity is launched (B), in doing so activity A is killed using finish(). This is to prevent the user being taken back to the login screen if they hit the back button, which works fine. Now when the app is closed from activity B using the home button and restored from the multitasking view the user comes back to activity B, which is great. However, when the user taps the back button in activity B the app closes and when the app is restored from the multitasking view, activity A is launched again when I actually want the behaviour clicking the home button gives and presenting the user with activity B.
Is there any way to do this?
You should simply add a check to your login activity, if the user is already signed in finish it and launch your B activity.
I'm really silly, just found my answer in one of the 'related' questions but it didn't come up when I created my question, oh well.
Here's what I did:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
Log.d("CDA", "onKeyDown Called");
onBackPressed();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onBackPressed() {
Log.d("CDA", "onBackPressed Called");
Intent setIntent = new Intent(Intent.ACTION_MAIN);
setIntent.addCategory(Intent.CATEGORY_HOME);
setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(setIntent);
}
This essentially emulates what the home button would do in activity B.
Related
I am working on an app service that will display on top of another app that is currently on the foreground and if the user pressed on the back button it will destroy the service and exit the app too, but not killing it.
I had read many articles on stack overflow that tells me to use finish() or finishAffinity() but it only works if it is my own app activity.
Can I exit the app with its package name?
FrameLayout interceptorLayout = new FrameLayout(this) {
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
// Only fire on the ACTION_DOWN event, or you'll get two events (one for _DOWN, one for _UP)
if (event.getAction() == KeyEvent.ACTION_DOWN) {
// Check if the HOME button is pressed
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
Log.v(TAG, "BACK Button Pressed");
onDestroy();
// As we've taken action, we'll return true to prevent other apps from consuming the event as well
return true;
}
}
// Otherwise don't intercept the event
return super.dispatchKeyEvent(event);
}
};
I am not recommending to close other app.
You can exit with other app's package name
Declare a permission for that in your AndroidManifest.xml file. here it is :
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
and now use ActivityManager class to kill other apps and it will work.
ActivityManager am = (ActivityManager)getSystemService(Activity.ACTIVITY_SERVICE);
am.killBackgroundProcesses(packageName);
How can I prevent the ActionBar back button (we gonna say ABBB) of my SecondActivity to recreate the MainActivitywhen clicked ?
I have a ListView in the MainActivity and it can be edited using the SecondActivity. The problem is that when the user presses the ABBB, the ListView is reset to default...
However, when the user clicks my OK button or presses physical back button, there is not any problem because I'm using finish();
#Override
public void onBackPressed() {
finish();
}
If I use this code... :
switch (item.getItemId()) {
case (android.R.id.home):
finish();
}
...there is the same problem because, I guess, this method is called after "Android's code".
How can I totally override Android ABBB's clicked code to set it to just call finish(); ?
The ideal scenario is, when are you in the SecondActivity (I take it that, this means that you are in Edit mode), and you press the device back button or ABBB, you show a subtle alert to the user saying "do they really want to dismiss the editing", or go ahead and apply the edit done as in the Contacts application.
So that being said, if all you require is to finish() the activity on press of ABBB, the code that you shown above should work fine (though you need to put return true; after finish()). It works for me. Try the below one in your activity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed(); // or finish();
return true;
}
return super.onOptionsItemSelected(item);
}
I put onBackPressed(); because your ABBB with now imitate your device back button.
Or, you can set your parent activity's launch mode as -
android:launchMode="singleTop"
that will do all without changing anything.
Reference
I want to play an audio file in the background of my app. Easy enough. I want the music to persist and NOT stop or pause while switching between activities in my app. Also fairly easy and accomplished simply by doing this in the onCreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mp = MediaPlayer.create(MainActivity.this, R.raw.lostmexicancity);
mp.setLooping(true);
mp.start();
}
The problem? Getting the music to stop when I press the HOME button.
Killing the sound when the user presses the back button seems easy. Here's what I have for that and works great:
public void onPause() {
if(this.isFinishing()){ //BACK was pressed from this activity
mp.stop();
}
super.onPause(); }
Not complicated, but this does not catch presses of the HOME button. If the Home button is pressed, the music keeps playing even while the user no longer sees my app.
I have seen answers that involve setting permission in the manifest to Get Tasks which I shouldn't have to do and appears dangerous to users. Besides that, the solution didn't even work. I've seen solutions that involve using a service, but none of those work either because the home button STILL plays the music just like before because there doesn't seem to be a way to catch it and it doesn't 'finish' the app (not to mention that every time someone suggest using a service for this task multiple people come in and state that this is not a proper use for services)
It seems the only way to kill the music when the Home button is pressed is to use a non-conditional stop() within onPause, but that's no good because that's called when I swap activities with intents, causing the music to end between activities which is no good.
I have trouble imagining that such a common function like background music is this hard, but I've seen post after post with the same issue as me and no proper answers other than ones that would kill the music between activities within the app.
How do all the other apps on the Google play store accomplish this and yet there appears to be no clear answer online? I could just stop and start the music with each onPause(), but that would cause unprofessional gaps in audio not to mention it would start the background audio from the beginning over and over again which is unacceptable.
I'm a bit new to Android Programming (few months) and today, I faced the same problem you did (maybe you still do?)
I made it work as the following :
Lets say I have MainActivity, and in MainActivity I have Btn2 which leads to SecondActivity, and Btn3 which leads to ThirdActivity.
I declared at the beginning of MainActivity :
public static boolean shouldPlay = false;
I then implemented my onStop() method :
public void onStop() {
super.onStop();
if (!shouldPlay) { // it won't pause music if shouldPlay is true
player.pause();
player = null;
}
}
If the boolean shouldPlay is set to true, then my onStop() won't be called entirely and my music won't turn off. I then have to decide when I set it to true. When I switch from MainActivity to SecondActivity, I do it through an Intent and that's when I'll set shouldPlay to true :
Button Btn2 = (Button) findViewById(R.id.Btn2);
Btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
shouldPlay = true;
startActivity(intent);
}
});
And the same is done for Btn3.
Now, the last thing we want to be looking for is that if I was to go back to MainActivity after visiting SecondActivity or ThirdActivity, shouldPlay would then have been set to true. The first thing I tried was to set it to false as soon as Second and ThirdActivity are called (in their onCreate()) but it want to work, maybe because the onStop() from Main and onCreate() from others are called simultaneously (frankly I don't really get life cycle for now).
What worked is simply to set shouldPlay to false every time we launch onCreate() of Main :
shouldPlay = false;
This works properly for me.
Let me know if it does for you,
Cheers,
bRo.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_HOME){
Log.d("Jorgesys", "Home button pressed!!!");
}
return super.onKeyDown(keyCode, event);
}
but hey! This no longer works as of 4.0 + , Read this: Capture Home Key Event
Try with Back button:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
Log.d("Jorgesys", "Back button pressed!!!");
}
return super.onKeyDown(keyCode, event);
}
To stop the media player, you are using the method:
isFinishing(): if the activity is finishing, returns true; else
returns false, but you are only pausing the activity not finishing the
activity.
public void onPause() {
if(this.isFinishing()){ //INCORRECT, Here you are pausing you activity not finishing.
mp.stop();
}
super.onPause();
}
so change to:
public void onPause() {
if(mp.isPlaying())
{
mp.stop();
}
super.onPause();
}
When your activity is on pause, evaluates if your MediaPlayer is playing, if this is true then stops the audio.
The Scenario :
I have four activities : A, B, C and HomeActivity. A is my launcher activity. Am using actionbarSherlock, so A,B and C have menu option in the bar.
The flow is :
A-> B-> C --**On submit in C**--> HomeActivity
Now when i press Back button on Home Activity, it goes back to activity B as after clicking Submit in C , am using
Intent intent = new Intent(this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP ); //Shouldn't this clear A,B and C ??
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP );
startActivity(intent);
finish();
But i would like to remain on HomeActivity only as data is submitted and then it was started.
Also if menu button is pressed on A,B,C, then HomeActivity is started and in that case, i would like to have default behaviour of Back button(i.e go back to activity in which menu was pressed)
Any insights on how to do this as FLAG_ACTIVITY_CLEAR_TOP not serving the purpose!
(P.S. : HomeActivity is not a launcher activity)
I think you finish your Home Acitivity while you go to the Home Activity -> Activity A. When you are using clear top flag then your Home Activity should be alive in your stack. Please make sure that you are not finish your Home activity.
And also put this code onKeyDown() method in your Home Activity.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
Log.e("onkeyDown>>>>", "Called>>>>>");
finish();
}
return super.onKeyDown(keyCode, event);
}
check more details check this link:
Other Way
EDIT:
try to put above code into Activity A.
remove finish() method from your code like below:
Intent intent = new Intent(this, HomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP ); //Shouldn't this clear A,B and C ??
//intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP );
startActivity(intent);
And Most Important thing Don't Finish your Activity A launcher
Activity for Clear top method it should be in stack of Activity remain
present in your device.
Hope it will solve your problem.
My app has three activities, A, B and C. I am moving from A to B through an OK button, and I want to move back from B to A by using the default back button of Android devices. When I press the button, though, the entire app gets closed. How can I get around this problem?
I suspect you call finish() in your OK button onclick listener. Don't do that. finish() removes your activity from activity stack.
Read more here.
why start your activity for result ? when you press the backbutton, the result is set to RESULT_CANCELED form the B activity, so it crashes if you don't handle the resultcode...
you can handle the backpress like this
private static final int NONE = -1;
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
setResult(NONE, intent);
finish();
return super.onKeyDown(keyCode, event);
}
When you are Ok button r u starting an intent...like
Intent int=new intent(context,B.class);
startActivity(int);
then if you are not handling backbutton.
If use default back button...it will goes back to A.
Hope it helps...
In my onClick method (in Main Activity) I use the code:
Intent intent = new Intent(context, SecondActivity.class);
context.startActivityForResult(intent, SecondActivity.SECONDACTIVITY_REQUEST);
In the manifest I've got:
<activity android:name=".SecondActivity" android:screenOrientation="landscape" android:launchMode="standard"></activity>
This works for me without any other settings that I can see. What events are you responding to?
Note that you can also go back an activity, in code like this:
super.setResult(Activity.RESULT_OK);
super.finish();
Edit...
Make sure you're not swallowing the event in the Main Activitys onKeyDown event.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//your code here
//if (keyCode ==
//...
//else
return super.onKeyDown(keyCode, event);
}