Introduction à Android

1 111 vues

Publié le

Support de cours sur les bases du développement Android

Publié dans : Formation
0 commentaire
1 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
1 111
Sur SlideShare
0
Issues des intégrations
0
Intégrations
4
Actions
Partages
0
Téléchargements
55
Commentaires
0
J’aime
1
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Introduction à Android

  1. 1. A propos Yoann Gotthilf, CTO d’une startup et freelance Web/Mobile •développeur Android depuis 6 ans •développeur Web depuis 13 ans •consultant sécurité pendant 6 ans •développeur FullstackJS depuis 1 ans yoann.gotthilf atgmail.com •@ygotthilf
  2. 2. Références Site officiel http://developer.android.com Blog officiel http://android-developers.blogspot.fr Blog Romain Guy http://www.curious-creature.org/category/android Blog Cyril Mottier(Fr + En) http://cyrilmottier.com
  3. 3. Qu'est ce qu'Android? Une plateforme unifiée pour terminaux mobiles (système d'exploitation + frameworks) Ce n'est pas une distribution Linux.
  4. 4. Qui développe Android? Android est open source: il existe donc de nombreux forks (CyanogenMod, Amazon, ...)
  5. 5. Qui soutient Android? L'Open Handset Alliance: un consortium d'industriels créé par Google en 2007.
  6. 6. L'histoire sans grand H 1991, norme GSM (communication «voix») 1992, IBM Simon (1er «smartphone») 2005, startup Android racheté par Google 2007, lancement iPhone + forfait data «illimité» Sept. 2008, officialisation et publication SDK Oct. 2008, lancement du 1ersmartphone Android
  7. 7. Le marché
  8. 8. Architecture Android 1/4
  9. 9. Architecture Android 2/4
  10. 10. Architecture Android 3/4
  11. 11. Architecture Android 4/4
  12. 12. Ou développer dans cette architecture? Uniquement sur la couche framework applicatif! Les développeurs tiers n'ont pas accès aux couches systèmes sous-jacentes.
  13. 13. IDE
  14. 14. Tester son application 3 méthodes : •Emulateur livré avec le SDK (pas terrible) •Emulateur Genymotion (pas mal) •Son smartphone (top) La communication s’effectue grâce au ADB
  15. 15. Les versions •Courante :KitKat 4.4 (API 19) •Prochaine : L (API 20)
  16. 16. Répartition des versions
  17. 17. Gérer la fragmentation Utiliser la librairie de support http://developer.android.com/tools/support-library/index.html
  18. 18. Que contient une application? •Manifeste Android •Ressources •Classes Java (Dalvik ou ART) •Librairies & JNI Le livrable est un APK (Android Package)
  19. 19. AndroidManifest.xml Permet au système de «connaître» l'application: •nom, logo et version •compatibilité (écran, version d'Android,…) •permissions •composants (activité, service, BR, CP)
  20. 20. Ressources Qu'est-ce? image fichier multimédia (musique, vidéo) layout (vue) style (couleur, marge, police, ...) animation internationalisation
  21. 21. Ressources L’organisation Chaque type à son propre répertoire Nom des fichiers : [a-z0-9_]+.<extention>
  22. 22. Ressources Gérer la configuration 1/2 Commentgérer les ressources en fonction de la configuration de chaque terminal Android? C’ést-à-dire de la langue, taille d'écran, ratio d'écran, résolution, version d'Android, ...
  23. 23. Ressources Gérer la configuration 2/2 1.Le développeurclasse par répertoire les différentes configurations souhaitées 2.A l'exécution, Androidchoisit les bonnes ressources
  24. 24. Ressources Les valeurs 1/2 •chaîne de caractères (chaîne simple, tableau, pluriel) •couleur •style •booléen •id •entier •tableau typé
  25. 25. Ressources Les valeurs 2/2 <?xml version="1.0" encoding="utf-8"?> <resources> <stringname="app_name">My first app</string> <stringname="hello">Hello world</string> <colorname="primary_color">#ff33b5e5</color> <colorname="secondary_color">#df0000</color> <string-arrayname="week_end_days"> <item>Sunday</item> <item>Saturday</item> </string-array> <dimenname="default_margin">2dp</dimen> <boolname="test_mode">false</bool> </resources> Fichier res/values/all.xml
  26. 26. Ressources Exemple de layout <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:text="@string/hello_world" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/primary_color"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher"/> </LinearLayout> Fichier res/layout/main.xml
  27. 27. Ressources Accès depuis un XML @<type>/<nom variable> Exemples : •@string/hello_world •@drawable/icon •@color/primary_color
  28. 28. Ressources Accès depuis le code imageView.setImageResource(R.drawable.icon); textView.setText(R.string.hello_world); aapt packagefr.imac.test; publicfinalclassR { publicstaticfinalclassattr { } publicstaticfinalclassdrawable { publicstaticfinalinticon=0x7f020000; } publicstaticfinalclassid { publicstaticfinalinthello_text=0x7f060000; } publicstaticfinalclasslayout { publicstaticfinalintinfo=0x7f030000; publicstaticfinalintmain=0x7f030001; } publicstaticfinalclassraw { publicstaticfinalintintra=0x7f040000; } publicstaticfinalclassstring { publicstaticfinalintapp_name=0x7f050000; publicstaticfinalinthello_world=0x7f050001; } }
  29. 29. Ressources prédéfinies Le SDK Android propose des ressources prédéfinies A manipuler comme les ressources du projet mais préfixé par Android. android.R.string.ok @android:string/ok La liste dans <Répertoire Android Studio>sdkplatformsandroid-<version>datares
  30. 30. Les composants UI
  31. 31. Déclarer une vue Démo
  32. 32. Exécution d'application Le système gère seul le cycle de vie des composantsapplicatifs. Le système vous donne temporairement la main dans des méthodes de callback pour exécuter vos traitements.
  33. 33. Activité Qu’est ce ? Une Activityréprésente un écrandans une application Son rôle est d’afficher et de contrôler une seule vue
  34. 34. import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; public class MyActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void onDestroy() { super.onDestroy(); // The activity is about to be destroyed. } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; return true; } } Activité Cycle de vie
  35. 35. public class MyActivity extends ActionBarActivity { @Override protectedvoidonCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); } } Activité Afficher une vue
  36. 36. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/connection" android:layout_gravity="center_horizontal" /> <EditText android:inputType="textEmailAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/email" android:id="@+id/email" /> <EditText android:inputType="textPassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/password" android:id="@+id/password" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@android:string/ok" android:id="@+id/submit"/> </LinearLayout> public class MyActivity extends ActionBarActivity { private EditText mEmailText ; private EditText mPasswordText ; private Button mSubmitButton ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); mEmailText = (EditText) findViewById(R.id.email); mPasswordText = (EditText) findViewById(R.id.password); mSubmitButton = (Button) findViewById(R.id.submit); } [...] } Activité Récupérer les composants graphiques
  37. 37. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); mEmailText = (EditText) findViewById(R.id.email); mPasswordText = (EditText) findViewById(R.id.password); mSubmitButton = (Button) findViewById(R.id.submit); mSubmitButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String email = mEmailText.getText().toString(); System.out.println(email); } }); } Activité Intéraction
  38. 38. Activité Exemple Démo
  39. 39. Fragment Problème Layout list Layout message Activity list Activity message Layout inbox Activity inbox Affiche Contrôle Contrôle Affiche Affiche Contrôle Phone Tablet
  40. 40. Fragment Solution Layout list Layout message Activity main Activity detail Phone Tablet Contrôle Contrôle Affiche Affiche Fragment list Fragment message Lance Lance Layout main
  41. 41. Fragment En détail packagefr.imac.uberconverter; importandroid.app.Fragment; importandroid.os.Bundle; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup; importandroid.widget.EditText; publicclassExampleFragment extendsFragment { @Override publicView onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment returninflater.inflate(R.layout.fragment_main, container, false); } @Override publicvoidonActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); View parent=getView(); EditText celsius = (EditText) parent.findViewById(R.id.celsius); } }
  42. 42. Fragment Chargement et manipulation <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragmentandroid:name="com.example.news.ArticleListFragment" android:id="@+id/list" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <fragmentandroid:name="com.example.news.ArticleReaderFragment" android:id="@+id/viewer" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent"/> </LinearLayout> <?xmlversion="1.0"encoding="utf-8"?> <fragmentxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list" android:name="com.example.news.ArticleListFragment" android:layout_width="match_parent" android:layout_height="match_parent"/> res/layout-large/activity1.xml res/layout/activity1.xml FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager .beginTransaction(); ArticleReaderFragmentfragment = newArticleReaderFragment(); fragmentTransaction.add(R.id.viewer, fragment); fragmentTransaction.commit(); Dans une activité
  43. 43. Fragment exemple Démo
  44. 44. L'ActionBar Depuis 3.0 Eléments : Actions items Navigation Tabs Drop-down Navigation Navigation drawer Recherche Vue personnalisable
  45. 45. AdapterView présentation Vue dont l’affichage des enfants est géré par un adaptateur •Implémentations : ListView, GridView, Spinner, Gallery, … •Optimisé pour l’affichage de beaucoup de vues : •Construction à la volé d’une vue •Réutilisation des vues inutilisés
  46. 46. AdapterView fonctionnement AdapterView Adapter ListView GridView ListAdapter CursorAdapter BaseAdapter Données Layout Utilise Construit Récupère Hérite Hérite
  47. 47. AdapterView exemple ListView publicclassList1 extendsListActivity { @Override publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list_1); ListAdapter adapter=newArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mStrings); setListAdapter(adapter); } privateString[] mStrings= { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi" }; <TextViewxmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:minHeight="?android:attr/listPreferredItemHeightSmall" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView style="?android:attr/textAppearanceLarge" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/cheeses"/> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> res/layout/simple_list_item1.xml dans le sdk res/layout/list_1.xml List1.java
  48. 48. Settings/Preferences public class SettingsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); } ... } <PreferenceScreenxmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategoryandroid:title="@string/pref_sms_storage_title" android:key="pref_key_storage_settings"> <CheckBoxPreferenceandroid:key="pref_key_auto_delete" android:summary="@string/pref_summary_auto_delete" android:title="@string/pref_title_auto_delete" android:defaultValue="false"... /> <Preferenceandroid:key="pref_key_sms_delete_limit" android:dependency="pref_key_auto_delete" android:summary="@string/pref_summary_delete_limit" android:title="@string/pref_title_sms_delete"... /> <Preferenceandroid:key="pref_key_mms_delete_limit" android:dependency="pref_key_auto_delete" android:summary="@string/pref_summary_delete_limit" android:title="@string/pref_title_mms_delete"... /> </PreferenceCategory> ... </PreferenceScreen>
  49. 49. Autres vues spécifiques •Boîte de dialogue •Toast •Notification
  50. 50. Composants principaux •Activity: gestion du cycle de vie d'une vue •Service: traitement en tâche de fond •BroadcastReceiver: traitement événementiel •ContentProvider: partage de données inter- application •Intent: canal de communication entre composants et applications
  51. 51. Sandbox Chaque application à : •son UID et GUID •son processus et sa VM •son répertoire protégé Une permission dans le manifeste : •doit être validé par l'utilisateurà l'installation •attribut un GUID à l'application Service IPC: via le Binder (Intent, AIDL)
  52. 52. Service Lancer des opérations en arrière plan sans interface graphique et indépendamment de l’utilisation de l’application
  53. 53. Intent présentation Message pour lancer une action d’un composant
  54. 54. Intent envoie Intent intent = newIntent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.youtube.com/watch?v=iwsqFR5bh6Q")); context.startActivity(intent); Intent takePictureIntent = newIntent(MediaStore.ACTION_IMAGE_CAPTURE); context.startActivityForResult(takePictureIntent, 1); Intent i=newIntent(Intent.ACTION_SEND); i.putExtra(Intent.EXTRA_EMAIL, newString[{"imac2011@googlegroups.com"}); i.putExtra(Intent.EXTRA_TEXT, "Ca avance le projet ?"); Intent i2=Intent.createChooser(i, "Choisir..."); context.startActivity(i2); context.startActivity(new Intent(context, SettingsActivity.class)); context.startService(new Intent(context, CurrencyService.class)); Implicite Explicite
  55. 55. Intent réception <receiverandroid:name=".CurrencyReceiver"> <intent-filter> <actionandroid:name="android.intent.action.TIMEZONE_CHANGED"/> <actionandroid:name="android.intent.action.ACTION_BOOT_COMPLETED"/> </intent-filter> </receiver> <activityandroid:name=".YouTubeActivityActivity"> <intent-filter> <actionandroid:name="android.intent.action.VIEW"/> <data android:host="www.youtube.com" android:scheme="http"/> </intent-filter> </activity> Intent filter dans le manifeste
  56. 56. BroadcastReceiver <receiver android:name=".MySMSReceiver"> <intent-filterandroid:priority="100"> <actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver> publicclassMySMSReceiver extendsBroadcastReceiver { privatefinalString ACTION_RECEIVE_SMS= "android.provider.Telephony.SMS_RECEIVED"; @Override publicvoidonReceive(Context context, Intent intent) { if(intent.getAction().equals(ACTION_RECEIVE_SMS)) { Bundle bundle = intent.getExtras(); if(bundle != null) { Object[] pdus = (Object[]) bundle.get("pdus"); finalSmsMessage[] messages = newSmsMessage[pdus.length]; for(inti = 0; i < pdus.length; i++) { messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); } if(messages.length> -1) { finalString messageBody = messages[0].getMessageBody(); finalString phoneNumber = messages[0] .getDisplayOriginatingAddress(); Toast.makeText(context, "Expediteur : "+ phoneNumber, Toast.LENGTH_LONG).show(); Toast.makeText(context, "Message : "+ messageBody, Toast.LENGTH_LONG).show(); } } } } }
  57. 57. Persistance des données 5 méthodes: •Le stockage externe(données publiques) •Le stockage interne •Les préférences •La base de donnéesprivée SQLite •La connexion réseau
  58. 58. Testing •Test unitaire (JUnit) •Test d’interface utilisateur •Mock •…

×