Przygotowane według tutoriala z:
http://frogermcs.blogspot.com/2010/09/usugi-dziaajace-w-tle-wstep-do-android.html
Usługi Androida są inne niż usługi Windows. Nie działają w osobnym wątku lub procesie,
a w głównym wątku aplikacji. Ale podobnie, jak usługi Windows nie mogą mieć interfejsu.
Usługa nie jest zamykana przez system (nawet jeżeli aktywność aplikacji zostanie usunięta),
chyba że nie ma innego sposobu na uruchomienie nowej aktywności. Jest przywracana, gdy są
już zasoby (pamięć) niezbędne do jej działania.
1. Tworzymy projekt aplikacji Android o nazwie Uslugi z Empty Activity
2. Interfejs aktywności (dwa przyciski, zegar tylko dla ozdoby):
3. W pliku MainActivity.java definiujemy zmienne dla przycisków i przygotowujemy ich
nasłuchiwacze.
package pl.umk.fizyka.uslugi;
public class MainActivity extends Activity
{
private Button button1,button2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1=(Button)findViewById(R.id.button1);
button2=(Button)findViewById(R.id.button2);
button1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), "Uruchamiam usługę", Toast.LENGTH_SHORT).show();
}
});
button2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), "Zatrzymuję usługę", Toast.LENGTH_SHORT).show();
}
});
}
}
4. Do projektu (do bieżącego pakietu) dodajemy plik Java Class.
Nazwa: Usluga, Superclass: android.app.Service,
Zaznaczamy "Show Select Overrides Dialog"
OK. Zaznaczamy metody do nadpisania: onCreate, onStartCommand, onDestroy i onBind (tej ostatniej nie będziemy jej używać)
5. Wracamy do pliku MainActivity.java i dodajemy polecenia uruchamiające i zatrzymujące
usługę (odpowiednio do metod OnClick obu nasłuchiwaczy).
a. Do pierwszego nasłuchiwacza:
button1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), "Uruchamiam usługę", Toast.LENGTH_SHORT).show();
startService(new Intent(MainActivity.this, Usluga.class));
}
});
b. Do drugiego nasłuchiwacza:
button2.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(getApplicationContext(), "Zatrzymuję usługę", Toast.LENGTH_SHORT).show();
stopService(new Intent(MainActivity.this, Usluga.class));
}
});
Próba uruchomienia usługi, która jest już uruchomiona nie zaszkodzi.
6. Przechodzimy do pliku Usluga.java.
Usługa posiada metody onCreate, onStart i onDestroy.
W pierwszej utworzymy timer, który będzie odpowiedzialny za wyświetlanie toastu informującego
o działaniu usługi.
Uwaga: wyświetlanie toastu w zadaniu timera wymaga utworzenia toastu poza timerem i tylko
jego aktualizację.
public class Usluga extends Service
{
Timer timer;
Toast toastDlaTimera;
@Override
public void onCreate()
{
super.onCreate();
timer=new Timer();
toastDlaTimera=Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT);
timer.scheduleAtFixedRate(
new TimerTask()
{
@Override
public void run()
{
//String czas = DateFormat.getDateInstance().format(Calendar.getInstance().getTime());
//Toast.makeText(getApplicationContext(), "Usluga: "+czas, Toast.LENGTH_SHORT).show();
//wątki (inne niż UI thread) nie mogą dotykać widoku (w tym toast)
//UWAGA! Ten problem będzie omawiany w następnej lekcji
ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);
};
},
1000, 2000); //co 1000 ms
Toast.makeText(getApplicationContext(), "Usługa utworzona", Toast.LENGTH_SHORT).show();
};
@Override
public void onDestroy()
{
timer.cancel();
Toast.makeText(getApplicationContext(), "Usługa zatrzymana", Toast.LENGTH_SHORT).show();
super.onDestroy();
};
@Override
//public int onStartCommand(Intent intent, @IntDef(value = {Service.START_FLAG_REDELIVERY, Service.START_FLAG_RETRY}, flag = true) int flags, int startId)
public int onStartCommand(Intent intent, int flags, int startId)
{
Toast.makeText(getApplicationContext(), "Usługa uruchomiona", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent)
{
return null;
}
7. Na koniec, aby uruchomienie usługi było możliwe, musimy do manifestu dodać deklarację usługi:
Usługa będzie wyświetlać komunikaty nawet po zamknięciu aplikacji (klawisze telefonu Home lub Wstecz).
8. Aby sprawdzić, czy usługa działa w tle, zdefiniujmy w klasie Usluga statyczne pole ze
statycznym getterem:
private static boolean uruchomiona = false;
public static boolean czyUruchomiona()
{
return uruchomiona;
}
@Override
public void onCreate()
{
...
uruchomiona=true;
};
@Override
public void onDestroy()
{
...
uruchomiona=false;
};
Użyjmy tej metody w aktywności, aby informować użytkownika, czy kliknięcie przycisku zmieniło
stan usługi:
button1.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if(!Usluga.czyUruchomiona())
{
Toast.makeText(getApplicationContext(), "Uruchamiam usługę", Toast.LENGTH_SHORT).show();
startService(new Intent(MainActivity.this, Usluga.class));
}
else Toast.makeText(getApplicationContext(), "Usługa jest już uruchomiona", Toast.LENGTH_SHORT).show();
}
});
button2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if(Usluga.czyUruchomiona())
{
Toast.makeText(getApplicationContext(), "Zatrzymuję usługę", Toast.LENGTH_SHORT).show();
stopService(new Intent(MainActivity.this, Usluga.class));
}
else Toast.makeText(getApplicationContext(), "Usługa jest już zatrzymana", Toast.LENGTH_SHORT).show();
}
});