* R AMAN K AZHAMIAKIN O SCAR Z G IOVANNI D E ITT M. B UONARROTI, T RENTO A NDROID D EVELOPMENT S ERVIZI E N OTIFICHE
* * 1.Servizi a. started b. bound 2.Notifiche Sommario
* * Cos’è un Service (servizio)? ●È un componente di un’app che può fare operazioni ad esecuzione continua in background. Non fornisce un’interfaccia utente. ●Un diverso componente dell’app può: ○far partire un servizio che continuerà a girare in background anche se l’utente passa ad un’altra applicazione ○può legarsi ad un servizio, interagire con esso e svolgere operazioni. Esempi: un servizio può gestire le reti, suonare musica, leggere e scrivere files, interagire con content provider, il tutto in background.
* * Servizio started Un servizio è started quando il componente di un’app (come una activity) lo fa partire usando il metodo startService(). Una volta avviato un servizio è eseguito in background in maniera continua, anche se il componente che l’ha avviato viene distrutto. Solitamente un servizio started esegue un’operazione e non restituisce un risultato a chi l’ha avviato. Quando l’operazione è completa il servizio dovrebbe fermarsi da solo. Ad esempio potrebbe scaricare o caricare un file in rete.
* * Un servizio è bound quando componente di un’app si lega a esso usando il metodo bindService(). Un servizio bound offre un’interfaccia client-server che permette ai componenti di interagire con il servizio, mandare richieste, e ottenere risultati. Un servizio bound è eseguito solo quando il componente di un’altra app è legato ad esso. Più componenti possono legarsi al servizio contemporaneamente. Quando tutti i componenti sono slegati il servizio viene distrutto. Servizio bound
* * Un servizio può essere sia started che bound! Un servizio è eseguito nel main thread dell’app in cui è definito, non crea un proprio thread e non gira in un processo separato, a meno che lo sviluppatore non lo faccia manualmente. Questo significa che se il servizio userà molta CPU o farà operazioni bloccanti sarebbe meglio creare un nuovo thread dove farlo eseguire. Questo riduce il rischio di Application Not Responding (ANR,, “L’applicazione non risponde”) mentre il main thread dell’app rimane dedicato all’interazione con l’utente. Servizio: attenzione!
* * Bisogna creare una sottoclasse di Service (o di una delle esistenti sottoclassi). Nell’implementazione bisogna fare override di alcuni metodi che gestiscono il ciclo di vita del servizio e forniscono ai componenti delle app un meccanismo per fare bound, se necessario. onStartCommand() Il sistema chiama questo metodo quando un componente dell’app richiede che il servizio venga attivato, usando il metodo startService(). Quando viene eseguito il servizio gira in background all’infinito. È responsabilità dello sviluppatore fermare il servizio quando ha svolto il suo compito con i metodi stopSelf() o stopService(). (Volendo fare solo bound non è necessario implementare questo metodo.) Creazione di un servizio
* * Creazione di un servizio #2 onBind() Il sistema chiama questo metodo quando un altro componente vuole fare bound con questo servizio chiamando il metodo bindService(). Nell’implementazione di questo metodo lo sviluppatore deve fornire un’interfaccia che i client possono usare per comunicare con il servizio, restituendo l’implementazione di un IBinder. Questo metodo va sempre implementato ma se non si vuole permettere il binding basta restituire null.
* * Creazione di un servizio #3 onCreate() Il sistema chiama questo metodo quando il servizio viene creato, per fare eventuali operazioni di configurazione, prima sia di onStartCommand() che di onBind(). Se il servizio è già in esecuzione il metodo non viene chiamato. onDestroy() Il sistema chiama questo metodo quando il servizio non è più usato e viene distrutto. Lo sviluppatore dovrebbe implementare questo metodo per far pulizia di eventuali risorse come thread, listeners, receivers, etc. Questo è l’ultimo metodo chiamato dal servizio.
* * Creazione di un servizio #4 Aggiungere il servizio al manifest Modificare il file AndroidManifest.xml e aggiungere la dichiarazione del service all’elemento
* * Creazione di un servizio #5 public class MyService extends Service public int onStartCommand(Intent intent, int flags, int startId) { // TODO do something useful return Service.START_NOT_STICKY; public IBinder onBind(Intent intent) { // TODO for communication return IBinder implementation return null; } }
* * Creazione di un servizio #6 Nel metodo onStartCommand() il servizio restituisce un int che definisce il comportamento di riavvio del servizio stesso nel caso sia terminato da Android. Si possono usare queste costanti: Service.START_STICKY: il servizio è riavviato se viene terminato. I dati che passati al metodo onStartCommand sono null. Si usa con servizi che gestiscono il proprio stato e che non dipendono dagli Intent data. Service.START_NOT_STICKY: il servizio non viene riavviato. Si usa per servizi che vengono in ogni caso richiamati in altri modi. Il servizio viene riavviato solo se ci sono chiamate startService() pendenti da prima della sua terminazione. Service.START_REDELIVER_INTENT: similmente a Service.START_STICKY ma l’Intent originale viene rispedito al metodo onStartCommand.
* * Uso di un servizio Intent i= new Intent(context, MyService.class); // è possibile aggiungere dati all’intent i.putExtra("chiave", "valore passato"); context.startService(i); È possibile fermare un servizio con il metodo stopService(). Non importa quanto frequentemente si chiama startService(intent), basta una chiamata a stopService() per fermare il servizio. Un servizio può terminare sé stesso usando il metodo stopSelf(). Questo è solitamente utilizzato quando un servizio finisce di fare ciò per cui è stato lanciato. Come si lancia un servizio? Con un Intent!
* * Uso di un servizio #2 Se una activity vuole interagire direttamente con il servizio può usare il metodo bindService() per farlo partire. Questo metodo richiede un oggetto ServiceConnection come parametro. Questo oggetto viene utilizzato dal servizio in fase di start e in fase di finish del metodo onBind(). Viene restituito un oggetto IBinder che può essere usato dall’activity per comunicare con il servizio. Quando il processo di binding finisce viene chiamato il metodo onStartCommand() con l’oggetto intent che era stato passato al metodo bindService(). Per slegarsi dal servizio si usa il metodo unbindService().
* * Communicare con servizio Ci sono diversi metodi: facendo binding locale del servizio. Si usa quando il servizio si accede dalla stessa app. facendo binding remoto del servizio: Si usa quando il servizio si accede anche dalle altre app. Usare AIDL per specificare l’interfaccia. utilizzando Messenger per mandare/ricevere messaggi al servizio. Anche in questo caso dai processi remoti ma senza implementare AIDL. utilizzando mezzi infrastrutturali del sistema/applicazione: DB o broadcast. Si usa in casi semplici.
* * Communicare con servizio: binding locale #1 Definire binder: public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } private final IBinder mBinder = new public IBinder onBind(Intent intent) { return mBinder; }
* * Communicare con servizio: binding locale #2 Definire client: private LocalService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName cName, IBinder service) { mBoundService = ((LocalService.LocalBinder)service).getService(); … // qui si utilizza il servizio } public void onServiceDisconnected(ComponentName className) {... } } … // si connette al servizio bindService(new Intent(this, LocalService.class), mConnection, Context.BIND_AUTO_CREATE);
* * Notifiche Una notifica è un messaggio che può essere mostrato all’utente al di fuori della normale interfaccia dell’app. Quando si dice al sistema di mostrare una notifica questa prima di tutto appare come icona nella notification area. Per vedere i dettagli della notifica l’utente apre il notification drawer. Sia la notification area che il notification drawer sono aree controllate dal sistema che l’utente può consultare quando vuole.
* * Notifiche #2 Per creare una notifica si usa la classe NotificationManager che si può ottenere dal Context tramite il metodo getSystemService(). NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Il Notification.Builder fornisce una interfaccia per creare un oggetto Notification. Poi si usa un PendingIntent per specificare l’azione che verrà eseguita una volta selezionata la notifica. Il Notification.Builder permette di aggiungere fino a tre bottoni con azioni da definire per ogni notifica.
* * Notifiche #3 // prepariamo l’Intent che verrà lanciato // quando verrà selezionata la notifica Intent intent = new Intent(this, NotificationReceiver.class); PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0); // costruiamo la notifica Notification n = new NotificationCompat.Builder(this).setContentTitle("New mail!").setContentText("Subject").setSmallIcon(R.drawable.icon).setContentIntent(pIntent).setAutoCancel(true).addAction(R.drawable.icon, "Call", pIntent).addAction(R.drawable.icon, "More", pIntent).addAction(R.drawable.icon, "And more", pIntent).build(); NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); notificationManager.notify(0, n);