5

Pracujemy nad rozwojem usługi dla platformy Android.Czy możliwe jest ciągłe uruchamianie usługi na platformie Android, nawet po zablokowaniu urządzenia?

W naszym serwisie musimy wysyłać dane GPS (długie i długie) urządzenia do jakiejś zewnętrznej usługi REST po każdej minucie.

Działa prawie przez 15 minut po zamknięciu urządzenia. Ale potem nie wysyła żadnych danych.

Po odblokowaniu urządzenia rozpoczyna się ponownie wysyłanie danych za pośrednictwem usługi REST.

mojego kodu Dotychczas

public class MainActivity extends AppCompatActivity { 

private PendingIntent pendingIntent; 
private PowerManager.WakeLock wakeLock; 

public static final String USER_NAME = "USERNAME"; 

String username; 
String password; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    Intent alarm = new Intent(this, AlarmReceiver.class); 
    boolean alarmRunning = (PendingIntent.getBroadcast(this, 0, alarm, PendingIntent.FLAG_NO_CREATE) != null); 
    if(alarmRunning == false) { 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarm, 0); 
     AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
     alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 30000, pendingIntent); 
    } 

    PowerManager mgr = (PowerManager)this.getSystemService(Context.POWER_SERVICE); 
    wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyWakeLock"); 
    wakeLock.acquire(); 
} 

public class BackgroundService extends Service { 

private boolean isRunning; 
private Context context; 
private Thread backgroundThread; 

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

@Override 
public void onCreate() { 
    this.context = this; 
    this.isRunning = false; 
    this.backgroundThread = new Thread(myTask); 
} 

private Runnable myTask = new Runnable() { 
    public void run() { 
     // Do something here 
     login("admin","admin"); 
     stopSelf(); 
    } 
}; 

@Override 
public void onDestroy() { 
    this.isRunning = false; 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if(!this.isRunning) { 
     this.isRunning = true; 
     this.backgroundThread.start(); 
    } 
    return START_STICKY; 
} 

private void login(final String strLatitude, final String strLongitude) { 


    class LoginAsync extends AsyncTask<String, Void, String> { 

     String charset = "UTF-8"; 
     HttpURLConnection conn; 
     DataOutputStream wr; 
     StringBuilder result = new StringBuilder(); 
     URL urlObj; 
     JSONObject jObj = null; 
     StringBuilder sbParams; 
     String paramsString; 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      // loadingDialog = ProgressDialog.show(MainActivity.this, "Please wait", "Loading..."); 
     } 

     @Override 
     protected String doInBackground(String... params) { 
      String uname = params[0]; 
      String pass = params[1]; 

      sbParams = new StringBuilder(); 

      try { 
       sbParams.append("name").append("=") 
         .append(URLEncoder.encode(uname, charset)); 
       sbParams.append("&"); 
       sbParams.append("password").append("=") 
         .append(URLEncoder.encode(pass, charset)); 
      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } 

      try { 

       String url="http://192.168.0.122:1234/YegoService.svc/AddVehicleMovement"; 
       URL object=new URL(url); 

       HttpURLConnection con = (HttpURLConnection) object.openConnection(); 
       con.setDoOutput(true); 
       con.setDoInput(true); 
       con.setRequestProperty("Content-Type", "application/json"); 
       con.setRequestProperty("Accept", "application/json"); 
       con.setRequestMethod("POST"); 

       JSONObject parent = new JSONObject(); 

       parent.put("strValidatorID","111"); 
       parent.put("TXT_LAT", "28.25252525"); 

       parent.put("TXT_LONG", "77.7777777"); 
       parent.put("DAT_DATE", ""); 
       con.connect(); 

       OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream()); 
       wr.write(parent.toString()); 
       wr.flush(); 
       wr.close(); 

       InputStream input = con.getInputStream(); 
       BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 
       String line; 

       while ((line = reader.readLine()) != null) { 
        result.append(line); 
       } 

       con.disconnect(); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      catch (Exception ex) { 
       ex.printStackTrace(); 
      } 

      return result.toString(); 
     } 

     @Override 
     protected void onPostExecute(String result){ 
      String s = result.trim(); 
     } 
    } 

    LoginAsync la = new LoginAsync(); 
    la.execute("admin", "admin"); 

} 

} 

public class AlarmReceiver extends BroadcastReceiver { 
String strLatitude; 
String strLongitude; 

@Override 
public void onReceive(Context context, Intent intent) { 
    Intent background = new Intent(context, BackgroundService.class); 
    context.startService(background); 
} 
} 

Co robić?

+0

Czy testowane na innym urządzeniu? Czy o/p będzie takie samo? –

+0

Testowany na innym urządzeniu, z tym samym wynikiem !!! –

+0

Czy używasz częściowego wakeloku? – ozo

Odpowiedz

4

Kupujesz blokadę wybudzania w swojej Activity. Problem polega na tym, że kiedy urządzenie jest zablokowane, twój telefon Activity zostaje wypchnięty na drugi plan. Po 15 minutach bezczynności Android po prostu zabija ten proces. To zwalnia blokadę wybudzania. Urządzenie przechodzi w stan uśpienia.

Teraz następnym razem alarm, urządzenie budzi się, twój BroadcastReceiver jest wyzwalany, onReceive() nazywa, zaczyna swój Service, ale to urządzenie wraca do snu, ponieważ nie ma blokady obudzić, więc `Usługa nic nie robi.


Innym podejściem, jeśli chcesz, aby zapobiec telefon przed pójściem spać, gdy aplikacja jest uruchomiona, będzie nabyć blokadę budzić się Service. W takim przypadku nie chcesz dzwonić pod numer stopSelf() za każdym razem, gdy uruchamia się Runnable. Będziesz chciał, aby Twój Service działał, dopóki nie chcesz go zatrzymać, kiedy to zadzwonisz stopService(). W ten sposób Service będzie zawsze aktywny (nawet jeśli nic nie robi) i zapobiegnie przesypianiu urządzenia przez blokadę wybudzania. Może to jednak spowodować niedopuszczalne zużycie baterii (będziesz musiał ją przetestować).

Musisz zdobyć blokadę wybudzania w BroadcastReceiver i upewnić się, że Service zostanie uruchomiony i uzyska blokadę wybudzania zanim urządzenie przejdzie w stan uśpienia. Zajrzyj na stronę WakefulBroadcastReceiver, której możesz użyć do zaimplementowania tego zachowania.

+0

Próbowałem użyć twojego podejścia. ale nadal nie działa dla mnie. Wciąż jestem początkującym w aplikacjach na Androida. Czy możesz podać mi przykładowy kod demonstrujący telefon komórkowy nigdy nie idzie spać. Byłoby to bardzo doceniane. –

4

Jednym podejściem może być poleganie na AlarmManager: po zasubskrybowaniu programu AlarmManager system sam uruchamia kod w ustawionym interwale, nawet jeśli aplikacja nie jest aktywna. Za każdym razem, gdy działa, możesz zdecydować się na przetworzenie kodu ... Więc całkowicie unikasz konieczności utrzymywania usługi przy życiu.

Potrzebna jest klasa Alarm, która obsłuży zamiar AlarmManagera.


Tworzenie systemu alarmowego:

public class Alarm extends BroadcastReceiver 
{ 

    private static final String TAG = "Alarm"; 

    @Override 
    public void onReceive(Context context, Intent intent) 
    { 
     PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
     PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ""); 
     wl.acquire(); 

     /*************** 
     Here you can do your stuff... 
     This will be triggered every second. 
     Send data from here, or better: call an IntentService 
     that will take care of it. 
     ****************/ 

     wl.release(); 
    } 

    public void SetAlarm(Context context) 
    { 
     Intent i = new Intent(context, Alarm.class); 

     boolean alarmUp = (PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_NO_CREATE) != null); 

     if (alarmUp) 
     { 
      // The alarm is already running, do not set it twice 
     } 
     else 
     { 
      AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
      PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0); 
      am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, pi); // 1000 Millisec means it will trigger it every second... and RTC_WAKEUP means that it will wake up your device if needed. 
     } 
    } 

    // later on, use this method if you want to manually cancel the AlarmManager : 

    public void CancelAlarm(Context context) 
    { 
     Intent intent = new Intent(context, Alarm.class); 
     PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0); 
     AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     alarmManager.cancel(sender); 
    } 
} 

W swoim manifeście zadeklarować ten Alarm BroadcastReceiver

<receiver 
    android:name=".utils.Alarm" 
    android:process=":remote" > 
</receiver> 

A skąd chcesz w wywołaniu Działalność Ten AlarmManager!

Alarm alarm = new Alarm(); 

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 

    alarm.SetAlarm(this); 

} 

// or if elsewhere you need to stop the Alarm : 
alarm.CancelAlarm(this); 

To jest główna idea. Teraz musisz włączyć lub wyłączyć ekran. Dla tego 2 rozwiązania: możesz zarejestrować się w celu zachowania stanu ekranu urządzenia i zarządzać lub włączać AlarmManager ... lub możesz pozwolić, aby AlarmManager zawsze działał, ale sprawdzając, czy urządzenie jest włączone/wyłączone przed wysłaniem danych ...

Mam nadzieję, że to pomoże!

1

Tak, możesz uruchomić dowolną usługę, nawet jeśli urządzenie jest zablokowane. Nawet, możesz wznowić usługę po ponownym uruchomieniu urządzenia.

Można zaimplementować Menedżera sieci GCM.

Przykładowy kod wymagane: -

<service 
    android:name=".MyTaskService" 
    android:exported="true" 
    android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"> 
    <intent-filter> 
     <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" /> 
    </intent-filter> 
</service> 

kod Java: -

mGcmNetworkManager = GcmNetworkManager.getInstance(this); 
OneoffTask task = new OneoffTask.Builder() 
     .setService(MyTaskService.class) 
     .setTag(TASK_TAG_WIFI) 
     .setExecutionWindow(0L, 3600L) 
     .setRequiredNetwork(Task.NETWORK_STATE_UNMETERED) 
     .build(); 

mGcmNetworkManager.schedule(task); 

Fore Więcej informacji można znaleźć https://developers.google.com/cloud-messaging/network-manager#run_tasks i czytać dokumenty.

Trzeba tylko uwzględnić usługi gcm w projekcie, aby użyć menedżera sieci GCM. Obsługa 4.0 +

Proszę przyjąć tę odpowiedź, jeśli jest to rozwiązanie, które chcesz. Może to również pomóc innym programistom.

1

Tak, możesz wdrożyć usługę w tle, która prawie nigdy nie zostanie zabita. Ale musisz zadeklarować, aby działał na pierwszym planie. możesz zobaczyć, co mówi witryna dla programistów Androida, odwołując się do tego adresu URL (http://developer.android.com/guide/components/services.html) w tym artykule (http://developer.android.com/guide/components/processes-and-threads.html), jak mówią,

Istnieje pięć poziomów w hierarchii ważności i różnych typów procesów według ich ważności (pierwszy proces jest najważniejszy i ginie ostatnia):

  1. proces Planie:

proces, który jest wymagany do tego, co użytkownik jest aktualnie robi. Sposób jest uznawany za pierwszym planie, jeśli dowolny z następujących warunków:

  • to odbywa się działanie, że użytkownik oddziaływuje z (metoda onResume w Activity'S() została wywołana).
  • Zawiera usługę związaną z działaniem, z którym użytkownik korzysta.
  • Jest hostem usługi, która działa "na pierwszym planie" - usługa nazywa się startForeground().
  • Zawiera usługę wykonującą jeden z wywołań cyklu życia (onCreate(), onStart() lub onDestroy()).
  • Jest hostem BroadcastReceiver, który wykonuje swoją metodę onReceive() .

Zasadniczo w danym czasie istnieje tylko kilka procesów pierwszoplanowych.Są zabijani tylko w ostateczności - jeśli pamięć jest tak niska, że ​​nie wszyscy mogą dalej działać. Ogólnie rzecz biorąc, w tym momencie urządzenie osiągnęło stan stronicowania pamięci, więc zabijanie niektórych procesów na pierwszym planie jest wymagane, aby zachować responsywność interfejsu użytkownika.

Musisz więc rozpocząć służbę na pierwszym planie. W tym celu wdrożysz usługę jak poniżej.

public class MyForegroundService extends Service { 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     //your code goes here 
    } 

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

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     keepServiceAlive(); 
     //your code goes here 
     return(START_NOT_STICKY); 
    } 

    private void keepServiceAlive() { 
     Intent notificationIntent = new Intent(this, MainActivity.class); 
     PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 

     Notification notification = new NotificationCompat.Builder(this).setContentTitle(getString(R.string.app_name)) 
       .setContentText("Hello") 
       .setSmallIcon(R.mipmap.ic_launcher) 
       .setContentIntent(pendingIntent) 
       .build(); 
     startForeground(Notification.FLAG_ONGOING_EVENT, notification); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.w(getClass().getName(), "Got to stop()!"); 
     stopForeground(true); 
    } 
} 

Dzięki i powodzenia gud ..

+0

Chcesz uruchomić usługę w głównym wątku aplikacji, na pierwszym planie i nazywasz ją prawie nigdy nie zabity? Usługa nie powinna być uruchamiana w głównym wątku, jeśli nie ma ona zakończyć całego dnia. A jeśli usługa pierwszego planu jest związana z cyklem życia (wątku), w którym działa, zostanie zabity, gdy tylko działanie zostanie zniszczone. –

+0

@JemshitIskenderov Ustanowienie usługi w stanie pierwszego planu, gdzie system uważa, że ​​jest to coś, o czym użytkownik jest aktywnie świadomy (jak również wspomniałem w odpowiedzi "Oni są zabijani tylko w ostateczności"). Pls czyta sekcję Podstawy z tego http://developer.android.com/guide/components/services.html#Basics (tam zobaczysz, wspomnieli "jeśli usługa zostanie zadeklarowana do uruchomienia na pierwszym planie, wtedy będzie prawie nigdy nie daj się zabić ") i przeczytaj sekcję poświęconą cyklowi życia procesu z tego http://developer.android.com/guide/components/processes-and-threads.html), aby uzyskać więcej informacji. – TdSoft

+0

Nawet w tym przypadku serwis zostanie zabity po 15 minutach. –

1

Miałem ten sam problem w mojej aplikacji, ale i rozwiązać mój problem najpierw stworzyć usługę, należy użyć okresowa obsługa. jesteś w stanie określić termin aktualizacji danych. W moim przypadku był to kod.

UpdateService.java

public class UpdateServices extends Service implements LocationListener { 

    String id, latee, longee; 
    // j 
    private ProgressDialog pDialog; 
    ProgressDialog progressDialog; 
    JSONParser jsonParser = new JSONParser(); 
    DBManager db; 
    private static String url_create_locationupdate = "http://192.168.0.175/simple_demo3/classes/create_locationupdate.php"; 
    private static final String TAG_SUCCESS = "success"; 
    public static String LOG = "Log"; 
    private final Context mContext; 
    boolean isGPSEnabled = false; 
    boolean isNetworkEnabled = false; 
    boolean canGetLocation = false; 
    Location location; // location 
    double latitude; // latitude 
    double longitude; // longitude 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 3; // 0 meters 
    private long MIN_TIME_BW_UPDATES; // 10 second 
    private long MIN_LENGTH_BW_UPDATES; 
    SharedPreferences mPref; 
    protected LocationManager locationManager; 

    public UpdateServices(Context context) { 
     this.mContext = context; 
    } 

    public UpdateServices() { 
     super(); 
     mContext = UpdateServices.this; 
    } 

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

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); 
     Log.i(LOG, "Service started"); 

     mPref = getSharedPreferences("mFile", 0); 
     MIN_TIME_BW_UPDATES = mPref.getLong("mint", 1) * 1000 * 60; 
     MIN_LENGTH_BW_UPDATES = mPref.getLong("kmeter", 1) * 1000; 
     Log.i("asd", "This is sparta"); 
     latitude = getLocation().getLatitude(); 
     longitude = getLocation().getLongitude(); 

     return START_STICKY; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     Log.i(LOG, "Service created"); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Log.i(LOG, "Service destroyed"); 

    } 

    public Location getLocation() { 
     try { 
      locationManager = (LocationManager) mContext 
        .getSystemService(LOCATION_SERVICE); 

      isGPSEnabled = locationManager 
        .isProviderEnabled(LocationManager.GPS_PROVIDER); 
      isNetworkEnabled = locationManager 
        .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      if (!isGPSEnabled && !isNetworkEnabled) { 
      } else { 
       this.canGetLocation = true; 
       if (isNetworkEnabled) { 
        locationManager.requestLocationUpdates(
          LocationManager.NETWORK_PROVIDER, 5000, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("Network", "Network"); 
        if (locationManager != null) { 
         location = locationManager 
           .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (location != null) { 
          latitude = location.getLatitude(); 
          longitude = location.getLongitude(); 
         } 
        } 
       } 
       // if GPS Enabled get lat/long using GPS Services 
       if (isGPSEnabled) { 
        if (location == null) { 
         locationManager.requestLocationUpdates(
           LocationManager.GPS_PROVIDER, 
           MIN_TIME_BW_UPDATES, 
           MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
         Log.d("GPS Enabled", "GPS Enabled"); 
         if (locationManager != null) { 
          location = locationManager 
            .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
          if (location != null) { 
           latitude = location.getLatitude(); 
           longitude = location.getLongitude(); 
          } 
         } 
        } 
       } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return location; 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     // this will be called every second 
     String laty = Double.toString(getLocation().getLatitude()); 
     String lagy = Double.toString(getLocation().getLongitude()); 
     db = new DBManager(mContext); 
     db.open(); 
     db.mInsertGPSCor(laty, lagy); 
     Toast.makeText(
       getApplicationContext(), 
       "Your Location is - \nLat: " + location.getLatitude() 
         + "\nLong: " + location.getLongitude(), 
       Toast.LENGTH_LONG).show(); 

     Toast.makeText(UpdateServices.this, "record entered", 
       Toast.LENGTH_SHORT).show(); 
     db.close(); 
// store in server 
     new CreateNewProduct(this).execute(); 

    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 

    } 

    @Override 
    public void onProviderEnabled(String provider) { 

    } 

    @Override 
    public void onProviderDisabled(String provider) { 

    } 

    class CreateNewProduct extends AsyncTask<String, String, String> { 
     private Context mContext; 

     public CreateNewProduct(Context context) { 
      super(); 
      mContext = context; 
     } 

     @Override 
     protected void onPreExecute() { 
      try { 
       super.onPreExecute(); 
       progressDialog = ProgressDialog.show(mContext, 
         "Press Back to Cancel", "Sending Data to Server..", 
         true, false); 
      } catch (Exception e) { 
       // TODO: handle exception 
      } 

     } 

     /** 
     * Creating product 
     * */ 
     protected String doInBackground(String... args) { 
      List<NameValuePair> params = new ArrayList<NameValuePair>(); 
      params.add(new BasicNameValuePair("ID", id)); 
      params.add(new BasicNameValuePair("LATITUDE", latee)); 
      params.add(new BasicNameValuePair("LONGITUDE", longee)); 

      JSONObject json = jsonParser.makeHttpRequest(
        url_create_locationupdate, "POST", params); 

      try { 
       int success = json.getInt(TAG_SUCCESS); 

       if (success == 1) { 

        return "done"; 
       } else { 
        // failed to create product 
        return "fail"; 
       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
       return "exec"; 
      } 

     } 

     /** 
     * After completing background task Dismiss the progress dialog 
     * **/ 
     protected void onPostExecute(String file_url) { 
      if (progressDialog.isShowing()) 
       progressDialog.dismiss(); 

      if (file_url.equalsIgnoreCase("done")) { 

       show.message(mContext, "uploading successed"); 
      } 
      if (file_url.equalsIgnoreCase("fail") 
        || file_url.equalsIgnoreCase("exec")) { 
       try { 
        show.message(mContext, "uploading failed"); 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

    public void onConnectionSuspended(int arg0) { 
     // TODO Auto-generated method stub 

    } 

} 

i Main.java

public class Main extends Activity { 

    Button btn_startGps, btn_stopGps; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.auto_gps_update); 
     btn_startGps = (Button) findViewById(R.id.button_service); 
     btn_stopGps = (Button) findViewById(R.id.button_stopservice); 


     btn_startGps.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) {   
       startService(new Intent(About.this, UpdateServices.class)); 
       Toast.makeText(About.this, "Service Started", 
         Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     btn_stopGps.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       stopService(new Intent(About.this, UpdateServices.class)); 
      Log.e("sss", "ddddd"); 
       Toast.makeText(About.this, "Service Stopped", 
         Toast.LENGTH_SHORT).show(); 

      } 
     }); 
} 

ale tutaj usługa problem nie jest tu zatrzymać, aby zatrzymać usługę

bo mam return

return START_STICKY; 

w onStartCommand(...)

Czytaj więcej na START_STICKY and START_NOT_STICKY

i Official docs

1

Jeśli uruchomić aplikację na API 21+ korzystając JobScheduler który jest opisany w dokumentacji Google jest także najlepszym rozwiązaniem.

Ponadto, jeśli nie chcesz zmieniać struktury kodu, możesz skorzystać z usługi, aby utrzymać procesor nawet jeśli ekran jest wyłączony. Przeczytaj, jak to keep CPU On z Dokumentacji Google. Wystarczy dodać uprawnienia w swoim manifeście <uses-permission android:name="android.permission.WAKE_LOCK" /> iw swoim Service.onCreate, umieścić:

PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); 
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 
     "MyWakelockTag"); 
wakeLock.acquire(); 

i zwolnić w Service.onDestroy z wakelock.release(). Należy jednak pamiętać, że bateria wyczerpuje się. Ale jeśli powiesz, że urządzenie będzie zawsze podłączone do źródła zasilania, myślę, że to nie będzie problem. Na wszelki wypadek lepiej będzie mieć interfejs administratora w aplikacji, aby ręcznie zatrzymać usługę.

1
In Manifest file, 
<service android:name=".MyService"></service> 

MyService.java

public class MyService extends Service { 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     // your code here 
    } 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     return START_STICKY; 
    } 
    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     Intent it = new Intent(MyService.this, MyService.class); 
     getApplication().startService(it); // If service will destroy, Start the service again 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 


} 

uruchomić usługę, dodać do swojej działalności,

Intent it = new Intent(getApplication(), MyService.class); 
getApplicationContext().startService(it);