Relaunch app from intent - android

I would like to put a notification with an intent.
My intent is basically action = DEFAULT and category = LAUNCHER in order to bring the activity that was launched into the front.
When the app is not shown, there is no problem, the intent works perfectly and launches the last activity seen but when there is already an activity launched, onNewIntent is not called (activity is in singleTop mode).
I'm wondering how to relaunch the app from an intent to the last activity seen and call onNewIntent when the activity is already launched.

the problem is that your activity is defined as
android:launchMode="singleTop"
when there is already an activity
launched, onNewIntent is not called
implement the onDestroy method::
#Override
public void onDestroy(){
super.onDestroy();
}

Related

Pending intent doesn't fire because of another intent in onPause

Consider the following scenario:
A notification is created with a pending intent (with some extras) to open some activity (let's say ActivityA) inside the app WHILE the app is running
The Activity in focus (ActivityFocus) at the time when the notification comes in overrides the onPause() method to open ANOTHER activity
#Override
public void onPause() {
startActivity(new Intent(this, ActivityB.class));
}
The user taps on the notification - now according to the onPause() documentation, the intent inside ActivityFocus will fire BEFORE the intent inside the PendingIntent
When activity B is launched in front of activity A, this callback will be invoked on A. B will not be created until A's onPause() returns, so be sure to not do anything lengthy here.
- From Android Documentation
Finally, the app launches ActivityB and completely ignores the PendingIntent
How can I fix this (without removing the onPause()) so that either:
The PendingIntent will fire AFTER onPause() execution is finished
The intent inside onPause() is somehow overridden by the intent inside the PendingIntent
Hopefully my question makes sense. Thanks in advance.

Application restart and activity hiding

I have application with two activities: SplashActivity and MainActivity. SplashActivity is the launch activity, it start for few seconds, close and launch MainActivity. MainActivity contains all application logic.
When user minimize application by Home button, then doesn't using application some time and maximize it again, data in my application is expired and I need to restart application. I make it with onStart in MainActivity:
#Override
public void onStart() {
super.onStart();
if (dataIsExpired()) {
finish();
Intent intent = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
It working well, but before SplashActivity launched I see MainActivity with old data for few moments. Is there way to restart without previous activity showing?
I don't need to clear it manually, I just need to restart whole app.
You can call finish() your activity in onPause() or onStop() of MainActivity so that it will be removed when minimising the app and will launch fresh.

In an activity, if the activity is paused and then invoked with an intent, getIntent() returns the old one

I have an activity that shows some information based on the intent that initiates the activity. The app icon starts this activity without any extra information and the activity displays correctly. The app widget also starts this activity, but with some extra information and is handled correctly. In this scenario, the app does not work as expected:
The user enters the activity using home screen shortcut.
The user uses the home key to send the app to the background.
The user uses the widget shortcut to enter the app
in this scenario, in onResume() the intent is the old one not the one from widget.
How can I solve this problem?
This is exactly why onNewIntent() exists: it is called:
when the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.
An activity will always be paused before receiving a new intent, so you can count on onResume() being called after this method.
Note that getIntent() still returns the original Intent. You can use setIntent(Intent) to update it to this new Intent.
Therefore add code such as:
#Override
protected void onNewIntent (Intent intent) {
setIntent(intent);
}
And/or move your code from onResume() into a method such as handleIntent() and call it from both your onCreate() and from onNewIntent().

Navigate Up to Parent Activity from Notification

My question is that I have two activities, Activity A and Activity B. Activity A is the main activity, Activity B is only accessible by touching a notification.
I need to be able to touch a notification, which will open Activity B. After the user is finished with Activity B, they can press the back button or finish Activity B. When Activity B closes, Activity A should be shown. Currently, I close Activity A (which closes the entire app) and receive a push notification. I select the push notification which opens Activity B. When I close Activity B, Activity A is not shown and the entire app closes. I want Activity A to be there after finishing Activity B.
I am using Parse SDK notifications. In my custom ParsePushBroadcastReceiver I have the following code
public class MyReceiver extends ParsePushBroadcastReceiver
{
#Override
public void onPushOpen(Context context, Intent intent)
{
Intent i = new Intent(context, NotificationActivity.class);
i.putExtras(intent.getExtras());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
I have it listed in the Android Manifest. My notification activity in manifest is
<activity
android:name=".NotificationActivity"
android:label="#string/app_name"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="portrait"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
In my notification activity I have the following code in onBackPressed
public class NotificationActivity extends ActionBarActivity
{...
#Override
public void onBackPressed()
{
if(NavUtils.getParentActivityName(this) != null)
{
Log.d(Constants.NAVIGATION_DEBUG, "Get Parent Activity NOT NULL");
NavUtils.navigateUpFromSameTask(this);
}
else
{
Log.d(Constants.NAVIGATION_DEBUG, "Get Parent Activity NULL");
super.onBackPressed();
}
}
...}
Surprisely, in the logs it states that it is NOT NULL, however it doesn't navigate back to Activity A if the app was closed prior to pressing the notification. Instead the app closes. I want Activity A to show whether the app was closed when the notification was pressed or whether the app is open. THANKS!
You can try the following method: put some boolean extra in your intent, and then start MainActivity. That extra will be the indicator of NotificationActivity start.
public class MyReceiver extends ParsePushBroadcastReceiver
{
#Override
public void onPushOpen(Context context, Intent intent)
{
Intent i = new Intent(context, MainActivity.class);
i.putExtras(intent.getExtras());
i.putExtra("IS_FROM_NOTIFICATION", true);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
Then in your MainActivity's onCreate() method, do something like this:
public class MainActivity extends ActionBarActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (getIntent().getBooleanExtra("IS_FROM_NOTIFICATION", false)) {
startActivity(MainActivity.this, NotificationActivity.class);
}
}
// other initialization code
...
...
}
Then you don't need to override onBackPressed in your NotificationActivity.
for the temporary solution, you must start your MainActivity onBackPress() of NotificationActivity..
Just so everyone else who is running into this problem will have a solution which works I will post my solution to this migraine problem. The way I solved this problem is by using Fragments.
Explanation: In the activity oncreate I check the Intent to see if the user is in the application due to selecting a notification. If so I can transition to the notification fragment, if not I can transition to the main fragment. After the user is finished with the notification fragment the user will either press the back key on their phone, or press the back arrow in the ActionBar, so the developer has to handle both of those situations.
To handle the back button on the phone simply override onbackpressed in your activity and check to see if the user is in the notification fragment, if so then smoothly transition to your main fragment, without keeping the notification fragment in the backstack.
To handle the back button in the actionbar, override onoptionsselected in your fragment and when the user presses the back button (android.R.id.home) you simply smoothly transition to your mainfragment.
If you are also handling overriding your activity onnewintent, simply pass in a boolean to your fragment letting your notification fragment know whether it has been opened from onnewintent or oncreate from your activity.
If your notification fragment is opened from onnewintent, you wouldn't want to transition to your mainfragment, since your mainfragment would already be open and in the backstack. So you would simply POP the fragments backstack, or let the android system automatically handle proper navigation.
It's a lot of work, but it is a solution, and in theory this solution should work across all Android API's from GINGERBREAD - LOLLIPOP, as long as the user is using Fragments, and the user is using a custom animation to transition between fragments.
The key is using a custom fragment transition from the notification fragment back to the main fragment ( or in the case of onnewintent, whatever fragment came before it) to give the impression that the user is going BACKWARDS from notification fragment to main fragment. If anyone else comes with a better solution... I am all ears.
Use TaskStackBuilder in Android its the same you need.

onNewIntent is called when app is launched from background

I have a singleTop activity, this activity is launched via Intent:
Intent intent = new Intent(GCMIntentService.this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
onNewIntent is called.
My problem is that then I hit home button, and then launch application again (from background) onNewIntent is called again with the same intent, and I can not find a way to discard this Intent.
I tried to putExtra flag to this intent, but it is not persisted between application state changes.
Is it possible to stop calling onNewIntent() when application comes to foreground?
In your manifest add the line below to your MainActivity
android:finishOnTaskLaunch="true"

Categories

Resources