2

I have made an App in android in which i have a TCP Client but now i want to send a message to the server only when the app is going to be closed, i've trying to add the openConnection (opening connection with TCP Client) and sendMessage (Sending message to the TCP server) action in onDestroy method but that didn't worked. The TCP Client i've used is in this guide, actually i need to send this message for communicate the server that the communication with the device is closed and send message "Device is Offline" and just then close the app.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
John K
  • 371
  • 5
  • 26
  • try to create a service at the beginning and then send a broadcast to this service when the `onDestroy` is called, the service will remain even if the app goes down... – Idemax Jul 19 '17 at 11:08
  • this might not work if the user is turning off his phone... – Idemax Jul 19 '17 at 11:09
  • @MarceloFilho actually i was trying to use this [guide](https://stackoverflow.com/questions/21040339/how-to-know-when-my-app-has-been-killed/33078782#33078782) but i only managed to start TCP Client again, when it closed app too fast for send also the message. – John K Jul 19 '17 at 13:24

3 Answers3

1

Method 1: You can use ActivityLifecycleCallbacks to achieve this. There's an example with some logs below.

public class MyApplication extends Application {

    private static final String TAG = MyApplication.class.getSimpleName();
    private int mVisibleCount;
    private boolean mInBackground;

    @Override public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            }

            @Override public void onActivityStarted(Activity activity) {
                mVisibleCount++;
                if (mInBackground && mVisibleCount > 0) {
                    mInBackground = false;
                    Log.i(TAG, "App in foreground");
                }
            }

            @Override public void onActivityResumed(Activity activity) {
            }

            @Override public void onActivityPaused(Activity activity) {
            }

            @Override public void onActivityStopped(Activity activity) {
                mVisibleCount--;
                if (mVisibleCount == 0) {
                    if (activity.isFinishing()) {
                        Log.i(TAG, "App is finishing");
                    } else {
                        mInBackground = true;
                        Log.i(TAG, "App in background");
                    }
                }
            }

            @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override public void onActivityDestroyed(Activity activity) {
            }
        });
    }

    public boolean isAppInBackground() {
        return mInBackground;
    }

    public boolean isAppVisible() {
        return mVisibleCount > 0;
    }

    public int getVisibleCount() {
        return mVisibleCount;
    }
}

Method 2: There's another method using Service to detect if application is terminated. See link

Fatih Santalu
  • 4,641
  • 2
  • 17
  • 34
  • I have to implement it in MainActivity or create a new class? and how can i evocate it from the MainActivity? – John K Jul 19 '17 at 07:02
  • I don't think you can do this in any activity. You should really create an application class – Fatih Santalu Jul 19 '17 at 07:04
  • And after i've created a new class with all this, how can i evocate it in MainActivity? – John K Jul 19 '17 at 07:06
  • After you created your application class you should set application name in your manifest file see [link](https://developer.android.com/reference/android/app/Application.html) . You don't need to invoke anything in your MainActivity. Just do your work here. Better understanding for application class see [link](https://stackoverflow.com/questions/18002227/why-extend-an-application-class) – Fatih Santalu Jul 19 '17 at 07:14
  • Look's like it working because i can see the Log "App in background" but when i close it from the task there is no Log "App is finishing" ... where should i implement my messageSend action in MyApplication? – John K Jul 19 '17 at 07:22
  • Yes exactly, in your case you should do your work when `Log.i(TAG, "App is finishing");` happens – Fatih Santalu Jul 19 '17 at 07:23
  • Seems it doesn't work properly because i can't see the Log.i((TAG,"App in foreground") and also the Log.i(TAG,"App is finishing") but only the Log.i(TAG,"App in background"); – John K Jul 19 '17 at 07:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149554/discussion-between-i-mytyuk-and-santalu). – John K Jul 19 '17 at 07:34
  • Is there a way to delay a bit onTaskRemoved from the second method? because it's too fast and i have the time just to reopen the TCP Client connection but not send the message – John K Jul 19 '17 at 08:34
  • I guess you can use Handler [link](https://stackoverflow.com/a/9166354/1512199) – Fatih Santalu Jul 19 '17 at 08:36
0

Following method call on diff action

  • Minimize the Application using home button --> this calls

    onPause() onStop()

  • Remove the app from Task Manager ->

    then onDestroy() is called for that MainActivity (launcher).

So Make an parent Activity suppose named BaseActivity and override its onPause(), onDestroy() and onStop() method and call your implementation from here and then extend this Activity from your another Activities

Bhushan Uniyal
  • 5,575
  • 2
  • 22
  • 45
0

You should not rely on the onDestroy method. As per the official android documentation it is not called always.

Try to put the same code in the onStop() method of your activity.

Additionally you can have a parent activity which is extended by all other activities.

You can then override the onPause() and onStop() method in your particular child activities and handle the specific scenarios.