0

У меня есть служба, которая выполняет AsyncTask, которая вызывает себя после каждого завершения. Как вы увидите ниже, я начинаю свою работу на переднем плане. Он запускается успешно и продолжает работать, как предполагалось, в то время как я подключен к нему на своем компьютере и выводят вывод в LogCat. Я знаю это, потому что, чтобы проверить, у меня мой цикл AsyncTask выплескивает уведомление каждые 5 минут. Однако, когда я отключу его от своего компьютера, уведомления не поступают! Это как если бы служба просто прекратилась после того, как я ее запустил!мой Android-сервис не будет работать

ПРИМЕЧАНИЕ. Мое обслуживание - это регулярное обслуживание, а не IntentService.

Вот мой onStartCommand ...

@SuppressWarnings("deprecation") 
@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    getData(intent); 
    self = this; 

    // Enter foreground state 
    String title = "Service started."; 
    String subject = "Service is running."; 
    String body = "Monitoring..."; 
    Notification notification = new Notification(R.drawable.ic_launcher, title, 
      System.currentTimeMillis()); 
    if(notificationSounds) 
     notification.defaults |= Notification.DEFAULT_SOUND; 
    else 
     notification.sound = null; 
    Intent notificationIntent = new Intent(this, MainActivity3.class); 
    PendingIntent pendIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 
    notification.setLatestEventInfo(this, subject, body, pendIntent); 
    startForeground(1500, notification); 

    new BatteryLifeTask(appContext).execute(); 
    return START_NOT_STICKY; 
} 

Вот мой AsyncTask:

// Looping AsyncTask for continuous mode 
private class BatteryLifeTask extends AsyncTask<Void, Void, Void> { 

    // Member variables 
    Context appContext; 
    int batteryPct0; 

    public BatteryLifeTask(Context context) { 
     super(); 
     appContext = context; 
    } 

    protected Void doInBackground(Void... params) { 
     System.out.println("Entering doInBackground"); 
     // Get the initial battery level 
     batteryPct0 = getBatteryPercent(); 
     System.out.println("Initial battery percent: " + batteryPct0); 

     // Check time 
     Calendar c = Calendar.getInstance(); 
     Date dateNow = c.getTime(); 
     // getTime returns ms, need minutes. 60000ms in a minute. 
     long currTime = dateNow.getTime()/60000; 

     if(currTime >= timeToUse){ 
      finished = true; 
      stopSelf(); 
     } 

     System.out.println("Leaving doInBackground"); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     super.onPostExecute(aVoid); 
     if(!finished) { 
      int waitTime = 60000 * interval; // 1 minute is 60000 miliseconds 
      System.out.println("Entering postExecute. waitTime is " + waitTime); 
      Runnable r = new Runnable() { 
       @Override 
       public void run() { 
        if(!finished) { // In case postDelayed is pending, avoids extra notification 
         System.out.println("An interval has passed."); 
         calculateHelper(batteryPct0); 
         new BatteryLifeTask(appContext).execute(); 
        } 
       } 
      }; 
      Handler h = new Handler(); 
      h.postDelayed(r, waitTime); 
     } 
    } 
} 

И вот мой код для создания уведомлений:

// Method for creating a notification 
@SuppressWarnings("deprecation") 
void notify0(int id, String title, String subject, String body, boolean playSound){ 
    NotificationManager NM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
    Notification notify = new Notification(android.R.drawable. 
    PendingIntent pending = PendingIntent.getActivity(
      getApplicationContext(), 0, new Intent(), 0); 
    notify.setLatestEventInfo(getApplicationContext(), subject, body, pending); 
    if(playSound) 
     notify.defaults |= Notification.DEFAULT_SOUND; 
    else 
     notify.sound = null; 

    // Cancel running notification if exists 
    NM.cancel(id); 

    // Push notification 
    NM.notify(id, notify); 
} 



Может ли кто-нибудь помочь е? Это сводит меня с ума! Мое приложение работает PERFECTLY при подключении и подключении к USB-отладке. Но когда он отключен, служба, похоже, полностью останавливается и ничего не делает.

+0

использовать alarmmanager – njzk2

+0

связаны между собой, но вместо '// 1 минуту 60000 miliseconds', вы можете использовать http://developer.android.com/reference/android/text/format/DateUtils.html#MINUTE_IN_MILLIS – njzk2

+0

@ njzk2 Спасибо, это полезно. Используйте будильник для чего? как это поможет? – JayB

ответ

0

Возврат START_STICKY вместо START_NOT_STICKY и рассмотрите ваш дизайн. В вашем случае лучше использовать AlarmManager с 5-минутным таймаутом, а затем запустить IntentService.

+0

waitTime в моем приложении можно установить до 3 часов. Часть дизайна состоит в том, чтобы получить уровень заряда батареи в начале в 3 часа, а в конце 3 часов и найти разницу, чтобы получить батарею, используемую в течение этого интервала. Это часть алгоритма прогнозирования. Будет ли этот 5-минутный тайм-аут вмешиваться в это? – JayB

+0

Установите тайм-аут диспетчера аварийных сообщений, который вы хотите, но установите таймер с диспетчером аварийных сигналов и управляйте им. Таким образом, вы избегаете утечки батареи. – greywolf82

+0

Можете ли вы представить пример задачи, выполненной с помощью будильника? Кроме того, имеет ли он выполнение pre/post? Мне нужен код, который в настоящее время находится в doInBackground, который должен быть выполнен и выполнен до кода в postExecute. Я видел, что AsyncTask имел эту функциональность, поэтому я решил использовать ее в своем дизайне. – JayB

2

Это потому, что вы возвращаете START_NOT_STICKY на службе onStartCommand().

START_NOT_STICKY если процесс этого сервиса убит в то время как он был запущен (после возвращения из onStartCommand (Intent, Int, Int)), и нет никакого нового стартового намерения , чтобы доставить к нему, а затем принять служба из начального состояния и не восстанавливаются до следующего явного вызова Context.startService (Intent).

Вы должны вернуть START_STICKY вместо

START_STICKY Если процесс этого сервиса будет убит в то время как он был запущен (после возвращения из onStartCommand (Intent, Int, Int)), то оставить его в начались, но не сохраняют это поставленное намерение. Позже система попытается воссоздать службу.

Проверьте это service api changes, в частности, раздел изменений жизненного цикла службы.