Search code examples
javaandroidandroid-intentserviceandroid-ondestroy

Android Request to server before application compeletly closed


I have just one Activity , when user close the application (from os clear list of recent apps) I want to send a request to my server api and change user status. so I make IntentService and call it in my onDestroy() method of activity, but it dosn't work. how do it? is there any way else to do this(send request to server before application killed compeletly)? my code :

Activity:

@Override
protected void onDestroy() {
    Intent intent = new Intent(this, MakeOfflineIntentService.class);
    intent.putExtra(Variables.INTENT_TOKEN, Token);
    intent.setAction("ACTION_MAKE_OFFLINE");
    startService(intent);
    super.onDestroy();
}

and in my IntentService:

public class MakeOfflineIntentService extends IntentService {

private static final String ACTION_MAKE_OFFLINE = "ACTION_MAKE_OFFLINE";

private static final String EXTRA_TOKEN = Variables.INTENT_TOKEN;

public MakeOfflineIntentService() {
    super("MakeOfflineIntentService");
}

public static void startActionFoo(Context context, String param1) {
    Intent intent = new Intent(context, MakeOfflineIntentService.class);
    intent.setAction(ACTION_MAKE_OFFLINE);
    intent.putExtra(EXTRA_TOKEN, param1);
    context.startService(intent);
}

@Override
protected void onHandleIntent(Intent intent) {
    if (intent != null) {
        final String action = intent.getAction();
        if (ACTION_MAKE_OFFLINE.equals(action)) {
            final String param1 = intent.getStringExtra(EXTRA_TOKEN);
            retrofitBaseInformationChange(param1,Variables.OFFLINE,1);
        }
    }
}

private void retrofitBaseInformationChange(final String Token, final int online, int vehicle){
    RetrofitCallServer retrofitCallServer = new RetrofitCallServer(WebServiceUrls.RETROFIT_INFORMATION_CHEETAH_MAN);
    OnCallBackRetrofit onCallBackRetrofit = retrofitCallServer.getResponse();

    Call<OBRbaseInfromationChange> call = onCallBackRetrofit.askBaseInformationChange(Token,online,vehicle);
    call.enqueue(new Callback<OBRbaseInfromationChange>() {

        @Override
        public void onResponse(Call<OBRbaseInfromationChange> call, Response<OBRbaseInfromationChange> response) {
            /*response gotten maybe success or not*/
            if (response.isSuccessful()){
                OBRbaseInfromationChange obr = response.body();
                if(obr.code == 200){
                    Log.i(Variables.APP_TAG,"BaseInformationChange successful");
                }
                else{
                    Log.i(Variables.APP_TAG,"BaseInformationChange error code: "+obr.code);
                }
            }// end if response successful
            else {
                Log.i(Variables.APP_TAG,"BaseInformationChange not Successful: "+response.code());
            }
        }

        @Override
        public void onFailure(Call<OBRbaseInfromationChange> call, Throwable t) {
            /*our request not sent or conversion problem*/
            Log.i(Variables.APP_TAG,"onFailure BaseInformationChange: "+t.getMessage());
        }

    });
}
// end retrofitBaseInformationChange()

}

and finally here is in my manifest:

<service
        android:name=".Services.MakeOfflineIntentService"
        android:exported="false"
        android:stopWithTask="false"/>

Solution

  • Have you tried to return START_STICKY in the onStartCommand override?

    After you sent your request you can then call stopService to stop yourself.

    As far as I know, even sticky services might be "recreated" when you kill the app. So maybe, an Intent is not the best way to use here.

    I'd go with SharedPreferences here:

    • The onCreate of your app sets the key "app_offline" to "false"

    • The onDestroy sets this key to "true" and starts the service

    • The service is START_STICKY and when it finds the "app_offline" as true, sends its request, updates "app_offline" to false (resets it) and then performs a self-shutdown.

    Something like that. Hope this helps, cheers, Gris