Android onTaskRemoved() вызывает веб-сервис

Добрый день. У меня ужасная ситуация. Я создаю логику общего доступа к местоположению в сеансе. Я сохраняю этот сеанс на сервере в mysql. Когда андроид переходит к этому действию, я вставляю соответствующую информацию о пользователе. Столбец, поэтому сеанс прекращается для противоположной стороны. Все отлично, пока не возникнет одна проблема. Android не обеспечивает обратный вызов для приложения, которое было удалено из недавних, что означает, что приложение было полностью убито. Я нашел там обходной путь. Я использую службу и запуск службы, как только она достигает желаемой активности. В службе у меня есть простая вещь, называемая onTaskRemoved(), которая уведомляет меня, как только приложение было убито, проводя его из последних. Все хорошо до того момента, когда я хочу позвонить на свой сервер чтобы удалить столбец. Вызов не просто пройдет, я никогда не получу там никакого ответа, но в onDestroy() все работает как положено. Собственно вот код

 @Override
public void onTaskRemoved(Intent rootIntent) {
    destroySession();
    super.onTaskRemoved(rootIntent);
}

private void destroySession() {
    Log.d("Fsafasfsafasfas", "destroySession: " + opponentId + " my user id" + sharedHelper.getUserId());
    Call<ResponseBody> locationCall = Retrofit.getInstance().getInkService().requestFriendLocation(sharedHelper.getUserId(), opponentId, "", "", Constants.LOCATION_REQUEST_TYPE_DELETE);
    locationCall.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response == null) {
                destroySession();
                return;
            }
            if (response.body() == null) {
                destroySession();
                return;
            }
            try {
                String responseBody = response.body().string();
                Log.d("Fsafasfsafasfas", "onResponse: " + responseBody);
                JSONObject jsonObject = new JSONObject(responseBody);
                boolean success = jsonObject.optBoolean("success");
                if (success) {
                    stopSelf();
                } else {
                    destroySession();
                }
            } catch (IOException e) {
                stopSelf();
                e.printStackTrace();
            } catch (JSONException e) {
                stopSelf();
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            destroySession();
        }
    });
}

Вызов никогда не пройдет, я думаю, поскольку единственный журнал, который печатается, это журналы идентификатора и ничего больше. Кто-нибудь знает, что происходит? И как я могу справиться с этой ситуацией?


person Android Developer    schedule 17.08.2016    source источник
comment
Здравствуйте, у вас есть решение этой проблемы? благодарю вас.   -  person user1510006    schedule 15.02.2017
comment
еще нет :( не могу пройти   -  person Android Developer    schedule 31.03.2017


Ответы (2)


Я решил это, отменив строгий режим политики потоков. Таким образом, http-запросы могут выполняться из основного потока.

 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
 StrictMode.setThreadPolicy(policy);

Это не рекомендуется в обычной ситуации, но когда приложение выходит из строя или закрывается, я думаю, что это нормально для отправки одного HTTP-запроса.

person Moshe Yamini    schedule 11.11.2020

/**
 * Created by Parag on 01/05/2017.
 */

public class AppService extends android.app.Service {
    public static final String TAG=AppService.class.getName();
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Bundle bundle=intent.getExtras();
        if(bundle!=null){
            final String logout=bundle.getString("logout");
            final String driverLoginId=bundle.getString("driverLoginId");
            if(logout!=null&&driverLoginId!=null){
                Toast.makeText(this, "logging out", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"Logging out");
                Log.e(TAG,"Inside driverLogout "+driverLoginId);
                Call<LogoutResponse> call = RestHandler.getApiService().driverLogout(driverLoginId);
                call.enqueue(new Callback<LogoutResponse>() {
                    @Override
                    public void onResponse(Call<LogoutResponse> call, Response<LogoutResponse> response) {
                        //close the service on receiving response from API
                        Log.e("Response : ",response.body().getStatus()+"");
                        AppService.this.stopSelf();
                    }
                    @Override
                    public void onFailure(Call<LogoutResponse> call, Throwable t) {
                        //close the service on receiving response from API
                        AppService.this.stopSelf();
                    }
                });

            }else{
                //Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
                Log.e(TAG,"DriverLoginId : "+driverLoginId);
                Log.e(TAG,"Logout : "+logout);
            }
        }else{
            //Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
            Log.e(TAG,"Service Start");
        }
        return super.onStartCommand(intent,flags,startId);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {

        Log.e(TAG,"Service Stop");
        UserLocalStore userLocalStore=new UserLocalStore(AppService.this);
        Log.e("USER DATA :",userLocalStore.fetchUserData().toString());
        Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
        restartServiceTask.setPackage(getPackageName());
        restartServiceTask.putExtra("logout","true");
        restartServiceTask.putExtra("driverLoginId",userLocalStore.fetchUserData().getUserId());
        PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        myAlarmService.set(
                AlarmManager.ELAPSED_REALTIME,
                SystemClock.elapsedRealtime() + 1000,
                restartPendingIntent);
        super.onTaskRemoved(rootIntent);
    }


}

Я также столкнулся с той же проблемой, когда не мог выполнять какие-либо вызовы API из метода onTaskRemoved. Итак, я также много исследовал, но не нашел решения. Итак, у меня, наконец, появилась идея перезапустить веб-сервис с некоторыми дополнениями, размещенными внутри намерения. Таким образом вы можете различать, когда служба перезапускается для выполнения вашего вызова API.

person Parag Bhadoria    schedule 03.05.2017
comment
Мне это помогло. но я сначала проверил также, если намерение не равно нулю, тогда делайте что-то. Вот мой код: @Override public int onStartCommand (намерение намерения, флаги int, int startId) { if (intent! = null) { Bundle bundle = намерение.getExtras(); if (bundle!= null) { final String logout = bundle.getString(logout); если (выход из системы!= ноль) { logoutAndStopServiceRightAway(); вернуть START_NOT_STICKY; } } } вернуть START_STICKY; } - person sAm; 19.10.2017
comment
По какой-то причине код не работает на моем oneplus 5 под управлением Android 10, а на моем планшете samsung tab 7 под управлением 7.1.1 он работает нормально - person DemoDemo; 23.09.2020
comment
То же самое. В Android 8 служба перезапускается, но дополнительные намерения недействительны. - person Moshe Yamini; 09.11.2020