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

Intentions sous Android

Cet article décrit l'utilisation des intentions(1) pour permettre aux composants Android de communiquer entre eux. Il est basé sur Eclipse 4.3, Java 1.6 et Android 4.3.

Nous remercions Lars Vogel qui nous a aimablement autorisés à traduire et héberger cet article.

N'hésitez pas à commenter cet article ! 3 commentaires Donner une note à l´article (5)

Article lu   fois.

Les deux auteur et traducteur

Site personnel

Traducteur : Profil Pro

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Intents et Intent Filter

I-A. Que sont les intentions ?

Les Intents sont des messages asynchrones qui permettent aux composants d'une application de demander des fonctionnalités à d'autres composants Android. Les Intents vous permettent d'interagir avec vos propres composants ou des composants d'autres applications. Par exemple, une activité peut démarrer une autre activité pour prendre une photo.

Les Intents sont des objets de type android.content.Intent. Votre code peut les envoyer au système Android pour définir les composants que vous ciblez. Par exemple à travers la méthode startActivity(), vous pouvez définir que cet Intent doit être utilisé pour démarrer une activité.

Un Intent peut avoir des données dans un Bundle. Ces données peuvent être utilisées par le composant qui traite l'Intent.

I-B. Démarrer une activité

Pour démarrer une activité(2), utilisez la méthode startActivity(Intent). Cette méthode est définie par l'objet Context hérité par l'activité.

Le code suivant montre comment démarrer une activité avec un Intent.

 
Sélectionnez
# Start the activity connect to the
# specified class

Intent i = new Intent(this, ActivityTwo.class);
startActivity(i);

I-C. Les sous-activités

Les activités qui sont démarrées par d'autres activités Android sont appelées sous-activités. Cette formulation permet de mieux décrire ce que l'on souhaite dire.

I-D. Démarrer un service

Vous pouvez aussi démarrer un service à l'aide d'un Intent. Utilisez la méthode startService(Intent) pour cela.

I-E. Intent Filter

Les Intents sont aussi utilisés pour signaler au système Android qu'un événement particulier est survenu. Les Intents décrivent souvent l'action qui doit être effectuée et fournissent les données sur lesquelles cette action doit être faite. Par exemple, votre application peut démarrer, avec une intention, un des composants du navigateur pour une certaine URL. Cela est montré par l'exemple suivant.

 
Sélectionnez
String url = "http://www.vogella.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);

Mais comment fait le système Android pour identifier les composants qui doivent réagir avec quel Intent?

Pour cela, le concept d'Intent Filter est utilisé. Un Intent Filter précise les types d'intentions auxquelles cette activité, ce service ou ce récepteur de diffusion peuvent répondre. Il déclare donc les capacités d'un composant.

Les composants Android enregistrent leurs Intent Filter soit statiquement dans le fichier AndroidManifest.xml soit, dans le cas d'un récepteur de diffusion, dynamiquement dans le code. Un filtre d'intentions est défini par sa catégorie, son action et ses filtres de données. Il peut également contenir des métadonnées supplémentaires.

Si un Intent est envoyé au système Android, la plate-forme Android initie la détermination du récepteur en utilisant les données contenues dans l'objet Intent. En cela, elle détermine les composants qui sont enregistrés pour les données de l'Intent. Si plusieurs composants sont enregistrés pour le même Intent Filter, l'utilisateur peut alors décider quel composant doit être lancé.

II. Types d'Intents

II-A. Les différents types d'Intents

Android supporte les Intents explicites et implicites.

Une application peut définir les composants cibles directement dans l'Intent (Intent explicite) ou demander au système Android de rechercher le composant adéquat en se basant sur les données de l'Intent (Intent implicite).

II-B. Les Intents explicites

Les Intents explicites définissent explicitement le composant qui doit être appelé par le système Android en utilisant le nom de classe Java comme identifiant.

L'exemple suivant montre comment créer un Intent explicite et comment l'envoyer au système Android. Si cette classe représente une activité, le système Android la démarrera.

 
Sélectionnez
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");

Les Intents explicites sont généralement utilisés au sein d'une application, car les classes de cette application sont contrôlées par le développeur de l'application.

II-C. Les Intents implicites

Les Intents implicites précisent l'action qui devrait être effectuée avec éventuellement les données pour cette action.

Par exemple, ce qui suit indique au système Android d'afficher une page Web. Tous les navigateurs Web installés doivent être enregistrés avec l'Intent correspondant en utilisant un Intent Filter.

 
Sélectionnez
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.vogella.com"));
startActivity(i);

Si un Intent explicite est envoyé au système Android, il recherche tous les composants qui sont enregistrés avec l'action spécifique et le type de données approprié.

Si un seul composant est trouvé, Android démarre directement ce composant. Si plusieurs composants sont identifiés par le système Android, l'utilisateur devra indiquer quel composant utiliser à l'aide d'une boîte de dialogue de sélection.

III. Transfert de données entre activités

III-A. Transfert de données vers le composant cible

Un Intent contient l'action et éventuellement des données complémentaires. Le composant qui crée l'Intent peut y ajouter des données avec la méthode surchargée putExtra(). Les données supplémentaires sont des paires clé/valeur, la clé est toujours une chaîne. En valeur, vous pouvez utiliser les types de données primitifs (int, float, ..) ainsi que les types String, Bundle, Parcelable et Serializable.

Le composant récepteur peut accéder à ces informations avec les méthodes getAction() et getData() sur l'objet Intent. Cet objet Intent peut être récupéré avec la méthode getIntent().

Le composant qui reçoit l'Intent peut utiliser la méthode getIntent().getExtras () pour obtenir les données supplémentaires.

 
Sélectionnez
Bundle extras = getIntent().getExtras();
if (extras == null) {
    return;
    }
// Get data via the key
String value1 = extras.getString(Intent.EXTRA_TEXT);
if (value1 != null) {
  // do something with the data
}

III-B. Exemple : utiliser un Intent partagé

Beaucoup d'applications Android vous permettent de partager des données avec d'autres personnes, par exemple les applications Facebook, Google+, Gmail et Twitter. Vous pouvez aussi envoyer des données à l'un de ces composants. Le morceau de code suivant vous montre comment faire :

 
Sélectionnez
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "News for you!");
startActivity(intent);

III-C. Récupérer le résultat d'une sous-activité

Une activité peut être fermée avec le bouton « back » sur le téléphone. Dans ce cas, la méthode finish() est appelée. Si l'activité a été lancée avec la méthode startActivity(Intent), l'appelant ne requiert pas de résultat ou de retour de l'activité qui est maintenant terminée.

Si vous lancez l'activité avec la méthode startActivityForResult(), vous attendez un retour de la sous-activité. Dès que la sous-activité se termine, la méthode onActivityResult() de la sous-activité est appelée et vous pouvez exécuter des actions suivant le résultat.

Dans la méthode startActivityForResult() vous pouvez spécifier le code de retour pour déterminer quelle activité vous avez démarrée. Ce code vous est retourné. L'activité démarrée peut aussi positionner un résultat que l'appelant peut utiliser afin de déterminer si l'activité a été abandonnée ou pas.

Image non disponible
Image non disponible

La sous-activité utilise la méthode finish() pour créer un Intent et mettre des données dedans. Cela mettra également une donnée de retour via l'appel de la fonction setResult().

L'exemple de code suivant montre comment déclencher un Intent avec la méthode startActivityForResult().

 
Sélectionnez
public void onClick(View view) {
  Intent i = new Intent(this, ActivityTwo.class);
  i.putExtra("Value1", "This value one for ActivityTwo ");
  i.putExtra("Value2", "This value two ActivityTwo");
  // Set the request code to any code you like, you can identify the
  // callback via this code
  startActivityForResult(i, REQUEST_CODE);
}

Si vous utilisez la méthode startActivityForResult() alors l'activité démarrée est appelée sous-activité.

Quand la sous-activité se termine, elle retourne des données à l'appelant avec une intention. Ceci est fait dans la méthode finish().

 
Sélectionnez
@Override
public void finish() {
  // Prepare data intent 
  Intent data = new Intent();
  data.putExtra("returnKey1", "Swinging on a star. ");
  data.putExtra("returnKey2", "You could be better then you are. ");
  // Activity finished ok, return the data
  setResult(RESULT_OK, data);
  super.finish();
}

Dès que la sous-activité est terminée, la méthode onActivityResult() de l'activité appelante est exécutée.

 
Sélectionnez
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
    if (data.hasExtra("returnKey1")) {
      Toast.makeText(this, data.getExtras().getString("returnKey1"),
        Toast.LENGTH_SHORT).show();
    }
  }
}

IV. Définir les Intents Filter

IV-A. Définir un Intent Filter

Vous pouvez enregistrer vos propres composants avec des Intent Filter. Si un composant n'en définit pas, il ne peut être appelé par un Intent explicite. Ce chapitre donne quelques exemples pour enregistrer un composant avec une intention. La clé de cette inscription, c'est que votre composant s'enregistre pour l'action correcte et précise le type mime et les métadonnées correctes.

IV-B. Exemple : Enregistrer une activité en tant que navigateur

Le code suivant enregistre une activité avec un Intent qui est déclenchée lorsque quelqu'un veut afficher une page Web.

 
Sélectionnez
<activity android:name=".BrowserActivitiy" 
          android:label="@string/app_name">
  <intent-filter>
     <action android:name="android.intent.action.VIEW" />
     <category android:name="android.intent.category.DEFAULT" />
     <data android:scheme="http"/> 
  </intent-filter>
</activity>

IV-C. Exemple : Enregistrer une activité pour un Intent partagé

L'exemple suivant enregistre une activité pour l'intention ACTION_SEND. Il se déclare lui-même comme acceptant le type mime text/plain.

 
Sélectionnez
<activity
  android:name=".ActivityTest"
    android:label="@string/app_name" >
    <intent-filter>
      <action android:name="android.intent.action.SEND" />
      
      <category android:name="android.intent.category.DEFAULT" />

      <data android:mimeType="text/plain" />
    
    </intent-filter>

</activity>

Si un composant ne définit pas d'Intent Filter, il peut être appelé uniquement par un Intent explicite.

V. Intents en tant que déclencheurs d'événements

Les Intents peuvent aussi être utilisées pour envoyer des messages de diffusion au système Android. Les récepteurs de messages de diffusion peuvent s'enregistrer à un événement et seront notifiés dès lors que cet événement est déclenché.

Votre application peut s'enregistrer aux événements système, par exemple l'arrivée d'un nouveau mail, le redémarrage système terminé, ou un appel téléphonique reçu et réagir en conséquence.

Comme indiqué plus tôt, depuis la version 3.1 d'Android, par défaut, le système Android empêchera les récepteurs de diffusion de recevoir des intentions si l'application correspondante n'a jamais été lancée par l'utilisateur ou si l'application a été stoppée explicitement par l'utilisateur avec le menu Android (dans Manage Application).

VI. Déterminer les récepteurs d'Intents valides

Parfois, vous voulez savoir si un composant a enregistré un Intent. Par exemple, vous voulez vérifier si un certain récepteur d'Intent est disponible et dans le cas où ce composant est disponible, vous activez une fonctionnalité dans votre application.

Ce contrôle peut être fait avec la classe PackageManager.

Le code suivant vérifie si un composant s'est enregistré pour une certaine intention. Construisez votre Intent comme si vous vouliez la déclencher et passez-la à la méthode suivante :

 
Sélectionnez
public static boolean isIntentAvailable(Context ctx, Intent intent) {
   final PackageManager mgr = ctx.getPackageManager();
   List<ResolveInfo> list =
      mgr.queryIntentActivities(intent, 
         PackageManager.MATCH_DEFAULT_ONLY);
   return list.size() > 0;
}

En se basant sur le résultat, vous pouvez ajuster votre application. Par exemple, vous pouvez désactiver ou cacher certaines options du menu.

VII. Prérequis pour ce tutoriel

La suite suppose que vous avez déjà une certaine connaissance du développement Android. Lisez le tutoriel du développement Android pour apprendre les bases.

VIII. Exercice : Démarrer l'activité

VIII-A. But de cet exercice

L'exercice suivant montre comment utiliser un Intent explicite pour démarrer une sous-activité et comment lui envoyer des données.

C'est la première partie d'un exercice qui se poursuit au paragraphe 9.1. Une solution peut être vue dans le chapitre 10.

VIII-B. Créer un projet et sa mise en page principale

Créez un nouveau projet Android nommé com.vogella.android.intent.explicit avec une activité nommée MainActivity.

Modifier la mise en page(3) de la première activité avec le code suivant :

 
Sélectionnez
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/inputforintent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minHeight="60dip"
        android:text="First Activity"
        android:textSize="20sp" >
    </EditText>

    <Button
        android:id="@+id/startintent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/inputforintent"
        android:layout_below="@+id/inputforintent"
        android:onClick="onClick"
        android:text="Calling an intent" />

</RelativeLayout>

VIII-C. Créer un nouveau fichier de mise en page

Créez une nouvelle mise en page appelée activity_result.xml qui sera utilisée dans notre seconde activité.

Pour créer un nouveau fichier de mise en page, sélectionnez votre projet, faites un clic droit et sélectionnez « File ? New ? Other… ? Android ? Android XML File » et sélectionnez l'option Layout.

Entrez activity_result.xml comme nom de fichier et appuyez sur le bouton Finish. Modifiez votre mise en page pour qu'elle ressemble à ce qui suit :

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/displayintentextra"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Input"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/returnValue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <requestFocus />
    </EditText>

</LinearLayout>

VIII-D. Créer une nouvelle activité

Ajoutez une nouvelle activité au fichier AndroidManifest.xml.

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.vogella.android.first"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="14" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".MainActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:label="Result Activity"
            android:name=".ResultActivity" >
        </activity>
    </application>

</manifest>

Créez la classe ResultActivity correspondante basée sur le code suivant :

 
Sélectionnez
package com.vogella.android.intent.explicit;

import android.app.Activity;
import android.os.Bundle;

public class ResultActivity extends Activity {

  @Override
  public void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.activity_result);
  }
}

La nouvelle activité sera démarrée par la première activité, c'est pourquoi elle est appelée sous-activité.

VIII-E. Démarrer la sous-activité

Démarrez la sous-activité avec un bouton à partir de la classe MainActivity. Le code suivant vous montre comment faire :

 
Sélectionnez
package com.vogella.android.intent.explicit;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends Activity {

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

  public void onClick(View view) {
    EditText text = (EditText) findViewById(R.id.inputforintent);
    // used later
    String value = text.getText().toString();
    // TODO 1 create new explicit Intent
    // based on "ResultActivity.class"

    // TODO 2 start second Activity with
    // startActivity(intent);
  }

}

Modifiez les TODO dans le code source de sorte que l'activité de ResultActivity soit lancée à partir de la méthode onClick().

Une fois que cette partie de l'exercice est terminée, démarrez votre application et vérifiez que vous pouvez lancer la seconde activité.

VIII-F. Envoyer des données à la sous-activité

La classe MainActivity doit passer la valeur du champ EditText à la sous-activité. Pour cela, utilisez la méthode putExtra(« yourKey », string) sur l'objet Intent.

VIII-G. Recevoir les données dans la sous-activité

Dans votre sous-activité ResultActivity, récupérez le Bundle avec les données de l'intention en utilisant la méthode getIntent().getExtras().

Lisez la valeur extra avec la méthode getExtra(« yourKey ») sur le Bundle récupéré avec la méthode getExtras().

Cette valeur doit être stockée dans le TextView dont l'identifiant est displayintentextra.

IX. Exercice : Recevoir des données en provenance de la sous-activité

IX-A. But de cet exercice

Ceci est la deuxième partie de l'exercice commencé dans le paragraphe 8.1. Un exemple de solution pour l'activité peut être vu dans le chapitre 10.

Continuez à utiliser le projet com.vogella.android.intent.explicit.

Dans l'exercice suivant, vous allez transférer des données depuis votre sous-activité vers l'activité principale quand l'utilisateur appuiera sur le bouton Back.

IX-B. Renvoyer des données depuis la sous-activité

Ajoutez le code suivant à la méthode finish() de la classe ResultActivity.

 
Sélectionnez
@Override
public void finish() {
    
  // TODO 1 create new Intent 
  // Intent intent = new Intent();
    
  // TODO 2 read the data of the EditText field
  // with the id returnValue
  
  // TODO 3 put the text from EditText
  // as String extra into the intent
  // use editText.getText().toString();
    
  // TODO 4 use setResult(RESULT_OK, intent); 
  // to return the Intent to the application
  
  super.finish();
}

Modifiez les TODO.

IX-C. Évaluer les données retournées dans l'activité principale

Utilisez dans MainActivity la méthode startActivityForResult() pour démarrer la sous-activité. Cela vous permet d'utiliser la méthode onActivityResult() pour recevoir des données en retour de la sous-activité. Extrayez les données reçues dans le Bundle.

Affichez un Toast avec les données extraites pour valider que vous les avez correctement reçues. Le code suivant contient le début de la solution pour cela :

 
Sélectionnez
package com.vogella.android.intent.explicit;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

public class MainActivity extends Activity {
  
  // constant to determine which sub-activity returns
  private static final int REQUEST_CODE = 10;

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

  public void onClick(View view) {
    EditText text = (EditText) findViewById(R.id.inputforintent);
    String string = text.getText().toString();
    Intent i = new Intent(this, ResultActivity.class);
    i.putExtra("yourkey", string);
    // TODO 2.. now use 
    // startActivityForResult(i, REQUEST_CODE);
  }

  // TODO 3 Implement this method
  // assumes that "returnkey" is used as key to return the result
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
      if (data.hasExtra("returnkey")) {
        String result = data.getExtras().getString("returnkey");
        if (result != null && result.length() > 0) {
          Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
        }
      }
    }
  }
}

X. Solution : Utiliser les intentions

X-A. Présentation

Après avoir fini l'exercice du paragraphe 9.1, le code de votre activité devrait ressemble à cela :

X-B. Le code de l'activité

 
Sélectionnez
package com.vogella.android.intent.explicit;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;

public class ResultActivity extends Activity {

  @Override
  public void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.activity_result);
    Bundle extras = getIntent().getExtras();
    String inputString = extras.getString("yourkey");
    TextView view = (TextView) findViewById(R.id.displayintentextra);
    view.setText(inputString);
  }

  @Override
  public void finish() {
    Intent intent = new Intent();
    EditText editText= (EditText) findViewById(R.id.returnValue);
    String string = editText.getText().toString();
    intent.putExtra("returnkey", string);
    setResult(RESULT_OK, intent);
    super.finish();
  }
} 
package com.vogella.android.intent.explicit;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

  // constant to determine which sub-activity returns
  private static final int REQUEST_CODE = 10;

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


  public void onClick(View view) {
    EditText text = (EditText) findViewById(R.id.inputforintent);
    String string = text.getText().toString();
    Intent i = new Intent(this, ResultActivity.class);
    i.putExtra("yourkey", string);
    startActivityForResult(i, REQUEST_CODE);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
      if (data.hasExtra("returnkey")) {
        String result = data.getExtras().getString("returnkey");
        if (result != null && result.length() > 0) {
          Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
        }
      }
    }
  }
}

XI. Exercice : Utiliser des Intents explicites

L'exercice suivant montre l'utilisation des Intents implicites pour démarrer des activités dans votre système Android.

Créez un nouveau projet appelé de.vogella.android.intent.implicit avec une activité appelée CallIntentsActivity.

Dans cet exemple, nous utilisons un Spinner pour sélectionner quel Intent déclencher. Le contenu de ce Spinner est défini par des valeurs statiques.

Créez le fichier d'intentions intents.xml dans le répertoire res/values.

 
Sélectionnez
<resources>
    <string-array name="intents">
        <item>Open Browser</item>
        <item>Call Someone</item>
        <item>Dial</item>
        <item>Show Map</item>
        <item>Search on Map</item>
        <item>Take picture</item>
        <item>Show contacts</item>
        <item>Edit first contact</item>
    </string-array>
    
</resources>

Modifiez la mise en page de l'activité pour ceci :

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:alignmentMode="alignBounds"
    android:columnCount="1" >

      <Spinner
        android:id="@+id/spinner"
        android:layout_gravity="fill_horizontal"
        android:drawSelectorOnTop="true"
        >
      </Spinner>
    
    <Button
        android:id="@+id/trigger"
        android:onClick="onClick"
        android:text="Trigger Intent">
    </Button>

  
</GridLayout>

Afin de pouvoir utiliser certains Intents, vous devez enregistrer les permissions requises dans le fichier AndroidManifest.xml. Vérifiez que le fichier AndroidManifest.xml contient bien les permissions suivantes :

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.vogella.android.intent.implicit"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.CALL_PRIVILEGED" >
    </uses-permission>
    <uses-permission android:name="android.permission.CALL_PHONE" >
    </uses-permission>
    <uses-permission android:name="android.permission.CAMERA" >
    </uses-permission>
    <uses-permission android:name="android.permission.READ_CONTACTS" >
    </uses-permission>
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:name=".CallIntentsActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Modifiez le code de votre activité pour cela :

 
Sélectionnez
package de.vogella.android.intent.implicit;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class CallIntentsActivity extends Activity {
  private Spinner spinner;

  
/** Called when the activity is first created. */

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    spinner = (Spinner) findViewById(R.id.spinner);
    ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
        R.array.intents, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
  }

  public void onClick(View view) {
    int position = spinner.getSelectedItemPosition();
    Intent intent = null;
    switch (position) {
    case 0:
      intent = new Intent(Intent.ACTION_VIEW,
          Uri.parse("http://www.vogella.com"));
      break;
    case 1:
      intent = new Intent(Intent.ACTION_CALL,
          Uri.parse("tel:(+49)12345789"));
      break;
    case 2:
      intent = new Intent(Intent.ACTION_DIAL,
          Uri.parse("tel:(+49)12345789"));
      startActivity(intent);
      break;
    case 3:
      intent = new Intent(Intent.ACTION_VIEW,
          Uri.parse("geo:50.123,7.1434?z=19"));
      break;
    case 4:
      intent = new Intent(Intent.ACTION_VIEW,
          Uri.parse("geo:0,0?q=query"));
      break;
    case 5:
      intent = new Intent("android.media.action.IMAGE_CAPTURE");
      break;
    case 6:
      intent = new Intent(Intent.ACTION_VIEW,
          Uri.parse("content://contacts/people/"));
      break;
    case 7:
      intent = new Intent(Intent.ACTION_EDIT,
          Uri.parse("content://contacts/people/1"));
      break;

    }
    if (intent != null) {
      startActivity(intent);
    }
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK && requestCode == 0) {
      String result = data.toURI();
      Toast.makeText(this, result, Toast.LENGTH_LONG);
    }
  }

}

Si vous lancez votre application, vous voyez une liste de boutons et si vous cliquez sur un de ces boutons, l'activité correspondante est démarrée.

Notez que vous n'avez pas spécifié une application de réception, uniquement ce qui doit être fait. Cela vous permet de définir des tâches faiblement couplées qui utilisent des composants d'applications différentes.

XII. Exercice : Enregistrer un Intent Filter pour requêtes HTTP

Dans l'exercice suivant, vous enregistrerez une activité en tant que navigateur Web. Cela signifie que si quelqu'un veut voir une URL commençant par http, votre activité sera aussi disponible pour cette intention.

Cet exemple récupère le code HTML de la page et l'affiche dans un TextView.

Créez un projet Android appelé de.vogella.android.intent.browserfilter avec une activité appelée BrowserActivity.

Enregistrez votre activité avec l'événement Intent.Action_VIEW et le protocole « http » avec les modifications suivantes dans votre fichier AndroidManifest.xml. Le manifeste définit aussi les permissions nécessaires pour accéder à Internet.

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.vogella.android.intent.browserfilter"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:name=".BrowserActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="http" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Modifiez la mise en page pour ceci :

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
<TextView  
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/textView"/>
</LinearLayout>

Modifiez le code de votre activité pour cela :

 
Sélectionnez
package de.vogella.android.intent.browserfilter;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.StrictMode;
import android.widget.TextView;

public class BrowserActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // To keep this example simple, we allow network access
    // in the user interface thread
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
        .permitAll().build();
    StrictMode.setThreadPolicy(policy);

    setContentView(R.layout.main);
    Intent intent = getIntent();
    TextView text = (TextView) findViewById(R.id.textView);
    // To get the action of the intent use
    String action = intent.getAction();
    if (!action.equals(Intent.ACTION_VIEW)) {
      throw new RuntimeException("Should not happen");
    }
    // To get the data use
    Uri data = intent.getData();
    URL url;
    try {
      url = new URL(data.getScheme(), data.getHost(), data.getPath());
      BufferedReader rd = new BufferedReader(new InputStreamReader(url.openStream()));
      String line = "";
      while ((line = rd.readLine()) != null) {
        text.append(line);
      }

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

  }
}

Installez votre application. Si maintenant vous déclenchez une intention pour ouvrir une URL, vous devriez être capable de sélectionner votre composant. Vous pouvez par exemple déclencher cette intention avec l'exemple du tutoriel implicit.

Si vous sélectionnez votre composant, le code HTML est chargé et affiché dans votre TextView.

Image non disponible
Image non disponible

XIII. Exercice : choisir une image avec un Intent

L'exemple suivant vous montre comment choisir une image depuis une application de photographie sur Android avec un Intent

Créez un nouveau projet appelé de.vogella.android.imagepick avec une activité appelée ImagePickActivity.

Modifiez le fichier activity_main.xml comme cela :

 
Sélectionnez
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="pickImage"
        android:text="Button" >
    </Button>

    <ImageView
        android:id="@+id/result"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/icon" >
    </ImageView>

</LinearLayout>

Modifiez le code de votre classe comme cela :

 
Sélectionnez
package de.vogella.android.imagepick;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class ImagePickActivity extends Activity {
  private static final int REQUEST_CODE = 1;
  private Bitmap bitmap;
  private ImageView imageView;

  
/** Called when the activity is first created. */

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    imageView = (ImageView) findViewById(R.id.result);
  }

  public void pickImage(View View) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    startActivityForResult(intent, REQUEST_CODE);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    InputStream stream = null;
    if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK)
      try {
        // recyle unused bitmaps
        if (bitmap != null) {
          bitmap.recycle();
        }
        stream = getContentResolver().openInputStream(data.getData());
        bitmap = BitmapFactory.decodeStream(stream);

        imageView.setImageBitmap(bitmap);
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } finally {
        if (stream != null)
          try {
            stream.close();
          } catch (IOException e) {
            e.printStackTrace();
          }
      }
  }
}

Si vous exécutez cette application, vous pouvez sélectionner une image de votre bibliothèque d'images sur votre téléphone Android et l'assigner à votre ImageView.

XIV. Liens et littérature

XV. Remerciements

Vous pouvez retrouver l'article original ici : Android Intents - Tutorial. Nous remercions Lars Vogel qui nous a aimablement autorisés à traduire et héberger ses articles.

Nous remercions aussi Mishulyna pour sa traduction, ainsi que Phillipe DUVAL pour sa relecture orthographique.

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


NDT La littérature anglaise utilise le mot « Intent ». Ce terme a été traduit par « intention » dans cet article.
NDT La littérature anglaise utilise le mot « Activity ». Ce terme a été traduit par « activité » dans cet article.
NDT La littérature anglaise utilise le mot « Layout ». Ce terme a été traduit par « mise en page » dans cet article.

Licence Creative Commons
Le contenu de cet article est rédigé par Lars Vogel et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.