IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriel Android : Apprendre à utiliser les Intent pour la communication des briques applicatives

Chapitre 3.3
Image non disponible
Android2ee

Ce chapitre vous explique la notion d'Intent qui vous permet de lier et de faire communiquer vos briques applicatives (Activity, Service, BroadCastReceiver…) entre elles et avec celles du système. C'est un objet essentiel de la programmation Android.

Pour réagir à ce tutoriel, un espace de dialogue vous est proposé sur le forum : Commentez Donner une note à l´article (5)

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Filtres d'intentions

I-A. Objectif des intentions et bonne pratique

Les applications Android doivent se décomposer en activités distinctes les unes des autres. Au sein de ces applications, les activités doivent pouvoir s'enchaîner, s'appeler, retourner à leur activité principale. Pour mettre en place cette communication entre activités, Android utilise le système des intentions. Celles-ci permettent d'envoyer des messages d'une activité vers une autre avec des données pour les activer.

Dans ce contexte, il faut se demander si l'activité mère, quand elle lance une autre activité, est dans une relation maître-esclave ou dans une relation de pair à pair.

Dans le premier cas, l'activité mère attend que l'activité fille finisse et est informée de cette fin. Dans l'autre cas, l'activité fille est lancée, l'activité mère n'a plus de contact avec elle.

I-B. Définition

Une intention peut se traduire par « je veux, toi système, que tu fasses… ». Et cela dépend de l'action demandée et du contexte. Il faut les considérer comme de la colle entre activités permettant de les lier les unes aux autres.

Une intention est ainsi une action associée à des données. Les actions sont des constantes : ACTION_VIEW, ACTION_EDIT, ACTION_PICK, les données sont des URI.

Les intentions peuvent se spécifier ; on peut leur rajouter des informations :

  • Une catégorie : LAUNCHER (pour les activités présentes dans le lanceur Android), DEFAULT ou ALTERNATIVE.
  • Un type MIME : indique le type de la ressource (comme pour les mails).
  • Un composant : indique la classe d'activité censée recevoir l'intention. Cette méthode n'est pas la plus heureuse, car elle fige l'activité associée. Soit vous l'avez codée vous-même, dans ce cas, c'est naturel, sinon, l'utilisation des autres paramètres est préconisée.
  • Des « extras » : un bundle d'informations permettant de transférer des données à l'activité cible.

I-C. Routage des intentions

Il est préférable d'utiliser les URI et le type MIME, plutôt que Composant si vous souhaitez dialoguer avec une application qui n'est pas la vôtre. En d'autres termes, laissez Android se charger de trouver l'activité cible.

Pour qu'une activité soit éligible au routage d'une intention, il faut qu'elle supporte :

  • l'action indiquée ;
  • le type MIME indiqué ;
  • ainsi que la catégorie.

Il faut donc spécifier suffisamment pour permettre à Android de trouver votre activité cible.

I-C-1. Déclarer des intentions

Les déclarations se déclarent dans le fichier manifest.xml de l'application.

Pour être éligible, une activité doit ainsi déclarer les intentions auxquelles elle souhaite répondre, typiquement, pour une activité qui se lance par l'IHM principale d'Android, on rajoute :

 
Sélectionnez
1.
2.
3.
4.
<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Un autre exemple plus utile est la déclaration d'une intention qui n'est pas main launcher :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.PICK" />
    <category android:name="android.intent.category.DEFAULT" />
    <data mimeType:name="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>

Cette intention déclare pouvoir répondre aux actions de visualisation et d'édition associées à un objet de type vnd.android.cursor.dir/vnd.google.note (c'est l'URI de la définition de l'objet). De même, le PICK permet de récupérer l'un de ces objets et de retourner dans l'application appelante. (Cf. http://developer.android.com/reference/android/content/Intent.html pour l'exemple complet).

Les intentions peuvent ainsi, en interne de l'application, faire des appels entre ces sous-modules. Ou en termes Android, les intentions permettent d'appeler différentes activités au sein de votre application de manière transparente.

I-C-2. Récepteur d'intention

Typiquement, au lieu de recevoir une intention avec une activité, il peut être utile d'implémenter au sein de l'application une classe spécifique qui s'occupe de la récupération des intentions (comme un service) et de leur traitement qui peut être, du coup, contextuel (appel à un service, à plusieurs activités…).

Pour cela, il suffit de faire étendre votre classe réceptrice de la classe BroadCastReceiver et la déclarer dans le manifest.xml par :

 
Sélectionnez
<receiver android :name="maClasseReceptionniste"/>

Cette classe doit étendre la méthode onReceive. De plus, elle ne vit que lors de la réception d'une intention, elle est créée à la réception et détruite dès que la méthode onReceive est terminée. Ainsi, la classe BroadcastReceiver ne peut être liée à un service, une fenêtre de dialogue ou quoi que ce soit d'autre n'appartenant pas à son thread.

La seule exception à cette règle est quand votre classe qui hérite de BroadCastReceiver est implémentée par un composant d'une durée de vie longue (un service, une activité), dans ce cas, elle sera détruite quand l'hôte (bref le service, l'activité) est détruite.

Dans ce cas, le receveur ne se déclare pas dans le manifest.xml, il faut appeler la méthode registerReceiver dans le code de votre activité (service) au sein de la méthode onResume() et unregisterReceiver dans la méthode onPause().

Seuls les récepteurs actifs peuvent recevoir des intentions…

I-D. Lancer des activités

I-D-1. Instanciation

Pour instancier une activité interne à son programme :

 
Sélectionnez
final Intent intent = new Intent().setClass(this, MyDaughterActivity.class);

Cette instruction déclare une intention associée à l'activité MyDaughterActivity qui est une classe de votre programme et this qui est l'activité courante.

Pour instancier une activité externe à votre programme, il vaut mieux spécifier une URI et une action, par exemple :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
// Retrieve latitude and longitude
String latitude = "43.565715431592736";
String longitude = "1.398482322692871";
// Format the associated uri
Uri uriGeo = Uri.parse("geo:" + latitude + "," + longitude);
// Declare the associated Intent
final Intent intentGeo = new Intent(Intent.ACTION_VIEW, uriGeo);

Cette intention demande au système d'afficher une URI de type géo, à lui de se débrouiller pour trouver quelle activité répondra à cette intention.

I-D-2. Appel

Pour lancer une activité, deux cas s'offrent à vous, le cas de la relation pair-à-pair ou le cas maître-esclave entre vos deux activités.

Dans le cas pair-à-pair (c.-à-d. l'activité mère lance l'activité fille et n'attend rien) :

 
Sélectionnez
startActivity(intentGeo);

Dans le cas maître-esclave :

 
Sélectionnez
startActivityForResult(intentContactForResult, INTENT_CALL_ID);

Il faut alors implémenter dans l'activité mère la méthode onActivityResult qui est appelée lorsque l'activité fille prend fin. L'activité fille, elle, doit implémenter la méthode setResult() qui généralement renvoie RESULT_OK ou RESULT_CANCELLED.

On peut récupérer aussi dans onActivityResult un String contenant des informations (une URL par exemple) ou un objet Bundle.

I-D-2-a. Exemple

Dans cet exemple, nous montrons comment lancer :

  • une activité qui appartient à votre programme ;
  • une activité qui permet de se géolocaliser avec une latitude/longitude grâce à la carte ;
  • une activité qui récupère un contact et affiche les informations associées.

Ce projet est donc séparé en deux classes :

  • l'activité principale qui lance les autres activités et qui implémente onActivityResult pour traiter les activités lancées avec la méthode startActivityForResults ;
  • l'activité otherActivity qui ne fait qu'afficher un champ texte.

Le code Java de la classe principale :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
public class IntentionSimpleTuto extends Activity {
    // The unique identifier for the call using Intent of contact
    private final int INTENT_CALL_ID = 10012220;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // To launch your own activity
        // First declare an intent
        final Intent intent = new Intent().setClass(this, OtherActivity.class);
        // Then add the action to the button:
        Button btnOtherActivity = (Button) findViewById(R.id.launchOther);
        btnOtherActivity.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Launch the activity
                startActivity(intent);
            }
        });

        // Do the same for Geo*
        // Retrieve latitude and longitude
        String latitude = "43.565715431592736";
        String longitude = "1.398482322692871";
        // Format the associated uri
        Uri uriGeo = Uri.parse("geo:" + latitude + "," + longitude);
        // Declare the associated Intent
        final Intent intentGeo = new Intent(Intent.ACTION_VIEW, uriGeo);
        // instanciate the button
        Button btnGeoActivity = (Button) findViewById(R.id.launchGeo);
        btnGeoActivity.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Launch the activity
                startActivity(intentGeo);
            }
        });
        // Do the same for Contact waiting for result
        // Format the associated uri
        Uri uriContact = Uri.parse("content://contacts/people");// "content://contacts/people"
        // Declare the intent:
        final Intent intentContactForResult = new Intent(Intent.ACTION_PICK,
                uriContact);
        // instanciate the button
        Button btnContactActivityForResults = (Button) findViewById(R.id.launchContactForResult);
        btnContactActivityForResults
                .setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        // Launch the activity
                        startActivityForResult(intentContactForResult,
                                INTENT_CALL_ID);
                    }
                });
    }

    /*
     *  * (non-Javadoc) * * @see android.app.Activity#onActivityResult(int, int,
     * android.content.Intent)
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == INTENT_CALL_ID) {
            if (resultCode == Activity.RESULT_OK) {
                Uri contactData = data.getData();
                Toast.makeText(
                        IntentionSimpleTuto.this,
                        "Result ok (uri:" + contactData + ") data "
                                + contactData.toString(), Toast.LENGTH_LONG)
                        .show();
                Cursor c = managedQuery(contactData, null, null, null, null);
                StringBuffer columnName = new StringBuffer("Result : ");
                String value;
                String name = "...";
                if (c.moveToFirst()) {
                    for (int i = 0; i < c.getColumnCount(); i++) {
                        value = c.getString(c.getColumnIndexOrThrow(c
                                .getColumnName(i)));
                        columnName.append(",\r\n" + c.getColumnName(i) + ": "
                                + value);
                    }
                    Toast.makeText(IntentionSimpleTuto.this, columnName,
                            Toast.LENGTH_LONG).show();
                    name = c.getString(c
                            .getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                    Toast.makeText(IntentionSimpleTuto.this,
                            "Et le nom : " + name, Toast.LENGTH_LONG).show();
                }
            } else if (resultCode == Activity.RESULT_CANCELED) {
                Toast.makeText(IntentionSimpleTuto.this,
                        "Result ko no contact picked", Toast.LENGTH_LONG)
                        .show();
            }
        }
    }
}

Le code Java de la seconde activité :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
public class OtherActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.other_activity);
    }
}

Le mainLayout.xml de l'activité principale qui déclare trois boutons et un champ texte :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello">
    </TextView>
    <Button
            android:text="@string/launchOther"
            android:id="@+id/launchOther"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    </Button>
    <Button
            android:text="@string/launchGeo"
            android:id="@+id/launchGeo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    </Button>
    <Button
            android:text="@string/launchContactForResult"
            android:id="@+id/launchContactForResult"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    </Button>
</LinearLayout>

Le layout de other_activity.xml :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
                android:id="@+id/otherTextView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/otheractivity"
    />
</LinearLayout>

Le fichier des chaînes de caractères (string.xml) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, IntentionSimpleTuto!</string>
    <string name="app_name">IntentionSimpleTuto</string>
    <string name="launchOther">Launch the activity other</string>
    <string name="launchGeo">Launch the activity Geo</string>
    <string name="launchContactForResult">Launch the activity Contact for results</string>
    <string name="otheractivity">And an other activity appears in front of your amazed eyes !</string>
</resources>

Et le fichier manifest.xml :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="net.stinfoservices.android.tuto.core" android:versionCode="1"
  android:versionName="1.0">
  <application android:icon="@drawable/icon" android:label="@string/app_name">
   <activity android:name=".IntentionSimpleTuto" android:label="@string/app_name">
     <intent-filter>
       <action android:name="android.intent.action.MAIN" />
       <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
   </activity>
   
   <activity android:name="OtherActivity"></activity>
 </application>
 <uses-sdk android:minSdkVersion="8" />
 <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
</manifest>

I-E. Cas particulier : la navigation par onglets

Pour des raisons de sécurité, une activité ne peut héberger les activités d'autres applications au sein de ses onglets. Ainsi, pour obtenir une navigation par onglet, il faut tout d'abord créer l'activité contenante qui est une TabActivity et lui rajouter des onglets que l'on peuple avec des intentions. Pour cela, on récupère le TabHost de la classe TabActivity et pour chacun des onglets on effectue les opérations suivantes :

  • définition de l'Intent qui représente l'activité contenue par l'onglet ;
  • récupération puis définition du TabSpec (son tag, son label, son contenu via l'Intent) ;
  • ajout du TabSpec au TabHost.

Le code Java de la classe principale :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
public class MultiTabBrowserTuto extends TabActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Define the Tab structure
        setContentView(R.layout.main);
        // Retrieve the ressource to access to the icon
        Resources resources = getResources(); // Resource object to get
                                                // Drawables
        // Set the tabHost (set it has final to use it in the
        // OnTabChangeListener)
        final TabHost tabHost = getTabHost();
        // Define the tabSpec that can be thought has the content of the
        // TabPanel
        TabHost.TabSpec tabSpec;
        // Define the intent that is used to populate the tabSpec
        Intent intent;

        // Create an Intent to launch an Activity for the tab
        intent = new Intent().setClass(this, SiteWebSTI.class);

        // Initialize a TabSpec for each tab and add it to the TabHost
        // Get a new TabHost.TabSpec associated with this tab host.
        tabSpec = tabHost.newTabSpec("SiteWebSti");
        // Define its indicator the label displayed (it should be
        // ressources.getString(R.string.stringId)
        tabSpec.setIndicator("SiteSti",
                resources.getDrawable(R.drawable.ic_tab));
        // Define the content of the Spec (the TabPanel)
        tabSpec.setContent(intent);
        // Add it to the tab container
        tabHost.addTab(tabSpec);

        // Do the same with the tab that displays a simple TextView:
        // Define the intent that will be displayed
        intent = new Intent().setClass(this, TextViewActivity.class);
        // Get a new TabHost.TabSpec associated with this tab host.
        tabSpec = tabHost.newTabSpec("textView");
        // Define its indicator the label displayed (it should be
        // ressources.getString(R.string.stringId)
        tabSpec.setIndicator("TextView",
                resources.getDrawable(R.drawable.ic_tab));
        // Define the content of the Spec (the TabPanel)
        tabSpec.setContent(intent);
        // Add it to the tab container
        tabHost.addTab(tabSpec);

        // Do the same with the tab that displays a simple Clock (analogic and
        // digital):
        // Define the intent that will be displayed
        intent = new Intent().setClass(this, ClockAD.class);
        // Get a new TabHost.TabSpec associated with this tab host.
        tabSpec = tabHost.newTabSpec("clock");
        // Define its indicator the label displayed
        tabSpec.setIndicator("Clock", resources.getDrawable(R.drawable.ic_tab));
        // Define the content of the Spec (the TabPanel)
        tabSpec.setContent(intent);
        // Add it to the tab container
        tabHost.addTab(tabSpec);

        // Define the current tab displayed (here the clock)
        tabHost.setCurrentTab(2);
        // Add a listener that just displays a Toast with the tag of the new
        // selected tab
        tabHost.setOnTabChangedListener(new OnTabChangeListener() {
            @Override
            public void onTabChanged(String tabId) {
                Toast.makeText(getApplicationContext(),
                        "New tab selection : " + tabHost.getCurrentTabTag(),
                        Toast.LENGTH_SHORT).show();
            }
        });

    }
}

Les codes Java des classes des activités sont des codes d'activités normales. Les classes ne savent pas qu'elles vont être utilisées au sein d'onglets.

Le code Java de la classe SiteWebSti qui ne fait que déclarer un WebKit qui pointe vers un site :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
public class SiteWebSTI extends Activity {
    WebView browser;

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        browser = new WebView(this);
        setContentView(browser);
        browser.loadUrl("http://www.stinfoservices.net/");
    }
}

Le code Java de la classe TextView qui ne fait que déclarer un TextView avec un texte simple :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
public class TextViewActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView textview = new TextView(this);
        textview.setText("Hello Guy this a TabPanel also called TabSpec");
        setContentView(textview);
    }
}

Le code Java de la classe ClockAD qui ne fait que charger son fichier de layout.xml nommé clock.xml :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
public class ClockAD extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.clock);
    }
}

Le fichier de layout associé à la classe ClockAD qui se nomme clock. Il déclare deux éléments, une horloge digitale et une analogique :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  >
  <AnalogClock android:id="@+id/analog"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:layout_centerHorizontal="true"
   android:layout_alignParentTop="true"
   />
   <DigitalClock android:id="@+id/digital"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_centerHorizontal="true"
     android:layout_below="@id/analog"
     />
</RelativeLayout>

Puis les fichiers principaux de l'application :

Le fichier Layout principal de la classe MultiTabBrowserTuto qui déclare la structure usuelle d'une application à onglets :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:padding="5dp" />
    </LinearLayout>
</TabHost>

Le fichier de ressource pour les icônes qui reroute automatiquement vers une ressource en fonction de son état « de sélection » :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- When selected, use grey -->
    <item android:drawable="@drawable/ic_tab_grey"
          android:state_selected="true" />
    <!-- When not selected, use white-->
    <item android:drawable="@drawable/ic_tab_white" />
</selector>

Il est à noter que le dossier drawable contient deux icônes, ic_tab_grey.png et ic_tab_white.png qui sont dans les en-têtes des onglets et qui sont pointés par le fichier ci-dessus.

Et enfin le fichier manifest.xml de l'application. Trois choses sont importantes dans ce manifest.xml :

  • Chaque activité est déclarée (il ne faut pas l'oublier).
  • L'attribut noTitleBar est spécifié pour l'activité principale, ce qui permet de gagner un peu de place en hauteur.
  • L'accès à Internet est demandé (nécessaire à l'activité WebKit).
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
                package="net.stinfoservices.android.tuto.gui" android:versionCode="1"
                android:versionName="1.0">
                <application android:icon="@drawable/icon" android:label="@string/app_name">
                               <activity android:name=".MultiTabBrowserTuto"
                                               android:label="@string/app_name"
                                               android:theme="@android:style/Theme.NoTitleBar">
                                               <intent-filter>
                                                               <action android:name="android.intent.action.MAIN" />
                                                               <category android:name="android.intent.category.LAUNCHER" />
                                               </intent-filter>
                               </activity>
                               <activity android:name="SiteWebSTI"></activity>
                               <activity android:name="TextViewActivity"></activity>
                               <activity android:name="ClockAD"></activity>
                </application>
                <uses-sdk android:minSdkVersion="8" />
                <uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>

Voilà, une activité affichant un navigateur avec des onglets qui marchent avec les intentions. Ce qui correspond à l'état de l'art pour un programme Android qui se doit d'être un ensemble d'activités liées les unes aux autres au moyen d'intents.

I-F. Filtres d'intention standard

Vous trouverez dans http://developer.android.com/reference/android/content/Intent.html une très bonne description de ces intentions.

Les points suivants listent les paramètres les plus utilisés pour la déclaration d'intentions.

I-F-1. Action standard des activités

Actions courantes et standard que les Intents définissent pour lancer les activités (usuellement au moyen de startActivity(Intent)). Les plus importantes et les plus utilisées sont de loin ACTION_MAIN et ACTION_EDIT.

I-F-2. Actions standard d'un Broadcast

Actions courantes et standard que les Intents définissent pour recevoir les BroadCast (usuellement au moyen de registerReceiver(BroadcastReceiver, IntentFilter) ou au moyen du tag <receiver> dans le fichier manifest.xml).

I-F-3. Catégories standard

Catégories courantes et standard qui peuvent être utilisées pour classifier les Intents au moyen de la méthode addCategory(String).

I-F-4. Extra Data standard

II. La rotation

Lors de la rotation de l'écran, votre activité est détruite puis reconstruite.

Vous pouvez vous référer à la partie 5.2 : Gestion des événements du cycle de vie d'une activité.

Pour désactiver la rotation, il suffit de rajouter dans son fichier manifest.xml le type d'orientation (landscape, portrait ou sensor) de votre activité :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
<activity android:name=".LaunchDemo" android:label="LaunchDemo">
  <intent-filter>
   <action android:name="android.intent.action.MAIN"
     android:screenOrientation="landscape" />
     <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
 </activity>

Si vous mettez le paramètre sensor, cela demande à Android de faire pivoter l'activité en fonction de l'accéléromètre qui détecte quand l'écran est en mode portrait ou pas.

III. Remerciements

Cet article a été publié avec l'aimable autorisation de la société Android2EE.

Nous tenons à remercier Ced et f-leb pour la relecture orthographique de cet article et Mickael Baron pour la mise au format Developpez.com.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2016 Mathias Séguy. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.