I have a situation, that when my app goes in background (not killed completely!) and last alive activity was BActivity. In this state. I receive a push notification.
When notification is clicked it should open the last activity which was opened earlier i.e., (BActivity).
Question How to open that last specific paused activity?
Is any answer like set flag or manifest configs?
If I understood correctly, you want to bring your app back to foreground after you receive a push notification? In that case, use the following code:
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(intent);
where MainActivity is the launcher Activity that you have specified in AndroidManifest.xml.
This should bring your app to foreground in its previous state, if there ever was one, and otherwise launch MainActivity.
For an explanation see here.
You can try by adding the activity life cycle callback to your application. And judge the activity type of current paused or resumed activity, etc. The sample code:
public static void init(Application app) {
app.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
private int activityCount = 0;
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
AppUtils.attachActivity(activity);
}
#Override
public void onActivityStarted(Activity activity) {
activityCount++;
AppUtils.attachForeActivity(activity);
}
#Override
public void onActivityResumed(Activity activity) {
if (!isForeGround) {
isForeGround = true;
notifyForegroundChange(true);
}
}
#Override
public void onActivityPaused(Activity activity) {
// no-op
}
#Override
public void onActivityStopped(Activity activity) {
AppUtils.detachForeActivity(activity);
activityCount--;
if (activityCount == 0) {
isForeGround = false;
notifyForegroundChange(false);
Log.i(TAG, "Activity foreground: " + System.currentTimeMillis());
}
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
// no-op
}
#Override
public void onActivityDestroyed(Activity activity) {
AppUtils.detachActivity(activity);
}
});
}
Here we use the activityCount filed to calculate current actived activities count. When it's 0, the app is background, otherwise foreground. You can judge the activity type by the callback method provided.
Hope it helps!
Related
I am creating one app In which I want to check status of activity like activity is in foreground or in background.this is working perfect from code but I want to bring activity to foreground when it is in background for that I am using service so when activity is going to background state I am calling that service and from that service I am launching activity but service is working ok upto version 10 after that same code of intent is not working.
This is my code.
MainActivity.Java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(android.os.Build.VERSION.SDK_INT>=29 &&
!Settings.canDrawOverlays(getApplicationContext())) {
MainActivity.this.startActivity(new
Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION));
}
}
This is DigitalApp class which extend application and from this I am calling service.
public class DigitalApp extends Application implements Application.ActivityLifecycleCallbacks
{
private int activityReferences = 0;
private boolean isActivityChangingConfigurations = false;
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
#Override
public void onActivityStarted(Activity activity) {
if (++activityReferences == 1 && !isActivityChangingConfigurations) {
// App enters foreground
Toast.makeText(this,"App is in foreground with
activity::"+activity.getLocalClassName(),Toast.LENGTH_LONG).show();
Log.d("Tracking Activity Started", activity.getLocalClassName());
Log.d("TAG","App is in foreground");
}
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
Toast.makeText(this,"App enters background with
activity::"+activity.getLocalClassName(),Toast.LENGTH_LONG).show();
isActivityChangingConfigurations = activity.isChangingConfigurations();
if (--activityReferences == 0 && !isActivityChangingConfigurations) {
// App enters background
Log.d("Tracking Activity Stopped", activity.getLocalClassName());
Log.d("TAG","App enters background");
Intent i= null;
getApplicationContext().startService(new
Intent(getApplicationContext(),service.class));
}
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
}
This is Service class.
#Override
public void onCreate() {
super.onCreate();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "IN HANDLER OF SERVICE",
Toast.LENGTH_LONG).show();
Intent i = new Intent(getApplicationContext(), MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(i);
}, 3000);
}
I am passing intent in handler to launch activity when it is going to background state.handler is in oncreate method of service.I want launch activity from there again after it is going to background state.
I am using flag new task but with this flag activity is not launching will I add other flags?
from the onStop() of your activity start the service like this-
fun launchService(){
val serviceIntent = Intent(this, LaunchAppService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent)
}else{
startService(serviceIntent)
}
}
and show notification for foreground service like this
Hey I have an application where I want to now when the APP goes to onPause or onDestroy because I want to call a certain function when this happens.
I tried to override the onPause in an activity and extended that activity in all project but the onPause was being called on every migration between activities (which is logical) but this is not what I want.
I want to know when the user exits the app or pauses it (pressing the home button)
Regards,
Pull this dependency in your build.gradle file:
dependencies {
implementation "android.arch.lifecycle:extensions:1.1.1"
}
Then in your Application class, use this:
public class MyApplication extends Application implements LifecycleObserver {
#Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
#OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackgrounded() {
Log.d("MyApp", "App in background");
}
#OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForegrounded() {
Log.d("MyApp", "App in foreground");
}
}
Update your AndroidManifest.xml file:
<application
android:name=".MyApplication"
....>
</application>
in all of your activities :
#Override
protected void onUserLeaveHint() {
super.onUserLeaveHint();
Log.e("TAG", "Activity Minimized");
}
in your main activity :
#Override
public void onBackPressed() {
Log.e("TAG", "App Exit");
super.onBackPressed();
}
note : there is no way to detect when app killed by system ( for example quit with task manager )
I use this method to detect if the app goes to background or is killed
step 1:
Make a service like this
public class OnClearFromRecentService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("ClearFromRecentService", "Service Started");
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("ClearFromRecentService", "Service Destroyed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.e("ClearFromRecentService", "END");
//Code here
stopSelf();
}
}
step 2)register this service in manifest.xml
<service android:name="com.example.OnClearFromRecentService" android:stopWithTask="false" />
step 3) Then start this service on your splash activity
startService(new Intent(getBaseContext(), OnClearFromRecentService.class));
So now when your app is manually killed, the onDestroy method will be called
Try this on your code and let me know if its working.
Happy Coding :)
If the user exits the application the onDestroy() callback will be called, if the user presses the home button the onStop() callback will be called.
So you want to know when the whole Application goes into Bacground, the method from Activity.onPause tells you when a single abtivity goes into background.
For your needs you could add
to your android manifest. this will call a class like this with name "YourApplication"
public class YourApplication extends Application {
#Override
public void onCreate() {}
public public void onTerminate() {
super.onTerminate();
}
}
e.g. for "onCreate" or "onTerminate" of the whole App (not for every single Activity).
But java documentation say you should not trust that onTerminate is called on every app destroy (see: android.app.Application subclass, onTerminate is not being called).
I Think the best way is, if you
add a own Methode "onPause" and "onResume" to your Application class
in ALL your Activities you store into Application class when onPause or onResume is called
and you call you own Application.onPause when ALL of you activities are in "onPause"
and you call you Application.onResume when first Activity is back in
"onResume"
Implement
Application.ActivityLifecycleCallbacks
in your Application Class. It will implement the following ActivityLifeCycle Methods :
isActivityVisible()
onActivityCreated()
onActivityStarted()
onActivityResumed()
onActivityPaused()
onActivityStopped()
onActivitySaveInstanceState()
onActivityDestroyed()
And Register the callback listener in OnCreate() of application class like :
registerActivityLifecycleCallbacks(this);
Define a Global variable in application class.
private static boolean isActive;
Now change the activity life cycle's overridden method like this:
public static boolean isActivityVisible() {
return isActive;
}
#Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
#Override
public void onActivityStarted(Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
isActive = true;
}
#Override
public void onActivityPaused(Activity activity) {
isActive = false;
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
#Override
public void onActivityDestroyed(Activity activity) {
isActive = false;
}
and you can perform the required operations on the value of isActive variable.
I have an application where I'm using GCM and I want to receive notifications only when app is closed, but when it's foreground don't receive them.
So is there some functionality to disable GcmListenerService for a while?
You do this wrong way. It is irrelevant really when your app will receive GCM message. In your case it's more important when it react to it. So instead of disabling your application component, I'd simply put some logic that would either ignore messages under certain conditions (like it's in foreground) or handle them differently in that case. That, for me, looks like better way than turning your app completely deaf.
You will have to track if your app is in foreground / background using Activity Life cycle callback.
public class SampleApplication extends Application
{
private static int sRunningActivityCount = 0;
#Override
public void onCreate()
{
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks(){
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState)
{
}
#Override
public void onActivityStarted(Activity activity)
{
sRunningActivityCount++;
}
#Override
public void onActivityResumed(Activity activity)
{
}
#Override
public void onActivityPaused(Activity activity)
{
}
#Override
public void onActivityStopped(Activity activity)
{
sRunningActivityCount--;
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
#Override
public void onActivityDestroyed(Activity activity)
{
}
});
}
public static boolean isAppBackground()
{
return sRunningActivityCount == 0;
}
public static boolean isAppForeground()
{
return sRunningActivityCount != 0;
}
}
You can use the following to enable/disable receiving GCM notifications:
public void setNotifications(boolean enabled)
{
mPackageManager.setComponentEnabledSetting(new ComponentName(mContext, YourGcmListenerService.class), enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Intent intent = new Intent(mContext, YourGcmListenerService.class);
if (enabled)
{
mContext.startService(intent);
}
else
{
mContext.stopService(intent);
}
}
I want my app to close when I press the back button on MainActivity. Currently when I press it on MainActivity, it returns to previous activity.
#Override
public void onBackPressed() {
YourActivity.this.finish();
}
It's worth noting that changing the default behavior is not a good idea.
You can use System.exit(0).
#Override
public void onBackPressed() {
System.exit(0);
}
Why would you want your app to not go back to previous activities?
If your MainActivity is started by an activity you don't want to go back to, its better to add flags to the intent that started MainActivity so the previous activity would not stay in the Task-stack.
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
If you dont want to do that, you must override the OnBackPress() to remove/finish the Tasks under the MainActivity in the stack.
This can be done with a LocalBroadcaster for example, even though its quite ugly.
In the activity you want to close:
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter("Your filter");
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
}
In your MainActivity:
#Override
public void onBackPressed() {
Intent intentBroadcast = new Intent("Your filter");
LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(intentBroadcast);
finish();
}
I have an application in which I have different activities. In 1 activity, I want that when the user presses the back button, I want the application to be closed and home screen is displayed
Code
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//Handle the back button
if(keyCode == KeyEvent.KEYCODE_BACK)
{
//Ask the user if they want to quit
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Exit")
.setMessage("Really Exit ?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
})
.setNegativeButton("No", null)
.show();
return true;
}
else
{
return super.onKeyDown(keyCode, event);
}
}
When I run this and press the back button, the home screen is displayed, but when I run it for the second time, I get a console output as
ActivityManager: Warning: Activity not started, its current task has been brought to the front.
And the activity in which the back button is pressed gets displayed.
I think the application does not get killed and runs in background. Just to mention, this is not the starting activity of my application.
Can somebody help me, I am beginner.
Try this code :
#Override
public void onBackPressed()
{
moveTaskToBack(true);
}
Also check this Link
For each and every Intent you have used for going into other activity u have to follow this way for passing intent just pass flag to each intent as given below and after starting Activity using startActivity() u have to add finish() after that demo code as given below
Intent i=new Intent(firstActivity.this,secondActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
finish();
You cannot kill your application at your will. The android OS will do it when it wishes to free the resources allocated to it. You cannot actually implement the exit application concept in android. The user can simply navigate away from your Activity and return to it. If it has to be restarted from the first Activity or resumed where it left, is upto the android OS, not you.
Read this post to understand the philosophy of how android apps should be designed and why you wouldn't want to exit at your will:
Is quitting an application frowned upon?
Add finish(); after that line startActivity(intent) it finish your activity.
Thanks
you need to include this class as such in your code.........
public abstract class AppBaseActivity extends Activity {
public static final String FINISH_ALL_ACTIVITIES_ACTIVITY_ACTION = "com.hrupin.FINISH_ALL_ACTIVITIES_ACTIVITY_ACTION";
private BaseActivityReceiver baseActivityReceiver = new BaseActivityReceiver();
public static final IntentFilter INTENT_FILTER = createIntentFilter();
private static IntentFilter createIntentFilter(){
IntentFilter filter = new IntentFilter();
filter.addAction(FINISH_ALL_ACTIVITIES_ACTIVITY_ACTION);
return filter;
}
protected void registerBaseActivityReceiver() {
registerReceiver(baseActivityReceiver, INTENT_FILTER);
}
protected void unRegisterBaseActivityReceiver() {
unregisterReceiver(baseActivityReceiver);
}
public class BaseActivityReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(FINISH_ALL_ACTIVITIES_ACTIVITY_ACTION)){
finish();
}
}
}
protected void closeAllActivities(){
sendBroadcast(new Intent(FINISH_ALL_ACTIVITIES_ACTIVITY_ACTION));
}
}
Then you need to extend all other classes from this class just as in an example below:
public class FirstActivity extends AppBaseActivity implements OnClickListener {
/** Called when the activity is first created. */
private Button buttonOpenNextActivity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first);
registerBaseActivityReceiver();
buttonOpenNextActivity = (Button)findViewById(R.id.buttonOpenNextActivity);
buttonOpenNextActivity.setOnClickListener(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
unRegisterBaseActivityReceiver();
}
#Override
public void onClick(View v) {
/* OPEN SECOND ACTIVITY.*/
startActivity(new Intent(this, SecondActivity.class));
}
}
Another class:
public class SecondActivity extends AppBaseActivity implements OnClickListener {
private Button buttonOpenNextActivity;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
registerBaseActivityReceiver();
buttonOpenNextActivity = (Button)findViewById(R.id.buttonOpenNextActivity);
buttonOpenNextActivity.setOnClickListener(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
unRegisterBaseActivityReceiver();
}
#Override
public void onClick(View v) {
/* OPEN THIRD ACTIVITY.*/
startActivity(new Intent(this, ThirdActivity.class));
}
}
Last Class:
public class ThirdActivity extends AppBaseActivity implements OnClickListener {
private Button buttonCloseAllActivities;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
registerBaseActivityReceiver();
buttonCloseAllActivities = (Button)findViewById(R.id.buttonCloseAllActivities);
buttonCloseAllActivities.setOnClickListener(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
unRegisterBaseActivityReceiver();
}
#Override
protected void onBackPressed() {
closeAllActivities();
super.onBackPressed();
}
}
Now when you press back button in third activity all other activities will also be finished altogether.
1/ dont forget to register the reciever in onCreate and unregister() it in ondestroy().
Your question is not clear dear.
As per my knowledge you should use broadCast Reciever for finishing the application and passing the intent to home Screen.
MoreOver Warning is nothing , before running your application just press Enter in your code or give sm space and den save it and re- run you appication.It will work fine....
if you want to exit your application on back press then you have to finish all the previous activities when you press the back button on that screen for this you should use the concept of BROADCAST RECIEVER ...... means you have broadcast an intent on that back press which will finish all the previous activities.