create pop up instead of notification from BroadcastReceiver - android

i need to display pop up message in the center of screen , after reading in few forums i found out that it can be achieved by starting a new transparent activity .
this is my code :
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent();
i.setClassName(context,
"com.ui.activity.NotificationActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
this work's but :
if application is in background than the application will come to the foreground with the pop up on it (if the application is not on background this work's great ).

If you don't want your app to be brought to the foreground when this popup is shown, you need to ensure that NotificationActivity has a different task affinity than the rest of your application.
In the manifest, add this to the <activity> definition for NotificationActivity:
android:taskAffinity=""
Without this, the default task affinity for all Activities is the same, so that when Android looks for a task to launch NotificationActivity into, and your app is already running, Android launches NotificationActivity into that task and brings it to the foreground.
If you change the task affinity, Android won't look for an existing task to launch NotificationActivity into, and will just create a new task.

Related

Launching activity from notification , app is going through latest activity onResume

I have problem with notifications. It all works well launching correct activity from notification.
Problem is that when new activity is launched from notification and app has been in background. Then first the latest activity is loaded (on Resume()) and after that intended activity is loaded. In onResume I'm checking the session expiration. And when its expired user will be taken to login. And in the latest activity i don't have notification extras.
Is there possibility to skip latest activity onResume when opening notification and going straight to the intended activity.
PendingIntent createContentIntent(Context appContext, NotificationData data) {
Intent notificationIntent = createNotificationIntent(appContext, data);
if (notificationIntent == null) {
notificationIntent = new Intent();
}
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Bundle extras = createBundle();
extras.putSerializable(EXTRA_NOTIFICATION_DATA, data);
notificationIntent.putExtras(extras);
return createPendingIntentActivity(appContext, notificationIntent);
}
Modify your new activity manifest to include custom task affinity, and consider changing launchMode to singleTop to prevent creating duplicates of the activity:
<activity
android:name=".your_activity"
android:launchMode="singleTop"
android:taskAffinity=":task_2"/>
Also include Intent.FLAG_ACTIVITY_NEW_TASK in your launch intent.
The problem you are having is that Android is bringing your existing task to the foreground and then (obviously) resuming the top Activity in the task BEFORE it creates the Activity from the Notification. This sounds like an Android bug.
Anyway, to get around this, you could try having the Notification launch an Activity into a different task. To do this, set taskAffinity="" on the Activity that the Notification starts. The Activity started by the Notification would then have to start another Activity that will run in the task with the rest of your app. Hopefully this would all happen after the phone is unlocked so that you don't see this onResume() problem.
If you need more help, please post the code from createNotificationIntent() and createPendingIntentActivity() and the relevant parts of your manifest.

Resume background activity on notification

I've read some answers here, I think I have what I need in order to achieve my result, but I need some help.
My app launches an notification on specific conditions, and I need my app to behave as follow:
if there is an instance of my main activity running in background I need to make it to the foreground (I found this on the site: intent.setFlags(FLAG_ACTIVITY_REORDER_TO_FRONT);, so I think this point is solved;
if there isn't any activity of the app running in background I need to start the app from the beginning (and this can be achieved starting the launcher activity of the app.);
My question is: how can I make the app search for any istance of itself running in background? Because the activity that I need to reorder to front with the Intent flag is different from the launcher activity.
The notification is handled by a service that check periodically some infos from the internet.
Thanks for the help.
What you need is just a simple Activity that decides what to do. Here is an example:
public class NotificationActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Check if the app was already running
if (isTaskRoot()) {
// App wasn't running, so start the app from the beginning
Intent startIntent = new Intent(this, MyStartingActivity.class);
startActivity(startIntent);
} else {
// App was already running, bring MainActivity to the top
Intent reorderIntent = new Intent(this, MainActivity.class);
reorderIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(reorderIntent);
}
// We are done now so just finish
finish();
}
}
Set up your notification to start this activity. Make sure that in the manifest the task affinity of this activity is the same as the task affinity of the other activities in your application (by default it is, if you haven't explicitly set android:taskAffinity).

Display Alertbox from service

Is there any way to use alertbox in service rather then making another activity for it and then starting that activity from service?
A Service cannot show a Dialog , only you can show short lived Toast from there.
But If your Requirement is of showing dialog I will not disappoint you .You have got following options:
If you have a MainActivity use a LocalBroadcastReceiver to send a broadcast to your activity and let your MainActivity show a Dialog. (This will be possible only when your activity is visible)
The other option is Define a Dialog theme activity (take a look here) in your manifest and start that activity from service.
Another option could be , Define a Activitiy in Manifest whose sole purpose would be display a Dialog and start that activity from service
Edit
I have a suggestion , If you wish to present information to your users , you should use Notification . The main reason that you cannot show a dialog from service is that Google wants information to be decently presented to its users , instead of surprising them when suppose they are in middle of a call , or typing message etc.
if the user is interested, then he will touch the notification and you start your own activity, possibly resuming your activity, creating a new one, and then using a dialog requesting action to be performed, or whatever you want to do.
Alternative Solution
However If you persist I have another solution if you like hacking, (but I don't like hacks in good application).
Create a custom Broadcast Receiver
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// AlertDialogue will be here
}
}
Register it in the manifest file
<receiver android:name="MyBroadcastReceiver">
<intent-filter>
<action android:name="com.sample.A_CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
Trigger the BroadcastReceiver from service
Intent intent = new Intent("MyCustomIntent");
EditText et = (EditText)findViewById(R.id.extraIntent);
// add data to the Intent
intent.putExtra("message", (CharSequence)et.getText().toString());
intent.setAction("com.sample.A_CUSTOM_INTENT");
sendBroadcast(intent);

Notification to restore a task rather than a specific activity?

I have a foreground service that keeps a connection open with the server as long as the user is logged into the application. This is so that the connection is kept alive and can receive messages directly from the server even when the application has been sent into the background by the user pressing Home.
The application has a number of Activities, any of which could be the active one when it is sent into the background.
I would like to allow the user to click on the notification to restore the current Activity. I understand how to restore a particular activity, but wondered if there is a way to restore the last Activity that the user was on? Of course I could keep track of the the last one, and then call that from the Notification callback, but thought there might be a way at a task level?
Thanks for any advice you can offer.
What you need is just a simple Activity that does nothing. Here is an example:
public class NotificationActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Now finish, which will drop the user in to the activity that was at the top
// of the task stack
finish();
}
}
Set up your notification to start this activity. Make sure that in the manifest the task affinity of this activity is the same as the task affinity of the other activities in your application (by default it is, if you haven't explicitly set android:taskAffinity).
When the user selects this notification, if your application is running, then the NotificationActivity will be started on top of the topmost activity in your application's task and that task will be brought to the foreground. When the NotificationActivity finishes, it will simply return the user to the topmost activity in your application (ie: wherever the user left it when it went into the background).
This won't work if your application isn't already running. However, you have 2 options to deal with that:
Make sure the notification isn't present in the notification bar when your application is not running.
In the onCreate() method of the NotificationActivity, check if your application is running, and if it isn't running call startActivity() and launch your application. If you do this, be sure to set the flag Intent.FLAG_ACTIVITY_NEW_TASK when starting the application so that the root activity of the task is not NotificationActivity.
Works very well, thanks David! The following class checks if the application is already running and if not, starts it before finishing (as suggested by David in option 2).
public class NotificationActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// If this activity is the root activity of the task, the app is not running
if (isTaskRoot())
{
// Start the app before finishing
Intent startAppIntent = new Intent(getApplicationContext(), MainActivity.class);
startAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startAppIntent);
}
finish();
}
}
There is a simpler solution that does not require the extra activity. See this post for details. Basically, the notification starts the (possibly existing) task the same way it is started when you click the launcher icon while the app ist in the background.
My solution, which emulates the behaviour of the launcher (bringing up the task to the foreground):
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClassName(MyApplication.class.getPackage().getName(), MainActivity.class.getName());
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
This works, no doubts about it but the problem is when you set your intent as ACTION_MAIN. Then you will not be able to set any bundle to the intent. I mean, your primitive data will not be received from the target activity because ACTION_MAIN can not contain any extra data.
Instead of this, you can just set your activities as singleTask and call your intent normally without setting ACTION_MAIN and receive the intent from onNewIntent() method of your target activity.
But be aware if you call, super.onNewIntent(intent); then a second instance of the activity will be created. Just don't call super method.
I combined David Wasser's and Raginmari's solution by doing that approach to the root activity of your app then it will work for both cases when your app was already started or haven't been started.
public class YourRootActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (!isTaskRoot()) // checks if this root activity is at root, if not, we presented it from notification and we are resuming the app from previous open state
{
val extras = intent.extras // do stuffs with extras.
finish();
return;
}
// OtherWise start the app as usual
}
}

Android AppWidget Configuration - Start in new task

I've searched and searched and searched for this!
So I've got an app widget and it has a configuration activity that I can open when pressing a button on the app. The scenario is:
Had the app opened.
Closed the app with the home button.
Selected to add my widget
I have configured the widget.
Placed on my home screen
Then open the configuration activity again with the button on the widget.
Cancel the new config by pressing back will put me back into the app.
When pressing back I want to just return home.
Basically what I'm asking is. How do I start the configuration activity in it's own task/stack?
I've looked into intent filters but I'm just not quite sure, or maybe it's something to do with the package it's in, or maybe it's just not possible!
I suppose it may have something to do with the intent I use to launch the config activity
Intent configIntent = new Intent(this, Configuration.class);
configIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
remoteView.setOnClickPendingIntent(R.id.config, PendingIntent.getActivity(this, 0, configIntent, PendingIntent.FLAG_UPDATE_CURRENT));
Perhaps because I launch it with 'this' as the context, it will always start in my applications stack...
but the pending intent api is:
PendingIntent API 1
"Note that the activity will be started outside of the context of an existing activity"
So yeah I'll stop talking now as I just end up going in circles!
EDIT
So tried android:launchMode="singleInstance" in the manifest like was stated. This worked however it stops the 'startActivityForResult' behaviour working correctly. (which is the whole reason for a config activity) Get the error:
WARN/ActivityManager(59): Activity is launching as a new task, so cancelling activity result.
So still haven't found a solution.
Ok sorted it :-) needed:
android:taskAffinity=""
in the manifest, setting the task affinity to an empty string allows for the activity to start in it's own stack, as it is not 'affiliated' with the rest of the application.
UPDATE
I have changed the task affinity to:
android:taskAffinity="com.my.package.alternative.task"
as each time I launched the activity it was showing up multiple times in the 'history'. So it now starts in it's own stack but is shared with other instances of the same activity.
Also need to add the Flag Intent.FLAG_ACTIVITY_NO_HISTORY to your intent :-) this stops your getting your application multiple time's in the history when you 'press and hold' the home button.
UPDATE
I've noticed FLAG_ACTIVITY_NO_HISTORY wasn't doing what I wanted, I've removed it and added:
android:excludeFromRecents="true"
into the activity tag in the manifest as well. The activity now behaves like I want :-)
Got this answer from the following link trail:
Tasks & Back Stack |
Managing Tasks |
Affiliation Tag
Try to put android:launchMode="singleInstance" for an activity of the app in AndroidManifest.xml

Categories

Resources