Programmation objets, web et mobiles (JAVA) · Middleware AndroidOS(extrait) • View Systemlistes,...
Transcript of Programmation objets, web et mobiles (JAVA) · Middleware AndroidOS(extrait) • View Systemlistes,...
Programmationobjets,webetmobiles(JAVA)
Licence3Professionnelle- MultimédiaPhilippeEsling ([email protected])Maîtredeconférences– UPMC
Equipereprésentationsmusicales(IRCAM,Paris)
ProgrammationAndroïd
Sommaire• Unpeud'historique• Andoid OScommemiddleware– Applicationsetévènementsgérésparlemiddleware
– UneapprochedéclarativedesIHMenXML– UneconfigurationenXML– LinuxetJava• sanslaJVMmaisavecuneDVM
• Principesdebase• Cen’estqu’uneintroduction…
Android:lesobjectifs
• http://www.android.com• http://www.OpenHandsetAlliance.com“…OpenHandset Alliance™,agroupof47technologyandmobilecompanies havecometogether toaccelerateinnovationinmobileandoffer consumers aricher,lessexpensive,andbetter mobileexperience.
•Together we havedeveloped Android™,thefirstcomplete,open,andfreemobileplatform.•We arecommitted tocommercially deploy handsetsandservicesusing theAndroidPlatform.“
Android ?• Uneplateformeouverte• +unensembledelibrairies,decomposantslogicielspourlessystèmesembarquésetmobiles– Unsystèmed’exploitation
• Linux– Unintergiciel (middleware)– Nombreuseslibrairies
• IHM,• Téléphonie,• Multimédia,• Capteurs,• Internet,cartographie
PourquoiAndroid?
• Indépendantd’unearchitecturematérielle– Avecdescontraintesmatériellesàrespecterparlesintégrateurs
• Dédiéauxsystèmesembarquésmaispasseulement
• AmbitionsdeGoogle/Apple–Marketing– Lesapplications• NombreusesetgratuitessurAndroidMarket• NombreusesetpayantessurAppStore
Applicationsgratuites(2011)
Lesautres
• Apple• Microsoft• Nokia• Palm• Research inMotion(BlackBerry)• Symbian• QuiddeJavaFX etjavaME ?….– javaFX/Flashprometteurmais:
• Lancéen2009,quil’utilise?– http://java.sun.com/javafx/1/tutorials/core/
– javaME obsolète?• Smartphone?Pourlespaysrichesetémergents?
Projections
Android lesgrandeslignes
• ComposantsAndroid• OutilsdeDéveloppement• ArchitectureLogicielle• Développement– enjava(J)– quelquesdirectives– configurationsensyntaxeXML
• Deuxexemples– Démonstration
• Deuxexemplesenquelqueslignesdejava
ComposantsAndroid• Frameworkdedéploiementd’applications• Dalvik commemachinevirtuelle(àregistres!=JVMàpile)
• Navigateurintégré,WebKit (webkit safari,GoogleChrome…)
• SQLite (Basededonnées)• MultimédiasupportPNG,JPG,GIF,MPEG4,MP3• Dépendantdumatériel– GSM– Bluetooth,EDGE,3G,WiFi– Caméra,GPS,boussoleetaccéléromètre– Température,
Outilsdedéveloppement• SDKAndroid
–Enlignedecommandes–Plug-insouseclipse–Émulateur–Débogueur–Tracesfinesd’exécution–Testsunitaires–Outilsdemiseaupoint
•Mesuredemémoireetperformance
ComposantsAndroid
http://developer.android.com/guide/basics/what-is-android.html
AndroidOS
• Un ensemble d’API
– http://developer.android.com/guide/basics/what-is-android.html
MiddlewareAndroid OS (extrait)• ViewSystem listes,boutons,…navigateur(WebView)
• ResourceManager,accèsauxString,auxdescriptifsdelihm– R.java …
• ActivityManager gestionducycledevied’uneapplication– Uneapplicationandroid peutêtrecomposéedeplusieursactivités
• ContentProviders Accèsauxdonnéesd’autresapplications
– partage,persistancededonnées
• NotificationManager autorisedesalertesdanslabarredestatut
• TelephonyManager
Librairies
C/C++…
•SGL comme moteur pour le 2D•FreeType comme fontes de caractères
Dalvik VM,aulieudeJVM
• Machinesàregistres
• ChaqueapplicationàsapropreDVM–Communicationinter-applicationsassuréeparlemiddleware–MultithreadassuréparLinux–AccèsauxcapteursparlenoyauLinux
Développementd’uneapplication
Pourdévelopperuneapplication,nousallonsutiliserEclipseetdesmécanismessimples1. Obtentiondes.class2. Générationdel’APK,(Android Packagefile)
1.Obtentiondes.class
• FichierdeconfigurationXML– UnsourceJavaestgénéré,lefichierderessourcesR.java• Configurationdel’application,IHM,String,…
– Approchedéclarativedel’IHM
• java– Paquetagejava.lang,
• AttentioncenesontpasleslibrairiesduJavaSE(android.jar n’estpasrt.jar)
• Compilateurjavac deSun/Oracle– javac –bootclasspath android.jar android/introduction/*.java
19
1er exercice
• Créer une applicationtrès simple
• Lancersurémulateur• Lancersurtéléphone• Examinersa structure
20
GoogleTutorial
• Commençons parcréer unprojet• (Etvérifier queleSDKEclipsemarche)• StartEclipse(Start->AllPrograms->Eclipse)• CreateanAndroidVirtualDevice(AVD)• CreateaNewAndroidProject
SetupAndroidSDK
21
• DownloadAndroidSDKandextractthezipfiletoanarbitraryfolder– http://androidappdocs.appspot.com/sdk/index.html
– E.g.:extracttoC:\– TheSDKwillbeusedbyADTineclipse
SetupADTplugin
22
• InstallEclipseADTplugin– EclipsemustbeJ2EEedition,3.5recommended
– Updatesite:https://dl-ssl.google.com/android/eclipse/
– Installallthepluginsintherepository
– Restartneededafterinstallation
ConfigureADTPlugin
23
• OpeneclipseWindow->Preferences,selectAndroid
• SetuptheSDKlocationasthefolderwhereyouextractedthedownloadedSDKzipfile
SetupSDKAPIs
24
• OpenWindow->AndroidSDKandAVDManager• ClickAvailablePackagesandthenchooseproperAPIstoinstall,thelatestmaybethebest
SetupEmulators
25
• AfterSDKAPIsinstallation,clickVirtualDevices
• Clicknew,therewillbeadialog– inputaname– choosearunningtargetandaskin
– specifytheSDcardsize
Ready…
26
• NowyoumaystarttheAVD– ClickstarttostartthenewAVD
– Firststart-upmaytakeavery longtime
CreateanewAndroidProject
27
• OpenFile->New->Androidproject– Projectname– BuildTarget– Applicationname– Packagename– CreateActivity
HelloWorldProject
28
• src:sourcefolder• gen:SDKgeneratedfile• android2.2:referencelib• assets:binaryresources• res:resourcefilesandresourcedescriptionfiles
• AndroidManifest.xml:applicationdescriptionfile
• default.properties:projectpropertiesfile
SayHelloWorld
29
• modifyHelloWorld.java
RunHelloWorld
30
• SelectHelloWorld Project,Run->Runas->AndroidApplication
• ADTwillstartaproperAVDandrunHelloWorldapponit
RClass
• Auto-generated:youshouldn’teditit• ContainsIDsoftheprojectresources• Enforcesgoodsoftwareengineering• UsefindViewByIdandResourcesobjecttogetaccesstotheresources– Ex.Buttonb=(Button)findViewById(R.id.button1)– Ex.getResources().getString(R.string.hello));
BehindHelloWorld #1
32
• R.java,generatedbyAndroidSDK,representsalltheresourcesoftheapp.resourcesareallinres folder
• resourcesarepre-compiledintobinaryformat/* AUTO-GENERATED FILE. DO NOT MODIFY.** This class was automatically generated by the* aapt tool from the resource data it found. It* should not be modified by hand.*/package sample.hello;public final class R {
public static final class attr {}public static final class drawable {
public static final int icon=0x7f020000;}public static final class layout {
public static final int main=0x7f030000;}public static final class string {
public static final int app_name=0x7f040001;public static final int hello=0x7f040000;
}}
XML
• Usedtodefinesomeoftheresources– Layouts(UI)– Strings
• Manifestfile• Shouldn’tusuallyhavetoedititdirectly,Eclipsecandothatforyou
• PreferredwayofcreatingUIs– Separatesthedescriptionofthelayoutfromanyactualcodethatcontrolsit
– CaneasilytakeaUIfromoneplatformtoanother
LinearLayout
BehindHelloWorld #2
34
• res/layout,containslayoutdeclarationsoftheapp,inXMLformat,UIsarebuiltaccordingtothelayoutfile
main.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout
xmlns:android=http://schemas.android.com/apk/res/androidandroid: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" />
</LinearLayout>
TextView,displaystatictext
AreferencetoStringresource
‘hello’
Strings
• Inres/values– strings.xml
• Applicationwideavailablestrings• Promotesgoodsoftwareengineering• UIcomponentsmadeintheUIeditorshouldhavetextdefinedinstrings.xml
• Stringsarejustonekindof‘Value’therearemanyothers
referencedinres/layout/mai
n.xml
BehindHelloWorld #3
36
• res/values,containsstringdeclarationsorothervalues(e.g.:colors)oftheapp– string.xml,containsstringresources
<?xml version="1.0" encoding="utf-8"?><resources>
<string name="hello">Hello World, HelloWorld!</string><string name="app_name">HelloWorld</string>
</resources>
referencedinAndroidManifest.xml
BehindHelloWorld #4
37
• res/drawable,containsallimageresources– foldersmayhavesuffixes,appwillchoosethemostsuitableone,sodotheotherresources
– threefolders:drawable-ldpi,drawable-hdpi,drawable-mdpi,eachcontainsanicon.pngfile
– appwillchoosethepropericonaccordingtothedeviceDPI
– referencename:@drawable/icon• otherfolderswemayuseinfuture– menu,anim (animation),xml(preferenceandsearchable)
BehindHelloWorld #5
38
• AndroidManifest.xmldescribetheapplication– declareapp’sname,version,icon,permission,etc…– declaretheapplication'scomponents:activity,service,receiverorprovider
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="sample.hello" android:versionCode="1" android:versionName="1.0"><application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".HelloWorld" android:label="@string/app_name"><intent-filter>
<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.LAUNCHER”/>
</intent-filter></activity>
</application><uses-sdk android:minSdkVersion="8" /></manifest>
ManifestFile(1)
• Containscharacteristicsaboutyourapplication• WhenhavemorethanoneActivityinapp,NEEDto
specifyitinmanifestfile– Gotographicalviewofthemanifestfile– AddanActivityinthebottomright– Browseforthenameoftheactivity
• NeedtospecifyServicesandothercomponentstoo• Alsoimportanttodefinepermissionsandexternal
libraries,likeGoogleMapsAPI
ManifestFile– AddinganActivity
AndroidProgrammingComponents
• Activity– http://developer.android.com/guide/topics/fundamentals/activities.html
• Service– http://developer.android.com/guide/topics/fundamentals/services.html
• ContentProviders• BroadcastReceivers• Androidinanutshell:
– http://developer.android.com/guide/topics/fundamentals.html
Activities(1)
• Thebasisofandroidapplications• AsingleActivitydefinesasingleviewablescreen– theactions,notthelayout
• Canhavemultipleperapplication• Eachisaseparateentity• Theyhaveastructuredlifecycle– Differenteventsintheirlifehappeneitherviatheusertouchingbuttonsorprogrammatically
Activities(2)
@2011 Mihail L. Sichitiu 44
Activity
• AnAndroidactivityisfocusedonasinglethingausercando.
• Mostapplicationshavemultipleactivities
@2011 Mihail L. Sichitiu 45
Activitiesstarteachother
Services(1)
• Runinthebackground– CancontinueevenifActivitythatstarteditdies– Shouldbeusedifsomethingneedstobedonewhiletheuserisnot
interactingwithapplication• Otherwise,athreadisprobablymoreapplicable
– Shouldcreateanewthreadintheservicetodoworkin,sincetheservicerunsinthemainthread
• Canbeboundtoanapplication– Inwhichcasewillterminatewhenallapplicationsboundtoitunbind– Allowsmultipleapplicationstocommunicatewithitviaacommon
interface• Needstobedeclaredinmanifestfile• LikeActivities,hasastructuredlifecycle
Services(2)
Exercice 2
48
• Buildupanappthatyoucaninputyourgreetingsanddisplayyourgreetings– Input:EditText– Display:TextView– Ofcourse,wehavetoaddanbutton
• Editres/layout/main.xmlfiletoaddthesecomponents– eachhasanandroid:id property,usedtoreferenceitincode
Cheat – Lookatthe« Layout tab »atthebottom ofEclipseJ
BeyondHelloWorld #2
49
• modifyHelloWorld.java– firstlygetthereferencesdeclaredinmain.xml
– thenaddeventresponseforButton
BeyondHelloWorld #3
50
• Finished!• Run->Runas->AndroidApplication
• Quiteeasy,isn’tit?
RunninginEclipse(1)
• SimilartolaunchingaregularJavaapp,usethelaunchconfigurations
• SpecifyanAndroidApplicationandcreateanewone
• Specifyactivitytoberun• Canselectamanualoption,soeachtimeprogramisrun,youareaskedwhetheryouwanttousetheactualphoneortheemulator– Otherwise,itshouldbesmartandusewhicheveroneisavailable
RunninginEclipse(2)
RunninginEclipse(3)
RunninginEclipse(4)
@2011 Mihail L. Sichitiu 55
Introduceabugpackagecom.example.helloandroid;
importandroid.app.Activity;importandroid.os.Bundle;
publicclassHelloAndroidextendsActivity{/**Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);Objecto=null;o.toString();setContentView(R.layout.main);
}}
@2011 Mihail L. Sichitiu 56
Runit!
USBDebugging
• Shouldbeenabledonphonetousedeveloperfeatures
• InthemainappsscreenselectSettings->Applications->Development->USBdebugging(itneedstobechecked)
AndroidDebugBridge
• Usedforawidevarietyofdevelopertasks– Readfromthelogfile– Showwhatandroiddevicesareavailable– Installandroidapplications(.apkfiles)
• Inthe‘platform-tools’directoryofthemainandroidsdkdirectory– Recommendputtingthisdirectoryandthe‘tools’directoryonthesystempath
• adb.exe
Debugging
• InsteadofusingtraditionalSystem.out.println,usetheLogclass– Importedwithandroid.util.Log– Multipletypesofoutput(debug,warning,error,…)– Log.d(<tag>,<string>)
• Canbereadusinglogcat.– Printoutthewholelog,whichauto-updates
• adblogcat– Eraselog
• adblogcat–c– Filteroutputviatags
• adblogcat<tag>:<msgtype>*:S• canhavemultiple<tag>:<msgtype>filters• <msgtype>correspondstodebug,warning,error,etc.• IfuseLog.d(),then<msgtype>=D
• Reference– http://developer.android.com/guide/developing/debugging/debugging-log.html
res/layout/main.xml• Declareslayouts&widgetsfortheactivity
60Treefrom:http://developer.android.com/guide/topics/ui/index.html
VariousLayouts
http://developer.android.com/resources/tutorials/views/index.html 61
VariousWidgets
http://developer.android.com/resources/tutorials/views/index.html62
@2011 Mihail L. Sichitiu 63
HelloAndroid.java
package com.example.helloandroid;
import android.app.Activity;import android.os.Bundle;public class HelloAndroid extends Activity {
/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main);
}}
Set the layout of the view as described in the main.xml layout
Développement1/2Fichierdeconfiguration,AndroitManifest.xml<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.biblio"android:versionCode="1"android:versionName="1.0">
<uses-permissionandroid:name="android.permission.INTERNET" />
<applicationandroid:icon="@drawable/icon" android:label="@string/app_name"><activity android:name=".Demo"
android:label="@string/app_name">
<intent-filter><actionandroid:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />
</intent-filter></activity>
</application>
</manifest>
FichierdeRessourcesXMLassocié
• Répertoireres/–Projeteclipse
• res/layout/main.xml
<?xmlversion="1.0" encoding="utf-8"?><LinearLayoutandroid:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent">…</LinearLayout>
FichierdeRessourcesXMLassocié<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/TextViewPrenom’android:layout_width="fill_parent »android:layout_height="wrap_content »android:text="@string/prenom »/>
<LinearLayout android:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content »>
<EditText android:id="@+id/EditTextPrenom"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:layout_gravity="bottom"android:hint="@string/prenomHint »/>
<Button android:id="@+id/ButtonEnvoyer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/bouton »/>
</LinearLayout>
<TextView android:id="@+id/TextViewHello"android:layout_width="wrap_content"android:layout_height="fill_parent"android:layout_gravity="center_horizontal"android:textSize="@dimen/dimMessage"android:textColor="@color/couleurMessage »/>
</LinearLayout>
LefichierR.java
• /test/biblio/R.javaAUTO-GENERATEDFILE.DONOTMODIFY.
package test.biblio;public final class R {…public static final class layout {public static final intmain=0x7f030000;
}}
Unpremiersourcejava,justepourlasyntaxe…
packagetest.biblio;import android.app.Activity;import android.os.Bundle;
public class Demo extends Activity {….
@Overridepublicvoid onCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.main);//associationIHM<->Activity….
}}
package test.biblio;public final class R {…public static final class layout {public static final intmain=0x7f030000;
}}
Unpremiersourcejava,justepourlasyntaxe…
public class Demo extends Activity {private EditText editText;private Button button;
publicvoid onCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.main);//association//récupérationdel'EditText grâceàsonIDeditText =(EditText)findViewById(R.id.EditTextPrenom);//récupérationduboutongrâceàsonIDbutton =(Button)findViewById(R.id.ButtonEnvoyer);//onappliqueunécouteurd'évenement aucliquesurleboutonbutton.setOnClickListener(newOnClickListener(){
@Overridepublicvoid onClick(View v){
??//Onrécupèreletexteécritdansl'EditText??//Oncréeunepop-upToast??//Onaffecteletextedansl’objetTextView
}}
);}}
Obtentiondel’application
• Detousles.classen.dex– DelaJVMàlamachineDalvik– D’unemachineàpileenmachineàregistres
• Générationdel’application.apk– Unearchivesignée– Téléchargement:émulateuroumobile
Générationdel’application
Source:http://stuffthathappens.com/blog/wp-content/uploads/2008/11/android_flow.png
Développement2/2,suite
• Du.classen.dex– Assemblagedetousles.classversun.dex– Unemachineparapplication,unprocessusLinux
– Lesapplicationscommuniquentvial’intergiciel• Uneapplicationpeutêtrecomposéedeplusieursactivités• Lesactivitéscommuniquentviadesvariablesglobales,delamémoirepersistante,…
• Générationdel’application.apk– Assemblage,éditiondesliens– Unearchivesignée
– Téléchargement:émulateuroumobile
IntroductionauxApplications• Uneprésentation,unvocabulaire
• Mots-clés– Applications,– Communication,évènements,intentions,– Servicesentâchedefond,– Persistance.
• UneApplicationestcomposéed’uneoudeplusieursActivity– Uneactivity– Surchargedecertainesméthodes,
• Dudéjàvu:Applet,MIDlet,Servlet,…
– Lecycledevieestimposéparleframework• Déjàvu:pouruneAppletteinit()puisstart()…
Vocabulaire
• LesEssentiels
– Activity– BroadcastReceiver– Service– ContentProvider
Introduction…Classes• Activity
– Uneinterfaceutilisateur• Démarred’autresactivités,émetdesévènements(intentions,intent)
– UneconfigurationdetypeXML,permissions,librairies,
• BroadcastReceiver– Busdemessages– Émissionetréceptiond’intentions
• Service– Pasd’interface,unserviceàrendre,entachedefond– Intention deservir
• ContentProvider– Donnéesrenduespersistantes(pourd’autresapplications)– Unfichier,baseSQLite
Deuxexemples,deuxActivity
1. Installationd’unnavigateuren2lignes(WebView)
2. UnetoutepetiteIHM• Unécranconstituéd’unbouton,d’unécouteur,• Achaqueclic,l’heureestaffichée!
Activity UsageduWebKitimport android.app.Activity;import android.os.Bundle;import android.webkit.WebView;
public class BrowserDemo extends Activity {privateWebView browser;@Overridepublic void onCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);browser=(WebView)findViewById(R.id.webWiew);browser.loadUrl("http://upmc.fr/");
}}
2lignes
OnCreateestdéclenchéparleframeworkAndroid
public class BrowserDemo extends Activity {private WebView browser;@Overridepublic void onCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);
//installationdel’IHMsetContentView(R.layout.main);
//accèsaucomposantgraphiquebrowser=(WebView)findViewById(R.id.webView);
browser.loadUrl("http://www.upmc.fr/");}
} R.layout.main, R.id.webView ?
RetoursurlaconfigurationXML• R.id.webView?R.layout.main?
– EnEntrée•FichiersdeconfigurationXML
–EnSortie•SourceJava,R.java
UneIHM,deuxièmeexemple
UneIHM
• Unbouton,unécouteur,unclicetl’heureestaffichée!
• Enapprochetraditionnelle• ToutestcodéenJavaIHMcomprise
– Enapprochedéclarative• Usaged’XMLpourlaconfiguration,dejavapour
l’utilisation
Clickpouractualiserl’heureimport android.app.Activity; import android.os.Bundle; import static android.view.View.OnClickListener ;import android.widget.Button; import java.util.Date;
public class Now extends Activity implements OnClickListener { private Button btn;
@Overridepublic void onCreate(Bundle bundle) {super.onCreate(bundle); btn = new Button(this); // <- un boutonbtn.setOnClickListener(this);// <- un écouteur auprès de cette vue
setContentView(btn); // <- le bouton occupe l’écran}
public void onClick(View view) { // <- à chaque clickbtn.setText(new Date().toString());
} }
Discussion:VueapparentéeswingIciunMVCàluitoutseul…
Activity,méthodesàredéfinir
• MonActivityextendsandroid.app.Activity;
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){
CoreComponents-Activity#1
83
• Basically,Anactivity presentsavisualuserinterfaceforonefocusedendeavortheusercanundertake
• Anapplicationmightconsistofjustoneactivityorseveral,eachActivityisderivedfromandroid.app.ActivityandshouldbedeclaredinAndroidManifest.xmlfile
• Eachactivityisgivenadefaultwindowtodrawin,thewindowmaybefullscreenorsmallerandontopofotherwindow
• Thevisualcontentofthewindowisprovidedbyahierarchyofviews— objectsderivedfromthebaseViewclass
• Activity.setContentView()methodisusedtosetacertainhierarchyofviewobjects
CoreComponents-Activity#2
84
• Activitiesareactivatedbyasynchronousmessagescalledintents– AnintentisanIntentobjectthatholdsthecontentofthemessage
– TheactionbeingrequestedortheURIofthedatatoacton• The<intent-filter>labelinAndroidManifest.xmlfilespecifiestheIntentthatcanstarttheActivity
– declaresthemainactivity,itwillbestartedautomaticallywhentheappstarts
• Anactivityislaunched(orgivensomethingnewtodo)bypassinganIntentobjecttoContext.startActivity()orActivity.startActivityForResult()
OtherCoreComponents
85
• Service– Aservice doesn'thaveavisualuserinterface,runsinthebackgroundforaperiodoftime
• Broadcastreceivers– acomponentthatdoesnothingbutreceiveandreacttobroadcastannouncements
• Contentproviders– Acontentprovidermakesaspecificsetoftheapplication'sdataavailabletootherapplications.
– Thedatacanbestoredinthefilesystem,inanSQLitedatabase,orinanyothermannerthatmakessense
android.app.Activitypackageandroid.app;
publicclassActivity extends ApplicationContext {
protected void onCreate(BundlesavedInstanceState){
protected void onStart();
protected void onRestart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestroy();
…etc …}
induituncycledevieimposéparle« framework »
InversiondeContrôle…Rappel
public class Activity extends ApplicationContext {
protected void onCreate(Bundle savedInstanceState);
protected void onStart();
…..}
Android,middleware
http://developer.android.com/reference/android/app/Activity.html
onCreate(..)onStart();
Activ
ités
activité_1 Activité2 Activité3
1
…activité_1=newActivité_1();activité_1.onCreate();activité_1.onStart();….
Petitesprécisions,rappels…
• Uneapplications’exécutedansunprocessusLinux
• Depuisceprocessus– lesméthodesd’uneactivitésontappeléesselonuncertainordre• onCreate …onPause….onResume…onPause….onResume…onDestroy
– L’appeldeonDestroy n’engendrepasl’arrêtduprocessusinitiateur
Démonstration,Activity danstoussesétats
public class BrowserDemo extends Activity {
private WebView browser;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("=======","onCreate");
// cf. page précédente
}
public void onDestroy(){
super.onDestroy();
Log.i("******", "onDestroy");
}
}
Enrésumé:émulateur+LogCat,tracesbienutiles
Activity danstoussesétatspublic class BrowserDemo extends Activity {
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.i("=======","onCreate");}
public voidonStart(){super.onStart();Log.i("=======","onStart");}
public void onResume(){super.onResume();Log.i("=======","onResume");
}
public void onPause(){super.onPause();Log.i("=======","onPause");
}
public void onStop(){super.onStop();Log.i("******","onStop");
}
public void onDestroy(){super.onDestroy();Log.i("******", "onDestroy");
}}
Vouspouveztoutsimuleravectelnet
1) telnetlocalhost5554
2-2)
3)
2-1)
OnPause
OnResume
2)
OnPause->onResume
Intentionde…porteruntoast
• IntentToast.makeText(context,intent.getStringExtra("message"),3000).show();
Toast!
Android:Intents,commeIntention
Il faut : • Un receveur
public class Receiver extends BroadcastReceiver {public void onReceive(Context context, Intent intent) {….
• Enregistrementauprèsdumiddleware• Uneintentiond’émettre• Ajusterlaconfiguration
sendBroadcast
Activ
ités
activité_1
extendsBroadcastRececeiveronReceive(){…}
<receiver android:name=".TestBroadcastReceiver"android:label="TestBroadcast receiver"/>
Intentionde
• Intent.ACTION_AIRPLANE_MODE_CHANGED,unabonnéàcetIntent
Émissiondel’intention:notificationintent=newIntent("PORTER_UN_TOAST");intent.putExtra("message",getResources().getString(R.string.message));sendBroadcast(intent);
Enregistrementauprèsdumiddleware:abonnementReceiverreceiver=newReceiver();registerReceiver(receiver,newIntentFilter("PORTER_UN_TOAST"));registerReceiver(receiver,newIntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
Unreceveur,quiporteuntoast:abonnépublicstaticclassReceiverextendsBroadcastReceiver{publicvoidonReceive(Contextcontext,Intentintent){Toast.makeText(context,intent.getStringExtra("message"),3000).show();}}
Intention…auprèsdumiddleware
• Intent.ACTION_AIRPLANE_MODE_CHANGED,jesuismaintenantabonnéàcetIntent
Enregistrementauprèsdumiddleware:Receiverreceiver=newReceiver();registerReceiver(receiver,newIntentFilter("PORTER_UN_TOAST"));
registerReceiver(receiver,newIntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
AvecprivatestaticfinalStringSMS_RECEIVED ="android.provider.Telephony.SMS_RECEIVED";
et
registerReceiver(receiver,newIntentFilter(SMS_RECEIVED));
Je suis maintenant abonné aux réception de SMS(si la permission est installée dans le AndroidManifest.xml)
SousAndroid
• Mediator,classeContext– http://developer.android.com/reference/android/content/Context.html
• Subscriber,classeBroadcastReceiver– http://developer.android.com/reference/android/content/BroadcastReceiver.html
• X,Ylesthèmes,classeIntent– http://developer.android.com/reference/android/content/Intent.html
• IntentFilter– http://developer.android.com/reference/android/content/IntentFilter.html
IntentiondetéléphonerJ
• Intent
• CommeCommunication
• Démarreruneactivitéprédéfinie:téléphoner
IntentiondetéléphonerpublicclassTelephoneextendsActivityimplementsOnClickListener {
publicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);((Button)this.findViewById(R.id.Button01)).setOnClickListener(this);
}
publicvoidonClick(Viewv){Intentintent=newIntent(Intent.ACTION_DIAL);startActivity(intent);
}}
EnImages,activitédetéléphoner
Clickempiler
Clickdépiler
Activitésunrésumé• Activity
– Cycledevie– Géréparleframework
• startActivity– Uneactivitépeutendémarreruneautre– Transmissiondesparamètresparlesintentions
• Communicationentredeuxactivités– Discussion
• UneApplicationpeutcontenirplusieursactivités– Communicationentreactivitésd’applicationsdifférentes
• Exempledescontacts
Service• Entachedefond
• Toujoursdisponible
– Locaux• Servicepersonnel,inaccessiblepourlesautresapplications
– Distants• Rmienplussimple…mêmemachine
• J’écouteunfichieraudiomp3,pendantquejenaviguesurleweb
UnService
• Servicedistant,– Découverteduserviceparuneintention…
Android,middleware
Activ
ités
activité_1 Activité2 service
Services
SMSService:unexemple• UncompteurdeSMSreçus
– Achaquesmsreçuuncompteurestincrémenté– Serviceaccessiblepartouteapplication
• Leserviceal’intentionderecevoirdesSMS– IntentFilterfilter=newIntentFilter(SMS_RECEIVED);– registerReceiver(newSMSReceiver(),filter);
• Unclientrechercheraceservicevialemiddleware
• Leservice:SMSService
Service,aidl(androidinterfacedescriptionlanguage)packagecnam.android;
interfaceSMSService{voidstart();voidstop();longreceived();}
/*Thisfileisauto-generated.DONOTMODIFY.*/packagecnam.android;import…;publicinterfaceSMSServiceextendsandroid.os.IInterface{
/**Local-sideIPCimplementationstubclass.*/publicstaticabstractclassStubextendsandroid.os.Binderimplementscnam.android.SMSService{…
LeClientrechercheleserviceprivateSMSServicestatsSMS;
bindService(new Intent(SMSService.class.getName()), connexion, Context.BIND_AUTO_CREATE);
}
// Traitement asynchrone de la réponse venant de l’intergiciel
private ServiceConnection connexion = new ServiceConnection() {public void onServiceConnected(ComponentName name, IBinder service) {Log.v("service","onServiceConnected()");
// réception de la soucheClient.this.statsSMS = SMSService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName name) {Client.this.statsSMS = null;
}};
Leservice1/3,réveilléàchaqueSMSpublic class SMSServiceImpl extends Service {
private static final String TAG = "SMSServiceImpl";private static final String SMS_RECEIVED =
"android.provider.Telephony.SMS_RECEIVED";
private boolean active;private int countSMSReceived;
public void onCreate() {super.onCreate();IntentFilter filter = new
IntentFilter(SMS_RECEIVED);registerReceiver(new SMSReceiver(), filter);
}
Leservice2/3,réveilléàchaqueSMSprivate class SMSReceiver extends BroadcastReceiver{
public SMSReceiver(){
Log.v("SMSReceiver","SMSReceiver()");
}
@Override
public void onReceive(Context context, Intent intent) {
Log.v("SMSReceiver","onReceive()");
if(active) SMSServiceImpl.this.countSMSReceived++;
}
}
Leservice3/3,Lasouchelestubfournieàlademande
public IBinder onBind(Intent arg0) {return new SMSServiceStubImpl();
}
public class SMSServiceStubImpl extends SMSService.Stub{
public long received() throws android.os.RemoteException{return SMSServiceImpl.this.countSMSReceived;
}
public void start(){active = true;
}public void stop() throws RemoteException {active = false;
}}
<serviceandroid:name=".SMSService"android:label="monservicedeSMS"/>
LeClient,uneactivity
1. bind service2. start SMS count
telnet localhost 55543. sms send 12345 test
Servicescycledevie
ContentProvider• Sauvegardeetrestitutiondedonnées– Donnéesaccessiblesàtoutesapplications
• ContentProvider
– Persistance
– DAO/CRUD
• DataAccessObject• CreateRetrieveUpdateetDelete
MesContacts,unclientleContentProvider prédéfini:phone
ContentProvider• ContentProvider,commelescontacts,accès
– ContentResolverresolver =getContentResolver();
Identificationdubon« Contentprovider »grâceàsonURI
– Uriuri=android.provider.Contacts.Phones.CONTENT_URI;– Strings=uri.toString();– //asserts.equals("content://contacts/phone");
– Appelderesolver.query• Pouruneinterrogation
– Parcoursàl’aided’un« Cursor »
CursorcommeResultSet
SonpropreContentProvider• publicclassMonPropreProvider extendsContentProvider
• Avec– UneUri,l’accèsàmonpropre« contentprovider »
• content://cnam.android.agenda/liste• content://….
– Lesméthodes• insert,update,deleteetquery
– Etdanslefichierdeconfiguration<providerandroid:name="MonPropreProvider"
android:authorities="cnam.android.agenda" />
Exercicefinal• UneapplicationSMS
– 3Views• Contactsandstats• SMSCheck• Parameters
– NActivities (?)– 1Service– SMSreceive– L’applicationdoitauminimum
• Récupérerlalistedescontacts• Permettrededéfinirunensembledemessagestypes• Affichertouteslesinformations
– Cycledevie• L’applicationrécupèrelesSMS• Calculedesstatistiques(nombredemessageparcontact)• EffectueunenvoiautomatiquedeSMSderéponseenfonctiondesstats etdes
messagespré-enregistrés deréponse– Bonus?
P.Esling- JAVA- Cours1.Fondamentaux 117
Communicationinterapplications• Intent,commenotification
– Souscription/Publication
– Appeler,déclencheruneautreactivité• Avecéventuellementdesparamètresetdesrésultatsattendus
– L’intergicielsélectionnela« bonneapplication »• Selonlescritèresexigésparlesouscripteur• Critèrespréciséslorsdelapublication
– Nécessaireadéquationàl’exécutionservicesfournis/servicesrequis
PatronPublish-Subscribe/Intent
• Source:http://roboticswikibook.org,rappel
SousAndroid
• Mediator,classeContext– http://developer.android.com/reference/android/content/Context.html
• Subscriber,classeBroadcastReceiver– http://developer.android.com/reference/android/content/BroadcastReceiver.html
• X,Ylesthèmes,classeIntent– http://developer.android.com/reference/android/content/Intent.html
• IntentFilter– http://developer.android.com/reference/android/content/IntentFilter.html
3Exemples1. Unpublisher s’adresseàl’intergiciel– Uneactivitésouhaitetéléphoner…
• Àlarecherched’uneapplicationprédéfinie
2. Unsubscriber deSMSentrants– UneactivitésouhaitefiltrerlecontenudesSMSentrants…
• Installationd’unReceiver
3. Unpublisher etunsubscriber• Uneactivitésouhaitepublierunrésultatàl’intention
d’autresactivités• Lepublisherd’adresseàl’intergicielquisélectionnelesabonnés
Publisher:Unmobileàl’Intentiondetéléphoner
• Intent• Démarreruneactivitéprédéfinie:téléphoner,légitime…
public class TelephonerActivity extends Activity {
@Overrideprotected void onCreate(Bundle bundle) {super.onCreate(bundle);setContentView(R.layout.activity_now);
}
public void onClick(View view) {
Intent intent = new Intent();intent.setAction("android.intent.action.DIAL");this.startActivity(intent);
}
}
• android.app.Activity extends ….. extends android.content.Context
Publisher :Téléphoner• Lesouscripteuradûdéjàsouscrire…
• DiscussionsIntent intent = new Intent();intent.setAction("android.intent.action.DIAL");
– ÀlarecherchedelabonneapplicationeffectuéeparAndroid• Iciunnom("android.intent.action.DIAL");
• Plusieurséluspossibles• Composantlogiciels,• Maintenance• …
• Lepatronchaînederesponsabilitésestutilisé
Subcriber :RecevoirunSMS(souscrire)
– Lesouscripteurhéritedeandroid.content.BroadcastReceiver• Etimplémentecequ’ilfautfairelorsdelanotification
public class ReceiverSMS extends BroadcastReceiver{// à chaque SMS reçupublic void onReceive(Context ctxt, Intent intent) {// }
}
//àchaqueSMSreçu?
Adéquationintention(Intent)ReceiverSMS parunfiltre(IntentFilter)
Réalisation : tout en java ou directives XML …
– Toutjava:unreceveur/souscripteurauseind’uneactivité
public class SMSActivity extends Activity {
private static class ReceiverSMS extends BroadcastReceiver{// à chaque SMS reçupublic void onReceive(Context ctxt, Intent intent) {// … }}
protected void onCreate(Bundle bundle) {super.onCreate(bundle);
final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
IntentFilter filter = new IntentFilter(SMS_RECEIVED);registerReceiver(new ReceiverSMS(), filter);
setContentView(R.layout.activity_now);}
Subcriber :RecevoirunSMS(souscrire)
Subcriber :Lereceveurendéclaratif<receiver android:name=".ReceveurDeSMS"android:exported="true" ><intent-filter android:priority="9999">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter>
</receiver>
public class ReceveurDeSMS extends BroadcastReceiver{// à chaque SMS reçupublic void onReceive(Context ctxt, Intent intent) {// }
}
Chaîne de responsabilités
Publish/SubscribePlusieursReceveurs/souscripteurs,
l’undeuxpeutarrêterlapropagation,
uneprioritépeutêtreaffectéàchaquereceveur
Lalistedessouscripteursserait-elle:uneChaînederesponsabilitésavecpriorités?
Patronpublish/subscribe « Overtheair »• GoogleCloudMessaging
• Android2.2
• Message<=4ko
• Traficillimité– NécessiteuneinscriptionauprèsdeGoogle
• Avecdepréférenceuncomptegmaildédié
Publish/Subscribe « Overtheair »
• 1)Souscription
Publish/Subscribe « Overtheair »
• 2)Publication
Publish/Subscribe« Overtheair »
• 3)Notification
Publish/Subscribe « Overtheair »
• 3)Notification• Suiteetfin
SMSSending
• STEP1– IntheAndroidManifest.xml file,
addthetwopermissions-SEND_SMSandRECEIVE_SMS.
• STEP2– Inthemain.xml,addTextview
todisplay"Enterthephonenumberofrecipient“and"Message"
– EditText withidtxtPhoneNoandtxtMessage
– AddthebuttonID"SendSMS“
SMSSending
• Step3ImportClassesandInterfacesimport android.app.Activity;import android.app.PendingIntent;import android.content.Intent;import android.os.Bundle;import android.telephony.SmsManager;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;
SMSSending� Step4WritetheSMSclasspublic class SMS extends Activity {Button btnSendSMS;
EditText txtPhoneNo;
EditText txtMessage;
/** Called when the activity is first created. */@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnSendSMS = (Button) findViewById(R.id.btnSendSMS);
txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo);txtMessage = (EditText) findViewById(R.id.txtMessage);
btnSendSMS.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { String phoneNo = txtPhoneNo.getText().toString();
String message = txtMessage.getText().toString();
if (phoneNo.length()>0 && message.length()>0)
sendSMS(phoneNo, message); else
Toast.makeText(getBaseContext(), "Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();}
});
} }
Inputfromtheuser(i.e.,thephoneno,textmessageand
sendSMS isimplemented).
SMSSending
� Step5◦ TosendanSMSmessage,youusetheSmsManagerclass.AndtoinstantiatethisclasscallgetDefault()staticmethod.◦ ThesendTextMessage()methodsendstheSMSmessagewithaPendingIntent.◦ ThePendingIntent objectisusedtoidentifyatargettoinvokeatalatertime.
private void sendSMS(String phoneNumber, String message) {PendingIntent pi = PendingIntent.getActivity(this, 0,new Intent(this, SMS.class), 0);
SmsManager sms = SmsManager.getDefault();sms.sendTextMessage(phoneNumber, null, message, pi, null);
}
SMSSending
ReceivingSMS
• Step1
ReceivingSMS
• Step2– IntheAndroidManifest.xml fileaddthe<receiver>elementsothatincoming
SMSmessagescanbeinterceptedbytheSmsReceiver class.<receiverandroid:name=".SmsReceiver">
<intent-filter><actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter></receiver>
ReceivingSMS
• Step3import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.widget.Toast;
ReceivingSMS� Step4
public class SmsReceiver extends BroadcastReceiver {
@Overridepublic void onReceive(Context context, Intent intent) {
//---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
if (bundle != null){
//---retrieve the SMS message received---Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n"; }
//---display the new SMS message---
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}
}
}
IntheSmsReceiver class,extendtheBroadcastReceiver classand
overridetheonReceive()method.ThemessageisattachedtotheIntent
ThemessagesarestoredinaobjectarrayPDUformat.Toextracteachmessage,youusethestaticcreateFromPdu()methodfromtheSmsMessage class.TheSMSmessageisthendisplayedusingtheToastclass
ReceivingSMS
GPS:AddLocationManagerpublic class GPSSimulator extends Activity {
private LocationManager lm;private LocationListener locationListener;
// Called when the activity is first created.@Overridepublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.main);
// use the LocationManager class to obtain GPS locationslm = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
} }
private class MyLocationListener implements LocationListener {
@Overridepublic void onLocationChanged(Location loc) {
if (loc != null) {Toast.makeText(getBaseContext(),
"Location changed : Lat: " + loc.getLatitude() + " Lng: " + loc.getLongitude(), Toast.LENGTH_SHORT).show();
}}
@Overridepublic void onProviderDisabled(String provider) {
// TODO Auto-generated method stub}
@Overridepublic void onProviderEnabled(String provider) {
// TODO Auto-generated method stub}
@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub}
}
GPS:AddLocationManager
TesttheGPSSimulator
• TotestinEclipse:1. SwitchtoDDMSview.2. FindtheLocationControlsintheEmulator
Controltab.3. ClicktheGPXtabandclickLoadGPX.4. LocateandselecttheGPXfile.5. ClickPlaytobeginsendingcoordinatestothe
Emulator.
AddabilitytouseGoogleMaps
� UpdatetheManifestwithtwolines.<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.GPSSimulator">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<uses-library android:name="com.google.android.maps" />
<activity android:name=".GPS" 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>
AddMapView tomain.xml<?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">
<com.google.android.maps.MapViewandroid:id="@+id/mapview1"android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey=“Your API Key Here" />
</LinearLayout>
GPSSimulator touseGoogleMapspublic class GPSSimulator extends MapActivity { private LocationManager lm;private LocationListener locationListener;private MapView mapView;private MapController mc;
// Called when the activity is first created.@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);
// use the LocationManager class to obtain GPS locationslm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new MyLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
mapView = (MapView) findViewById(R.id.mapview1);mc = mapView.getController();
}
@Overrideprotected boolean isRouteDisplayed() {return false;
}
private class MyLocationListener implements LocationListener {
@Overridepublic void onLocationChanged(Location loc) {
if (loc != null) { Toast.makeText(getBaseContext(), "Location changed : Lat: " + loc.getLatitude() + " Lng: " + loc.getLongitude(), Toast.LENGTH_SHORT).show();
GeoPoint p = new GeoPoint((int) (loc.getLatitude() * 1E6), (int) (loc.getLongitude() * 1E6));mc.animateTo(p);mc.setZoom(16); mapView.invalidate();
}}
@Overridepublic void onProviderDisabled(String provider) {}
@Overridepublic void onProviderEnabled(String provider) {}
@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}
} }
ViewtheLocationontheMap
InternetLayers� TheInternet,isbasedonalayered
architecturecalledtheTCP/IPstack.� LinkLayer◦ Protocols:ARPandRARP
� InternetLayer◦ Protocols:IP,ping,etc.
� Transport◦ Protocols:TCPandUDP
� ApplicationLayer◦ Protocols:HTTP,FTP,DNS,etc.
Client-ServerCommunication
• AservermachineisidentifiedontheInternetbysomeIPaddress
• Daemonsaretheprocessesrunninginthebackgroundwhicharelisteningallthetimeforconnectionrequestsfromclientsonaparticularportnumber.
• Onceaconnectionrequestcomesintotheserveronagivenport,thecorrespondingdaemoncanchoosetoacceptit,andifso,aconnectionisestablished.
• Thentheapplicationlayerprotocolistypicallyusedfortheclienttogetorsenddatatotheserver.