how to call method after 2 minutes in background

519 views Asked by At

i need to call a method after 2 minutes. i have tried handler and timer but when app close then it doesn't work. then i have call timer in service and start service on button click and stop service after 2 minutes. it works but problem is sometime service calls itself. below is my code.

MyService class

public class MyService extends Service {

private static Retrofit retrofit = null;

@Override
public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public void onCreate() {
    new CountDownTimer(120000, 1000) {
        public void onTick(long millisUntilFinished) {
            Log.d("message", "start");
        }
        public void onFinish() {
            Log.d("message", "finish");

            callMyMethod();
            stopService(new Intent(MyService.this, MainActivity.class));
        }
    }.start();
}

MainActivity class from where i start service.

stopService(new Intent(getContext(), MyService.class));
startService(new Intent(getContext(), MyService.class));

Manifest

<service android:name="MyService" android:enabled="true" android:exported="true"/>

NOTE: I WANT TO CALL SERVICE ONLY ON BUTTON CLICK AND STOP SERVICE AFTER 2 MINUTES. please need help to solve this issue or If there is other good solution other than services.

Updated: if network response in not success how can i handle to retry.

MyService class

public class MyService extends Service {

private static Retrofit retrofit = null;

@Override
public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public void onCreate() {
    new CountDownTimer(120000, 1000) {
        public void onTick(long millisUntilFinished) {
            Log.d("mess", "start");
        }
        public void onFinish() {
            Log.d("mess", "finish");

            selectDriverForJOb();
            stopSelf();//(new Intent(MyService.this, MainActivity.class));
        }
    }.start();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
     return START_NOT_STICKY;
}

private void selectDriverForJOb() {
    SharedPreferences sharedPreferences = getSharedPreferences("Login_credentials", MODE_PRIVATE);
    String user_id = sharedPreferences.getString("userID", null);
    if (retrofit == null) {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    APIServices_interface selectDriver_interface = retrofit.create(APIServices_interface.class);
    Call<SelectDriverforJobResult> call = null;
    try {
        call = selectDriver_interface.selectDriverforJob(user_id);
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (call != null) {
        try {
            call.enqueue(new Callback<SelectDriverforJobResult>() {
                @Override
                public void onResponse(Call<SelectDriverforJobResult> call, Response<SelectDriverforJobResult> response) {
                    SelectDriverforJobResult selectDriver = response.body();
                    String message = selectDriver.getMessage();
                    if(!(message.equalsIgnoreCase("success"))){

                    }
                }

                @Override
                public void onFailure(Call<SelectDriverforJobResult> call, Throwable t) {
                    Log.d("mess : ", "Error Updating ");
                    //want to retry
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
}
2

There are 2 answers

2
Zain Ul Abideen On BEST ANSWER

override onStartCommand in service and return START_NOT_STICKY it will not restart the

public void onStartCommand()
{
     return START_NOT_STICKY
}

and use stopSelf() insted of stopService(new Intent(getContext(), MyService.class));

2
SpiritCrusher On

Your Service will not run after app close, Read background restriction. And this is not really a Service use case.

The solution can be to your problem is AlarmManager . Set an alarm for exact after 2 minutes and your Receiver willget called when its triggered . Before using AlarmManger give a read to setExactAndAllowWhileIdle() and setExact().

Alternatively you can also use WorkManager to set a Exact Job . But This will be an overkill if you do not need Job Constraints. So if your work does not depends of any Constraints like Network connection or other you can go with AlarmManger.

PS:- If your task depends on a Network connection then you should go with WorkManager. Read Schedule tasks with WorkManager .