I'm developping a SIP application. I have a little problem: when "reducing" the application with home button and i make a call to the phone, i have the coded ringing incoming call but the application doesn't shows. How to pops up all the application UI when having an incoming call ?
Thank you for your help.
EDIT:
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Dialog dialog = new Dialog(context,intent);
dialog.répondre();
}
}
So, you have an Activity that is stopped and you want to pop it up when call arrives. Approach I would suggest:
originally start that Activity with flag FLAG_ACTIVITY_SINGLE_TOP
override function onNewIntent() in that Activity and process incoming Intent depending on action code from Intent (you define them to distinguish reasons for popping up)
when you want to move that Activity to foreground again, call startActivity() with some action code (you can to that from Service as well). If Activity is not started, it will be. If it is started, it will not be re-started but resumed and you will receive your Intent in onNewIntent() and your Activity will be moved to foreground.
UPDATE:
onNewIntent() handling example:
\android-sdk-windows\samples\android-8\ApiDemos\src\com\example\android\apis\app\SearchQueryResults.java
Related
I am working at an application that uses a notification(with a foreground service).
The use case is the following:
If the activity of the application is killed, when clicking on the notification's icon the activity is created and brought to foreground.
If the activity of the application is not visible, when clicking on the notification's icon the activity is simply brought to foreground.
For re-creating/bringing the activity on foreground I am using the following broadcast receiver in my foreground service:
private static class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent intent = new Intent(context,MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setAction("android.intent.action.MAIN")
.addCategory("android.intent.category.LAUNCHER");
context.startActivity(sIntent);
}
}
The desired action is pretty much similar to the default music player on an android phone, i.e: when clicking on the icon it's activity is simply brought to foreground(or re-created and brought to foreground in case it was previously killed)
This a screenshot from a Samsung S4
first notification is from usb - we do not care about it
second notification is my application - when clicking on the icon the activity gets created but not brought to foreground(the user has to swipe back the menu to see the activity)
How can I bring it to front without the additional swipe-back-menu? (in the similar way how music player app does?
PS: Minimum Android SDK version is 16
As far as i know, theres no possibility to bring your activity in front of the notification menu. But you're able to close the menu automatically with:
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(i);
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().
There are a lot of topics on this post. But i couldn't find a solution to my problem.
Let me describe my activity stack first.
SplashScreen->A->Login->Home.
What i would like to achieve is , when i click on back button after logging in to Home, i should come out of the application and go to Home if i use my application again. For this i am assuming i should clear the activity stack before Home, after i login. I would also like to preserve the activity stack if the user hasn't logged in yet.
I want this to work on or after 2.1
What i have tried already.
using finish() in Login Activity , before calling startActivity on Home. This will redirect me to A , if i use back button on Home.
All variations of FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TOP . Nothing worked, when i use back button, i am redirected to login screen.
Any suggestions or simple solution to achieve this?
using finish() in Login Activity , before calling startActivity on Home. This will redirect me to A , if i use back button on Home.
ok so use finish on all the activities that you want them to be popped before calling startActivity
go to Home if i use my application again
Simply save your login parameters in SharedPreference and from A startActivity Home directly if login successful.
You can also try to make use of BroadcastReceiver aswell if you want to try that route.
In your "SplashScreen" and "A" activities, in the onCreate method you can create and register and IntentFilter and a BroadcastReceiver like so:
Assuming you have a global variable called broadcastReceiver
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("ACTION_LOGIN");
this.broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
registerReceiver(broadcastReceiver, intentFilter);
Also don't forget to unregister your receiver in the onDestroy method (this is to prevent memory leaks in the program):
#Override
protected void onDestroy() {
unregisterReceiver(this.broadcastReceiver);
super.onDestroy();
}
Now in your "Login" activity, once the user has successfully logged in, you can broadcast a message to all the registered receivers, which will finish those activites in the back stack:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("ACTION_LOGIN");
sendBroadcast(broadcastIntent);
Your SplashScreen and A activities will now be finished.
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
}
}
We have a live video streaming app with a lot going on. A user presses the home button. I want the app to be removed from memory. When the app is selected again we have a brand new load. There are a lot of processes going on and we don't want to have to manually manage all the connections, streams, etc. This is how our iPhone version of the app works.
I've read this: Is quitting an application frowned upon?
I don't really care about Androids design patterns here either way. However if someone has an elegant, simple way that all my activities will be removed from the stack when the home button is pressed, and then when the app is reloaded it starts with a fresh main activity, that would be great. Also, I can't seem to ever debug when the home key is pressed in onKeyDown. Its simply not registering. (keyCode == KeyEvent.KEYCODE_HOME) is my check. It picks up back buttons, etc.
Any thoughts?
You can call system.exit(0); but I would still suggest to follow the Android guidelines, and clean everything (as should be) on onPause() or similar method.
Could you just override the onPause method and use the finish() function?
int p = android.os.Process.myPid();
android.os.Process.killProcess(p);
you can do than on button click. Define any static method like exit() and define
android.os.Process.killProcess(android.os.Process.myPid()); in exit method
in the main or first activity.
Then call this method on button click.
If you want to clear all of your activities from the stack, you can broadcast an intent from the activity which initiates the quit like this:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("CLEAR_STACK");
sendBroadcast(broadcastIntent);
And in every one of your activities that you want to be cleared off the stack you can create a BroadcastReceiver with an inner class:
class ActivitiesBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
}
And register your BroadcastReceiver in the onCreate() method:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("CLEAR_STACK");
BroadcastReceiver r;
r = new ActivitiesBroadcastReceiver();
registerReceiver(r, intentFilter);