Android sdk activity flow - android

Can someone help me replicate the following scenario:
I'm having a activity A with some specific tasks from which the app goes to activity B. When the user goes to B and presses back the app should close (maybe meaning that activity A performed finish()). But in some cases the app (not on the user action) goes back to Activity A, with the state preserved to when it went to B. The thing is that the app can never know if it should preserve activity A to be re-displayed later or not.
Hope I made it clear. Many thanks

You can start the Activity B with startActivityForResult() and in function of the result, when we come back to the activity A, Activity A finish() himself or not.

You can populate your Activity A every time in its onResume(). For persistence you can use SharedPreferences.
You can setup a BroadcastReceiver in Activity A which will call finish() for Activity A upon receiving a message. In the Activity B just before you close you then send that message to Activity A's broadcast receiver.

Related

How to prevent to relaunch specific Activity after pressed back button?

When I pressed the back button on B Activity to go back A Activity, B Activity is relaunched 'cause B Activity was launched from intent.extra at onCreate of A Activity.
The intent.extra is recreated with previous data, so it happens recursively.
My intention is to load B Activity from FCM and then back to the A Activity when the user pressed the back button.
I already tried to remove data of intent after startActivity but it didn't work.
But If I check savedInstanceState is null or not, it works but I'm not sure it's the right way or not.
Plus, the A Activity's launchMode is singleTop but it's not the point of this problem, I think.
Whole scenarios are the following.
Get the data from FCM in the background and then the data is served from the System tray.
Check if there is data or not at onCreate of A Activity and then if there is launch B Activity.
Pressed back button on B Activity but B Activity relaunched at onCreate of A Activity.
How to prevent the action of 3 in the scenarios?

Fragment comes alive after stop

I'm working on an Android application which pretty much works like this:
There are two activities.
Activity A leads to activity B.
While pressing back from activity B, the user goes back to Activity A.
I have listeners listening to internet connectivity on a fragment of Activity B.
If I press back button from activity B after staying in B for a considerable amount of time, the app crashes immediately after going to the activity A.
On seeing the error logs, I verified that the activity B is paused, Activity A is resumed and that the Fragment in activity B is stopped. But I could also see that the internet listeners in fragment in activity B are still alive even after coming back to activity A, and so it receives the ping response and the fragment seems to be coming alive.
here is the exception message I got:
main Thread[main,5, main] Disallowed call from unknown notification listener: "android.service.notification.INotificationListener$Stub$Proxy#ecbe517java.lang.SecurityException: Disallowed call from unknown notification listener: android.service.notification.INotificationListener$Stub$Proxy#ecbe517"
In the onStop() method of my fragment, i have done something like this:
myContext.unregisterReceiver(myReceiver) .
myWifiScanner.pause()
myHandler.quitSafely()
I figured out that this is the problem. How can I fix it?
I tried removing all callbacks from all handlers involved in the fragment.
Take a look at your activity life cycle.
Make sure you are pausing or destroying your activities when jumping from one to the next.
https://developer.android.com/guide/components/activities/activity-lifecycle.html

Android how to save and restore state of Activity when calling finish()?

In Android, from Activity A, if I start new Activity B, Android will automatically save all the state of Activity A. So when I click back or call finish() from Activity B, Activity A will be restored to the state when I start Activity B (for example: position of a ScrollView in Activity A, or the value of ProgressBar). In Activity A I have a ProgressBar showing progress of some task, then if I come back from Activity B, the ProgressBar is restored and keep running.
Now what I want is, from Activity A, I will call finish(). How can I save all the state of Activity A just like Android did (include the ProgressBar as I describe above), so when I start Activity A again, I can restore everything like before calling finish(), and my ProgressBar keep running?
Can I push Activity A to something like stack in Android and then pop it out? Anyone know how to achieve this?
Do not call finish on clicking the back button.
Instead call the method "moveTaskToBack(false)". This will 'minimize' your application.
Next time you open the application the application opens with the previous state.
The whole point of finish() is to say that your Activity is "done and should be closed". If you aren't done, just don't call finish().
When you go from Activity A to Activity B, Android does not kill Activity A. Activity A still lives in the background. It can however be killed at any moment if Android needs the memory.
To save the state of an activity you have to do it manually.
Here's a similar question with a good answer: Saving Android Activity state using Save Instance State
If you want to finish your activity and then start it again just to load some new configurations, You can call activity's recreate() method instead of calling finish(). Calling recreate() will call onSaveInstanceState() and onRestoreInstanceState(), helping you to restore your previous configurations..
You can look at this answer for more detail : How do I restart an Android Activity

Resuming back to an activity without restarting the activity

am having a two activities that interact.
activity A picks input values and sends to activity B for the user to confirm input before submitting. activity B should allow the user to go back to activity A to edit input values if required or submit the values if they are ok. If user submits values, activity A should be finished and if he edits, then he goes back to activity A.
I have used startActivityForResult() and setResult() methods to kill the activity A when the user submits the values that has worked perfectly, but when i click the edit button to return to activity A, it call the activity A using a new Intent, and subsequently, it starts the activity A, yet previously started activity A is still running . what i want is to resume the activity A where it was left with the existing values before activity B started on click of the back button. How do i achieve this?? Your assistance is highly appreciated
Call finish() in Activity B when you need to edit. There is no need to fire an intent that creates new instance of Activity A. It will resume Activity A.

Is there any way to distinguish between an Android Activity onResume from the home screen?

Is there any way to tell whether an Activity is being resumed (i.e. onResume is called) from the home screen/launcher?
For example, if I have an Application with two activities, A and B.
Scenario 1:
Some user action on Activity A will invoke Activity B, bringing it into the foreground - moving Activity A into the background. As Activity A moves into the background, it goes through onPause() and onStop(). The user (now on Activity B) either finishes the Activity or hits the "back" button, bringing Activity A back to the foreground, causing an onRestart(), onStart(), onResume() sequence.
Scenario 2:
If the user hits the "home" button while Activity A is in the foreground and then re-invokes the Application from the launcher, it goes through the same lifecycle as in Scenario 1. I.e. User hits the "home" button. Activity goes through onPause() and onStop(). User launches the application again, causing Activity A go come back into the foreground, again going through the same onRestart(), onStart(), onResume() sequence as in Scenario 1.
As far as I can tell, the Activity has no way of knowing how it was resumed, it just knows it is being brought back into view. In fact, I have a feeling that there isn't really as much of a concept of an "Application" in Android - in the sense of something that has a single entry and exit point.
in Scenario 2, your activity will get an onNewIntent call, with the launcher intent passed to it.
You could capture the back button press on Activity B and pass an extra value to Activity A. If there is an extra value then the activity was resumed from pressing back on Activity B, if there is no extra value then the Activity was resumed from being hidden.
Could Acitivity A use startActivityForResult() to start Activity B and use onActivityResult() to detect that Activity B finished?
So the straightforward answer to the initial question is probably: no. Launching an activity from the home screen through an icon, or resuming it from the recents screen can not be observed from the intent it is (re)started/resumed with.
Depending on what you are trying to achieve there are some approaches though:
what #superfell suggested:
Check for whether the onNewIntent-method is called on your activity to decide if it was restarted from the launcher. As a precondition you need to set your activity to singleTask/singleTop launchMode in your Manifest:
android:launchMode="singleTask"
depending on what you're trying to achieve, this might be enough! But additionally you might have to deal with what happens when the user presses the back button. Default behavior is to finish & destroy your activity. Thus a brand new copy of it would be launched when it gets selected from the recents screen. Though onNewIntent would not be called, everything would be rebuilt from scratch. If you need to prevent this you can use:
override fun onBackPressed() {
moveTaskToBack(true)
}
finally when you navigate "back" from an activity you launched yourself onNewIntent will also not be called. If you further need to distinguish why your activity is resumed, you might want to start the 2nd activity with startActivityForResult so the onActivityResult is called when you get resumed.
Launcher activity & Intent extra
A completely different approach would be to have a "launcher" activity in your manifest that directly calls your "main" activity and finishes itself. When calling your main activity you can put an intent extra that allows your main activity to distinguish if it was just launched for the first time, or not. As the extra would be present on further onResumes, make sure to overwrite it the first time you "consume" it:
override fun onResume() {
super.onResume()
val firstLaunch = intent.getBooleanExtra(FIRST_LAUNCH, false)
intent.putExtra(FIRST_LAUNCH, false)
if (firstLaunch) {
// do something
}
}
and when starting from your "launcher" activity:
intent.putExtra(FIRST_LAUNCH, true)
startActivity(intent)

Categories

Resources