Как я могу превратить свою asyncTask в службу?

Как можно изменить мой asyncTask на сервис, потому что каждый раз, когда я закрываю приложение или перезагружаю устройство, мой aysncTask не работает. У меня есть aysnc, который отправляет почтовый запрос на php-сервер, и я возвращал изображение по каждому запросу, поэтому я поставил пользователю параметр настройки, который он может выбрать, чтобы изображение обоев менялось каждые 1,5,10,..... мин., но, как я уже сказал, я хочу быть службой, поэтому, когда пользователь выбирает время для смены обоев и закрывает (уничтожает) приложение, сервер все еще продолжает изменяться, вот мой код

public class MainActivity extends AppCompatActivity {

    TextView txt;
    Button btn;
    String forecastJsonStr;
    RadioButton rd1, rd2, rd3, rd4, rd5, rd6, rd7;
    Handler mHandler;
    RadioGroup radioGroup;

    private final static int INTERVAL = 1000*60 * 1; //1 min
    private final static int INTERVAL2 = 1000*60*5; // 5 min
    private final static int INTERVAL3 = 1000 * 60 * 10; // 10 min
    private final static int INTERVAL4 = 1000 * 60 * 15; // 15 min
    private final static int INTERVAL5 = 1000 * 60 * 30; // 30 min
    private final static int INTERVAL6 = 1000 * 60 * 60; // 1 hour
    private final static int INTERVAL7 = 1000 * 60 * 1440; // 1 day

    private final String hostName = "http://555.555.555.555";
    private final String hostRequestName = "/yay.php";
    private final String hostWallpaperName = "/wallpaper/";
    private static int SELECTED_INTERVAL = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txt = (TextView) findViewById(R.id.textView);
        rd1 = (RadioButton) findViewById(R.id.radioButton);
        rd2 = (RadioButton) findViewById(R.id.radioButton2);
        rd3 = (RadioButton) findViewById(R.id.radioButton3);
        rd4 = (RadioButton) findViewById(R.id.radioButton4);
        rd5 = (RadioButton) findViewById(R.id.radioButton5);
        rd6 = (RadioButton) findViewById(R.id.radioButton6);
        rd7 = (RadioButton) findViewById(R.id.radioButton7);
        radioGroup = (RadioGroup) findViewById(R.id.radiogroup);
        mHandler = new Handler();
        btn = (Button) findViewById(R.id.button);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(rd1.isChecked()) {
                    SELECTED_INTERVAL = INTERVAL;
                } else if (rd2.isChecked()) {
                    SELECTED_INTERVAL = INTERVAL2;
                }
                startRepeatingTask();
            }
        });
    }

    void startRepeatingTask() {
        mHandlerTask.run();
    }

    Runnable  mHandlerTask = new Runnable() {
        @Override
        public void run() {
            new WallpaperData().execute();
            mHandler.postDelayed(mHandlerTask, SELECTED_INTERVAL);
        }
    };

    private class WallpaperData extends AsyncTask<Void, Void, String> {

        @Override
        protected String doInBackground(Void... params) {

            HttpURLConnection urlConnection = null;
            BufferedReader reader = null;

            try {

                URL url = new URL("http://555.555.555.555/yay.php");

                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("POST");
                urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                urlConnection.setDoInput(true);
                urlConnection.setDoOutput(true);
                urlConnection.connect();
                DataOutputStream wr = new DataOutputStream(
                        urlConnection.getOutputStream());
                wr.write("method=get_random_wallpaper".getBytes());
                wr.flush();
                wr.close();

                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                if (inputStream == null) {
                    return null;
                }
                reader = new BufferedReader(new InputStreamReader(inputStream));

                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line + "\n");
                    Log.d("hey", buffer.toString());
                }

                if (buffer.length() == 0) {
                    return null;
                }
                forecastJsonStr = buffer.toString();

                return forecastJsonStr;
            } catch (IOException e) {
                Log.e("PlaceholderFragment", "Error ", e);
                return null;
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (final IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        @Override
        protected void onPostExecute(final String forecastJsonStr) {

            txt.setText(forecastJsonStr);

            Thread thread = new Thread(new Runnable() {

                @Override
                public void run() {

                    WallpaperManager wallpaperManager = WallpaperManager.getInstance(getApplicationContext());
                    try {
                        Bitmap result = Picasso.with(getBaseContext())
                                .load(hostName + hostWallpaperName + forecastJsonStr)
                                .get();
                        wallpaperManager.setBitmap(result);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            });
            thread.start();

            super.onPostExecute(forecastJsonStr);

        }
    }

}

person Community    schedule 31.10.2016    source источник


Ответы (1)


Для временных интервалов, превышающих 30 секунд, вы должны использовать AlarmManager вместо метода Handler .postDelayed. См. эти руководства: https://developer.android.com/training/scheduling/alarms.html, http://code4reference.com/2012/07/tutorial-on-android-alarmmanager/ . Существует JonScheduler для планирования повторяющихся задач, у Vogella есть учебник: http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html . В двух словах: вы создаете Сервис (InteneService), создаете PendingIntent, указывающий на этот сервис, и планируете AlarmManager, который будет отправлять это намерение, которое, в свою очередь, все еще запускает ваш IntentService.

person Alex Shutov    schedule 31.10.2016
comment
Service и IntentService — это Android-компоненты, которые работают в фоновом режиме без какого-либо пользовательского интерфейса, вы должны переместить в него свой код. - person Alex Shutov; 31.10.2016
comment
Для вашей цели используйте IntentService - по умолчанию у него есть фоновый поток, поэтому вам не понадобится AsyncTask. Он остановится, когда работа будет выполнена. - person Alex Shutov; 31.10.2016
comment
но мне нужна асинхронная задача для отправки почтового запроса на php-сервер. может ли Intentservice сделать это? - person ; 31.10.2016
comment
AsyncTask используется для работы в фоновом режиме (не в MainThread), это просто для удобства. IntenService также работает в фоновом потоке. Но AsyncTask доставляет результаты работы в основной поток в методе postExecute(). Если вы хотите уведомить пользовательский интерфейс о результате операции, вы должны отправить Intent и получить его в BroadcastReceiver или использовать EventBus - person Alex Shutov; 31.10.2016
comment
В туториалах есть примеры рабочего кода, просто изучите их. - person Alex Shutov; 31.10.2016
comment
до сих пор не знаю, как совместить аварийный менеджер с сервисом намерений с моим кодом :( - person ; 31.10.2016
comment
спасибо в любом случае, но я пытаюсь больше часа и потерпел неудачу - person ; 31.10.2016