Travaux Pratiques

tp8 IntentService

Thème: Déclenchement d'un service

Question 1)

Question1.1) Proposez une activité permettant de déclencher en tâche de fond l'affichage d'un Toast dans le futur... A chaque clic, un service est exécuté, à ce service lui est transmis un nombre de secondes indiquant le délai attendu pour l'affichage effectif du Toast.

Ci-dessous un exemple possible d'interface, l'unité est ici en secondes

Après avoir cliqué, le service est créé, le délai est transmis, le toast est affiché au délai écoulé

Notes sur l'implémentation demandée: 

public class DelayedToastIntentService extends IntentService {
protected void onHandleIntent(Intent intent) { // rappel: cette méthode est exécutée dans un autre thread que main
    final int period =intent.getIntExtra("period",10);
    SystemClock.sleep(period*1000);
...
Vérifiez que le toast s'affiche même après avoir quitté l'activité...

Question 1.2)  Le service est maintenant placé sur un autre processus, un attribut android:process répond à cette fonctionnalité, il vous suffit de modifier le fichier  AndroidManifest.xml comme suit :

<service
    android:name=".DelayedToastIntentService"
    android:exported="false"
    android:process=":delayed_toast">
</service>

        Vérifier que tout fonctionne correctement, qu'il n'y a qu'un thread chargé de l'affichage (l'UIThread).

 

Question 2)  L'affichage du Toast mentionnant le délai écoulé est maintenant effectué dans l'activité, un "messager" assure la communication avec le service, celui-ci contient un handler permettant de réceptionner un message et le délai d'attente dans l'activité.

http://developer.android.com/reference/android/os/Messenger.html

Un exemple de Handler au sein de l'activité pourrait être :

private Handler handler = new Handler() {
    public void handleMessage(Message message) {
        Bundle extras = message.getData();
        if (extras != null) {
            int period = extras.getInt("delai",-1);
            Toast.makeText(MainActivity.this,"messenger: délai écoulé " + delai, Toast.LENGTH_LONG).show();
        }
    };
};

Proposez une nouvelle version de votre application avec une instance de la classe Messenger transmise au service, et avec au retour, un message contenant le délai attendu, message, qui a sa réception engendre l'affichage du Toast dans l'activité.

 

Question 3)  Le service engendre une fenêtre d'alerte lorsque le délai souhaitée dépasse trente secondes, i.e. au bout de trente secondes une alerte est affichée sur l'écran de l'utilisateur, même si l'activité initiatrice n'existe plus...

protected void onHandleIntent(Intent intent) { //
   

    final int period =intent.getIntExtra("period",10);
    SystemClock.sleep(Math.min(TRENTE_SECONDES,period)*1000);
    if(period>TRENTE_SECONDES)
// Déclencher une alerte sur l'écran de votre votre mobile
   

  C'est une activité fournie ci-dessous (cf AlertDialogActivity), qui est en charge de l'affichage de l'alerte (en rappel aucun affichage n'est possible dans un service...), proposez une solution pour cette nouvelle fonctionnalité.

Source de l'activité extrait de http://stackoverflow.com/questions/2176922/how-to-create-transparent-activity-in-android

public class AlertDialogActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        final int period = intent.getIntExtra("period", -1);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

        alertDialogBuilder
                .setTitle("Alerte en question 3 du tp8/SMB116" )
                .setMessage("votre délai excède 30 secondes (" + period + ") sec.)")
                .setCancelable(false)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        AlertDialogActivity.this.finish();
                    }
                });
        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();
    }
Cette ligne est ajoutée à votre AndroiManifest.xml
<activity android:name=".AlertDialogActivity" android:theme="@style/Theme.Transparent"/>
Ce style est inclus dans le fichier values/styles.xml
<style name="Theme.Transparent" parent="android:Theme">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:backgroundDimEnabled">false</item>
</style>