Projet Android (LI260) Cours 3 - Laboratoire d`Informatique de Paris 6

Transcription

Projet Android (LI260) Cours 3 - Laboratoire d`Informatique de Paris 6
Quelques rappels
Services et communication simple
Projet Android (LI260)
Cours 3
Nicolas Baskiotis
Université Pierre et Marie Curie (UPMC)
Laboratoire d’Informatique de Paris 6 (LIP6)
S2 - 2013/2014
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Plan
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Rappel : démarrer une activité
Problème
•
chaque activité dans un processus séparé
⇒ communication entre activités impossible directement (appel de méthodes, passage de
paramètres, lecture de variables . . . )
•
solution facile : Intent ! (l’action voulue, les données, . . . )
Deux modes :
•
Deux types d’activités :
sans “filtrage” de retour :
•
new
Intent(Context,Class<?>)
• avec retour :
startActivityForResult(Intent, • implicite : new Intent(String
action, [Uri uri])
int reqcode)
startActivity(Intent)
explicite :
Gestion du retour :
•
dans l’activité appelée :
(new Intent()).putExtra(String key, XXX
val)
•
dans l’activité d’origine :
v o i d onResult ( i n t reqcode , i n t rescode , I n t e n t i n t e n t ){
i f ( ( reqcode== REQ) && ( rescode = ACTION OK ) ) {
i n t e n t . g e t S t r i n g E x t r a ( key ) ;
}}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Exemple
p u b l i c c l a s s M a i n A c t i v i t y extends A c t i v i t y {
...
o n C l i c k B u t t o n 1 ( View v ) {
I n t e n t i n t e n t =new I n t e n t ( M a i n A c t i v i t y . t h i s , S e c o n d A c t i v i t y . c l a s s ) ;
startActivityForResult ( intent , 1);
}
o n C l i c k B u t t o n 2 ( View v ) {
I n t e n t i n t e n t =new I n t e n t ( ACTION VIEW ) ;
startActivityForResult ( intent , 2);
}
p r o t e c t e d v o i d o n A c t i v i t y R e s u l t ( i n t requestCode , i n t resultCode , I n t e n t data ){
super . o n A c t i v i t y R e s u l t ( requestCode , resultCode , data )
i f ( requestCode ==1){
t e x t V i e w . s e t T e x t ( data . g e t S t r i n g E x t r a ( ”MESSAGE” ) ) ;
i f ( requestCode ==2){
t e x t V i e w . s e t T e x t ( ACTION VIEW ) ;
}
}
p u b l i c c l a s s S e c o n d A c t i v i t y extends A c t i v i t y {
...
p u b l i c v o i d o n C l i c k ( View arg0 ) {
S t r i n g message= e d i t T e x t . g e t T e x t ( ) . t o S t r i n g ( ) ;
I n t e n t i n t e n t =new I n t e n t ( ) ;
i n t e n t . p u t E x t r a ( ”MESSAGE” , message ) ;
s e t R e s u l t ( ACTION OK , i n t e n t ) ;
finish ();
}
}
Quelques rappels
Services et communication simple
Plan
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Service
Définition
• tourne en tâche de fond
• n’a pas d’interface graphique
• prioritaire sur les activités
• cycle de vie simplifié
• lié ou non à des activités
Exemples
• media player
• écriture/lecture de fichiers, de
ressources
• communication réseau
• localisation
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Un exemple simple
p u b l i c c l a s s TestMyService1 extends A c t i v i t y implements O n C l i c k L i s t e n e r {
TextView txtMsg ;
ComponentName s e r v i c e ;
I n t e n t intentMyService1 ;
@Override
p u b l i c v o i d onCreate ( Bundle s a v e d I n s t a n c e S t a t e ) {
super . onCreate ( s a v e d I n s t a n c e S t a t e ) ;
setContentView (R . l a y o u t . main ) ;
txtMsg = ( TextView ) f i n d V i e w B y I d (R . i d . txtMsg ) ;
i n t e n t M y S e r v i c e 1 = new I n t e n t ( t h i s , MyService1 . c l a s s ) ;
service = s t a r t S e r v i c e ( intentMyService1 ) ;
txtMsg . s e t T e x t ( ” MyService1 s t a r t e d\n ( see LogCat ) ” ) ;
}
p u b l i c v o i d o n C l i c k ( View v ) {
try {
stopService ( intentMyService1 ) ;
txtMsg . s e t T e x t ( ” A f t e r s t o p p i n g S e r v i c e : \n ” + s e r v i c e . getClassName ( ) ) ;
} c a t c h ( E x c e p t i o n e ) {Toast . makeText ( t h i s , e . getMessage ( ) , 1 ) . show ( ) ; }
}
}
p u b l i c c l a s s MyService1 extends S e r v i c e {
@Override
p u b l i c v o i d onCreate ( ) {super . onCreate ( ) ; }
@Override
p u b l i c v o i d o n S t a r t ( I n t e n t i n t e n t , i n t s t a r t I d ) {Log . e ( ”<<MyService1−o n S t a r t>>” , ” I am a l i v e −1! ” ) ; }
@Override
p u b l i c v o i d onDestroy ( ) {Log . e ( ”<<MyService1−onDestroy>>” , ” I am dead−1” ) ; }
}
et dans le manifest : <service android:name=‘‘MyService1’’ />
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Communiquer avec un service
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Broadcast : plus simple la vie
Une seule méthode :
void onReceive(Context context, Intent brdMsg)
• quand un message est reçu, cette méthode est appelée
• tout le reste du temps, le broadcast est inactif !
• gestion des destinataires par filtres et catégories
Envoyer un broadcast
• sendBroadcast : aucune garantie sur l’ordre de réception, ni le
quand !
• sendOrderedBroadcast : reception en cascade ordonnée par
priorité (définie dans le filtre)
Cycle de vie
• statique : définie dans le manifest, toujours à l’écoute
• dynamique : instanciation dans le code,
registerReceiver(recv,filter) et
unregisterReceiver(recv).
Quelques rappels
Services et communication simple
Exemple
Une application à 3 services :
tiré du cours de V. Matos, Cleveland University,
http://grail.cba.csuohio.edu/˜matos/
• MyService4 : lecture de musique
• MyService5Async : calcu récursif de Fibonacci
• MyService6 : localisation GPS
p u b l i c c l a s s T e s t S e r v i c e 4 extends A c t i v i t y {
TextView txtMsg ;
Intent intentCallService4 ;
Intent intentCallService5 ;
Intent intentCallService6 ;
BroadcastReceiver r e c e i v e r ;
@Override
p u b l i c v o i d onCreate ( Bundle s a v e d I n s t a n c e S t a t e ) {
super . onCreate ( s a v e d I n s t a n c e S t a t e ) ;
setContentView (R . l a y o u t . main ) ;
txtMsg = ( TextView ) f i n d V i e w B y I d (R . i d . txtMsg ) ;
i n t e n t C a l l S e r v i c e 4 = new I n t e n t ( t h i s , MyService4 . c l a s s ) ;
i n t e n t C a l l S e r v i c e 5 = new I n t e n t ( t h i s , MyService5Async . c l a s s ) ;
i n t e n t C a l l S e r v i c e 6 = new I n t e n t ( t h i s , MyService6 . c l a s s ) ;
I n t e n t F i l t e r f i l t e r 5 = new I n t e n t F i l t e r ( ” matos . a c t i o n . GOSERVICE5” ) ;
I n t e n t F i l t e r f i l t e r 6 = new I n t e n t F i l t e r ( ” matos . a c t i o n . GPSFIX ” ) ;
r e c e i v e r = new MyEmbeddedBroadcastReceiver ( ) ;
registerReceiver ( receiver , f i l t e r 5 ) ;
registerReceiver ( receiver , f i l t e r 6 ) ;
}
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Exemple
@Override
p u b l i c v o i d o n C l i c k ( View v ) {
i f ( v . g e t I d ( ) == R . i d . b t n S t a r t 4 )
Log . e ( ” MAIN ” , ” o n C l i c k : s t a r t i n g s e r v i c e 4 ”
} e l s e i f ( v . g e t I d ( ) == R . i d . btnStop4 ) {
Log . e ( ” MAIN ” , ” o n C l i c k : s t o p p i n g s e r v i c e 4 ”
} e l s e i f ( v . g e t I d ( ) == R . i d . b t n S t a r t 5 ) {
Log . e ( ” MAIN ” , ” o n C l i c k : s t a r t i n g s e r v i c e 5 ”
} e l s e i f ( v . g e t I d ( ) == R . i d . btnStop5 ) {
Log . e ( ” MAIN ” , ” o n C l i c k : s t o p p i n g s e r v i c e 5 ”
} e l s e i f ( v . g e t I d ( ) == R . i d . b t n S t a r t 6 ) {
Log . e ( ” MAIN ” , ” o n C l i c k : s t a r t i n g s e r v i c e 6 ”
} e l s e i f ( v . g e t I d ( ) == R . i d . btnStop6 ) {
Log . e ( ” MAIN ” , ” o n C l i c k : s t o p p i n g s e r v i c e 6 ”
}
}
) ; startService ( intentCallService4 ) ;
) ; stopService ( intentCallService4 ) ;
) ; startService ( intentCallService5 ) ;
) ; stopService ( intentCallService5 ) ;
) ; startService ( intentCallService6 ) ;
) ; stopService ( intentCallService6 ) ;
p u b l i c c l a s s MyEmbeddedBroadcastReceiver extends BroadcastReceiver {
@Override
p u b l i c v o i d onReceive ( Context c o n t e x t , I n t e n t i n t e n t ) {
Log . e ( ” MAIN>>>” , ” ACTION : ” + i n t e n t . g e t A c t i o n ( ) ) ;
i f ( i n t e n t . g e t A c t i o n ( ) . equals ( ” matos . a c t i o n . GOSERVICE5” ) ) {
S t r i n g s e r v i c e 5 D a t a = i n t e n t . g e t S t r i n g E x t r a ( ” MyService5DataItem ” ) ;
Log . e ( ” MAIN>>>” , ” Data r e c e i v e d from S e r v i c e 5 : ” + s e r v i c e 5 D a t a ) ;
txtMsg . append ( ”\nService5Data : > ” + s e r v i c e 5 D a t a ) ;
}
e l s e i f ( i n t e n t . g e t A c t i o n ( ) . equals ( ” matos . a c t i o n . GPSFIX ” ) ) {
double l a t i t u d e = i n t e n t . g e t D o u b l e E x t r a ( ” l a t i t u d e ” , −1);
double l o n g i t u d e = i n t e n t . g e t D o u b l e E x t r a ( ” l o n g i t u d e ” , −1);
String provider = intent . getStringExtra ( ” provider ” ) ;
S t r i n g s e r v i c e 6 D a t a = p r o v i d e r + ” l a t : ” + Double . t o S t r i n g ( l a t i t u d e )+ ” l o n : ” +Double . t o S t r i n g ( l o n g i t u d e ) ;
Log . e ( ” MAIN>>>” , ” Data r e c e i v e d from S e r v i c e 6 : ” + s e r v i c e 6 D a t a ) ;
txtMsg . append ( ”\nService6Data : > ” + s e r v i c e 6 D a t a ) ;
}
}
}
}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Service4 : Player
p u b l i c c l a s s MyService4 extends S e r v i c e {
p u b l i c s t a t i c boolean b o o l I s S e r v i c e C r e a t e d = f a l s e ;
MediaPlayer p l a y e r ;
@Override
p u b l i c I B i n d e r onBind ( I n t e n t i n t e n t ) {
return null ;
}
@Override
p u b l i c v o i d onCreate ( ) {
Toast . makeText ( t h i s , ” MyService4 Created ” , Toast . LENGTH LONG ) . show ( ) ;
Log e ( ” MyService4 ” , ” onCreate ” ) ;
boolIsServiceCreated = true ;
p l a y e r = MediaPlayer . c r e a t e ( g e t A p p l i c a t i o n C o n t e x t ( ) , R . raw . good bad ugly ) ;
}
p u b l i c v o i d onDestroy ( ) {
Toast . makeText ( t h i s , ” MyService4 Stopped ” , Toast . LENGTH LONG ) . show ( ) ;
Log . e ( ” MyService4 ” , ” onDestroy ” ) ;
player . stop ( ) ;
player . release ( ) ;
player = n u l l ;
}
@Override
public void onStart ( I n t e n t intent , i n t s t a r t i d ) {
i f ( player . isPlaying ( ) )
Toast . makeText ( t h i s , ” MyService4 A l r e a d y S t a r t e d ” + s t a r t i d , Toast . LENGTH LONG ) . show ( ) ;
e l s e Toast . makeText ( t h i s , ” MyService4 S t a r t e d ” + s t a r t i d , Toast . LENGTH LONG ) . show ( ) ;
Log . e ( ” MyService4 ” , ” o n S t a r t ” ) ;
player . s t a r t ( ) ;
}
}
Quelques rappels
Services et communication simple
Plan
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Plus compliquée la vie... : les Threads
Beaucoup de problèmes
• peut être dans le même processus ou non
• code complexe
• interblocage
• communication par file de messages : classe Handler
p u b l i c c l a s s M a i n A c t i v i t y extends A c t i v i t y {
@Override
p u b l i c v o i d onCreate ( Bundle s a v e d I n s t a n c e S t a t e ) {
super . onCreate ( s a v e d I n s t a n c e S t a t e ) ;
setContentView (R . l a y o u t . main ) ;
new Thread ( new Runnable ( )
{
@Override
p u b l i c v o i d run ( ) {
try {
Thread . s l e e p ( 2 0 0 0 ) ;
Log . i ( ” Thread ” , ” coucou ” ) ;
} c a t c h ( I n t e r r u p t e d E x c e p t i o n e ) {e . p r i n t S t a c k T r a c e ( ) ; }
}
}
). start ();
}
Quelques rappels
Services et communication simple
En détail
Heureusement, il y a :
• IntentService
• ASyncTask
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
IntentService
Avantages/Inconvénients :
• simple à utiliser : une méthode onHandleIntent()
• ne peut manipuler l’interface
• une seule instance : plusieurs exécutions en séquence
uniquement
• ne peut être interrompu
p u b l i c c l a s s MyService extends I n t e n t S e r v i c e {
@Override
protected void onHandleIntent ( I n t e n t i n t e n t ) {
/ / f a i r e quelque chose
publishResults ( ) ;
}
p r i v a t e v o i d p u b l i s h R e s u l t s (){
I n t e n t i n t e n t = new I n t e n t (RESULTATS ) . p u t E x t r a (RESULT, r e s u l t ) ;
sendBroadcast ( i n t e n t ) ;
}
}
p u b l i c c l a s s M a i n A c t i v i t y extends A c t i v i t y {
p r i v a t e BroadcastReceiver r e c e i v e r = new BroadcastReceiver ( ){ p u b l i c v o i d onReceive . . . } ;
p u b l i c v o i d o n C l i c k ( View v){
I n t e n t i n t e n t = new I n t e n t ( t h i s , MyService . c l a s s ) ;
startService ( intent ) ;
}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
ASyncTask : communication simplifiée
Avantages/inconvénients
• permet d’intéragir avec l’interface
• une seule exécution à la fois !
p r i v a t e c l a s s VerySlowTask extends AsyncTask<S t r i n g , Long , Void> {
/ / Begin − can use UI t h r e a d here
p r o t e c t e d v o i d onPreExecute ( ) {}
/ / t h i s i s t h e SLOW background t h r e a d t a k i n g care o f heavy t a s k s
/ / cannot d i r e c t l y change UI
p r o t e c t e d Void doInBackground ( f i n a l S t r i n g . . . args ) {
...
p u b l i s h P r o g r e s s ( ( Long ) someLongValue ) ;
}
/ / p e r i o d i c updates − i t i s OK t o change UI
@Override
p r o t e c t e d v o i d onProgressUpdate ( Long . . . v a l u e ) {
}
/ / End − can use UI t h r e a d here
p r o t e c t e d v o i d onPostExecute ( f i n a l Void unused ) {
}
}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Exemple
p u b l i c c l a s s M a i n A c t i v i t y extends A c t i v i t y {
p u b l i c v o i d o n C l i c k ( f i n a l View v ) {
new VerySlowTask ( ) . execute ( ” dummy1 ” , ” dummy2 ” ) ;
}
p r i v a t e c l a s s VerySlowTask extends AsyncTask<S t r i n g , Long , Void> {
p r i v a t e f i n a l P r o g r e s s D i a l o g d i a l o g = new P r o g r e s s D i a l o g ( M a i n A c t i v i t y . t h i s ) ;
S t r i n g waitMsg = ” Wait\nSome SLOW j o b i s being done . . . ” ;
p r o t e c t e d v o i d onPreExecute ( ) {
s t a r t i n g M i l l i s = System . c u r r e n t T i m e M i l l i s ( ) ;
txtMsg . s e t T e x t ( ” S t a r t Time : ” + s t a r t i n g M i l l i s ) ;
t h i s . d i a l o g . setMessage ( waitMsg ) ;
t h i s . d i a l o g . show ( ) ;
}
p r o t e c t e d Void doInBackground ( f i n a l S t r i n g . . . args ) {
Log . e ( ” doInBackground>>” , ” T o t a l args : ” + args . l e n g t h ) ;
Log . e ( ” doInBackground>>” , ” args [ 0 ] = ” + args [ 0 ] ) ;
try {
f o r ( Long i = 0L ; i < 5L ; i ++) {
Thread . s l e e p ( 1 0 0 0 0 ) ; / / s i m u l a t e t h e slow j o b here
p u b l i s h P r o g r e s s ( ( Long ) i ) ;
}} c a t c h ( I n t e r r u p t e d E x c e p t i o n e ) {Log . e ( ” slow−j o b i n t e r r u p t e d ” , e . getMessage ( ) ) ; }
return null ;
}
@Override
p r o t e c t e d v o i d onProgressUpdate ( Long . . . v a l u e ) {
super . onProgressUpdate ( v a l u e ) ;
d i a l o g . setMessage ( waitMsg + v a l u e [ 0 ] ) ;
txtMsg . append ( ”\nworking . . . ” + v a l u e [ 0 ] ) ;
}
/ / can use UI t h r e a d here
p r o t e c t e d v o i d onPostExecute ( f i n a l Void unused ) {
i f ( t h i s . d i a l o g . isShowing ( ) ) {
t h i s . dialog . dismiss ( ) ;
}
txtMsg . append ( ”\nEnd Time : ” + ( System . c u r r e n t T i m e M i l l i s ( ) − s t a r t i n g M i l l i s ) / 1 0 0 0 ) ;
txtMsg . append ( ”\ndone ! ” ) ;
}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Service6 : GPS
p u b l i c c l a s s MyService6 extends S e r v i c e {
S t r i n g GPS FILTER = ” matos . a c t i o n . GPSFIX ” ;
Thread s e r v i c e T h r e a d ;
LocationManager lm ;
GPSListener m y L o c a t i o n L i s t e n e r ;
@Override
p u b l i c I B i n d e r onBind ( I n t e n t arg0 ) {r e t u r n n u l l ;}
@Override
p u b l i c v o i d onCreate ( ) {super . onCreate ( ) ; }
@Override
public void onStart ( I n t e n t intent , i n t s t a r t I d ) {
Log . e ( ”<<MyGpsService−o n S t a r t>>” , ” I am a l i v e−GPS! ” ) ;
s e r v i c e T h r e a d = new Thread ( new Runnable ( ){
p u b l i c v o i d run ( ) {
getGPSFix Version1 ( ) ; / / uses NETWORK p r o v i d e r
getGPSFix Version2 ( ) ; / / uses GPS c h i p p r o v i d e r
}
});
serviceThread . s t a r t ( ) ;
}
p u b l i c v o i d getGPSFix Version1 ( ) {
LocationManager l o c a t i o n M a n a g e r = ( LocationManager ) getSystemService ( Context . LOCATION SERVICE ) ;
C r i t e r i a c r i t e r i a = new C r i t e r i a ( ) ;
S t r i n g p r o v i d e r = locationManager . getBestProvider ( c r i t e r i a , f a l s e ) ;
L o c a t i o n l o c a t i o n = l o c a t i o n M a n a g e r . getLastKnownLocation ( p r o v i d e r ) ;
i f ( l o c a t i o n ! = n u l l ){
double l a t i t u d e = l o c a t i o n . g e t L a t i t u d e ( ) ;
double l o n g i t u d e = l o c a t i o n . g e t L o n g i t u d e ( ) ;
I n t e n t myFilteredResponse = new I n t e n t ( GPS FILTER ) ;
myFilteredResponse . p u t E x t r a ( ” l a t i t u d e ” , l a t i t u d e ) ;
myFilteredResponse . p u t E x t r a ( ” l o n g i t u d e ” , l o n g i t u d e ) ;
myFilteredResponse . p u t E x t r a ( ” p r o v i d e r ” , p r o v i d e r ) ;
Log . e ( ”>>GPS Service<<” , p r o v i d e r + ” =>L a t : ” + l a t i t u d e + ” l o n : ” + l o n g i t u d e ) ;
sendBroadcast ( myFilteredResponse ) ;
}
}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Service6 : GPS
p u b l i c v o i d getGPSFix Version2 ( ) {
try {
Looper . prepare ( ) ;
lm = ( LocationManager ) getSystemService ( Context . LOCATION SERVICE ) ;
m y L o c a t i o n L i s t e n e r = new GPSListener ( ) ;
l o n g minTime = 2000; / / 2 seconds
f l o a t minDistance = 5 ; / / 5 meter
lm . r e q u e s t L o c a t i o n U p d a t e s ( LocationManager . GPS PROVIDER, minTime , minDistance , m y L o c a t i o n L i s t e n e r ) ;
Looper l o o p ( ) ;
} c a t c h ( E x c e p t i o n e ) {e . p r i n t S t a c k T r a c e ( ) ; }
}
@Override
p u b l i c v o i d onDestroy ( ) {
super . onDestroy ( ) ;
Log . e ( ”<<MyGpsService onDestroy>>” , ” I am dead GPS” ) ;
t r y { lm . removeUpdates ( m y L o c a t i o n L i s t e n e r ) ;
isRunning = f a l s e ;
} c a t c h ( E x c e p t i o n e ) {Toast . makeText ( g e t A p p l i c a t i o n C o n t e x t ( ) , e . getMessage ( ) , 1 ) . show ( ) ; }
}
p r i v a t e c l a s s GPSListener implements L o c a t i o n L i s t e n e r {
p u b l i c v o i d onLocationChanged ( L o c a t i o n l o c a t i o n ) {
double l a t i t u d e = l o c a t i o n . g e t L a t i t u d e ( ) ;
double l o n g i t u d e = l o c a t i o n . g e t L o n g i t u d e ( ) ;
I n t e n t myFilteredResponse = new I n t e n t ( GPS FILTER ) ;
myFilteredResponse . p u t E x t r a ( ” l a t i t u d e ” , l a t i t u d e ) ;
myFilteredResponse . p u t E x t r a ( ” l o n g i t u d e ” , l o n g i t u d e ) ;
myFilteredResponse . p u t E x t r a ( ” p r o v i d e r ” , l o c a t i o n . g e t P r o v i d e r ( ) ) ;
Log . e ( ”>>GPS Service<<” , ” L a t : ” + l a t i t u d e + ” l o n : ” + l o n g i t u d e ) ;
sendBroadcast ( myFilteredResponse ) ;
}
p u b l i c v o i d o n P r o v i d e r D i s a b l e d ( S t r i n g p r o v i d e r ) {}
p u b l i c v o i d onProviderEnabled ( S t r i n g p r o v i d e r ) {}
p u b l i c v o i d onStatusChanged ( S t r i n g p r o v i d e r , i n t s t a t u s , Bundle e x t r a s ) {}
}; / / GPSListener c l a s s
}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Service5 : Fibonacci
p u b l i c c l a s s MyService5Async extends S e r v i c e {
boolean isRunning = t r u e ;
p r i v a t e Handler h a n d l e r = new Handler ( ) {
@Override
p u b l i c v o i d handleMessage ( Message msg ) {
super . handleMessage ( msg ) ;
Log . e ( ” MyService5Async−Handler ” , ” Handler g o t from MyService5Async : ” + ( S t r i n g ) msg . o b j ) ;
}
};
@Override
p u b l i c I B i n d e r onBind ( I n t e n t arg0 ) {
return null ;
}
@Override
p u b l i c v o i d onCreate ( ) {
super . onCreate ( ) ;
}
public void onStart ( I n t e n t intent , i n t s t a r t I d ) {
Log . e ( ”<<MyService5Async−o n S t a r t>>” , ” I am a l i v e −5Async ! ” ) ;
new ComputeFibonacciRecursivelyTask ( ) . execute ( 2 0 , 5 0 ) ;
}
p u b l i c I n t e g e r f i b o n a c c i ( I n t e g e r n){
i f ( n==0 || n==1 )
return 1;
else
r e t u r n f i b o n a c c i ( n−1) + f i b o n a c c i ( n−2);}
@Override
p u b l i c v o i d onDestroy ( ) {
super . onDestroy ( ) ;
Log . e ( ”<<MyService5Async−onDestroy>>” , ” I am dead−5−Async ” ) ;
isRunning = f a l s e ;
}
Quelques rappels
Services et communication simple
Threads, IntentService, ASyncTask
Service5 : Fibonacci
p u b l i c c l a s s ComputeFibonacciRecursivelyTask extends AsyncTask <I n t e g e r , I n t e g e r , I n t e g e r > {
@Override
p r o t e c t e d I n t e g e r doInBackground ( I n t e g e r . . . params ) {
f o r ( i n t i =params [ 0 ] ; i<params [ 1 ] ; i ++)
Integer fibn = fibonacci ( i ) ;
publishProgress ( i , f i b n ) ;
}
return null ;
}
@Override
p r o t e c t e d v o i d onProgressUpdate ( I n t e g e r . . . v a l u e s ) {
super . onProgressUpdate ( v a l u e s ) ;
I n t e n t i n t e n t F i l t e r 5 = new I n t e n t ( ” matos . a c t i o n . GOSERVICE5” ) ;
S t r i n g data = ” dataItem−5−f i b o n a c c i−AsyncTask ” + v a l u e s [ 0 ] + ” : ” + v a l u e s [ 1 ] ;
i n t e n t F i l t e r 5 . p u t E x t r a ( ” MyService5DataItem ” , data ) ;
sendBroadcast ( i n t e n t F i l t e r 5 ) ;
Message msg = h a n d l e r . obtainMessage ( 5 , data ) ;
h a n d l e r . sendMessage ( msg ) ;
}
}}
Quelques rappels
Services et communication simple
Un dernier
p u b l i c c l a s s LocalWordService extends S e r v i c e {
p r i v a t e f i n a l I B i n d e r mBinder = new MyBinder ( ) ;
p r i v a t e A r r a y L i s t<S t r i n g> l i s t = new A r r a y L i s t<S t r i n g >();
@Override
p u b l i c i n t onStartCommand ( I n t e n t i n t e n t , i n t f l a g s , i n t s t a r t I d ) {
Random random = new Random ( ) ;
i f ( random . nextBoolean ( ) ) {
l i s t . add ( ” L i n u x ” ) ;
}
i f ( random . nextBoolean ( ) ) {
l i s t . add ( ” Android ” ) ;
}
i f ( random . nextBoolean ( ) ) {
l i s t . add ( ” iPhone ” ) ;
}
i f ( random . nextBoolean ( ) ) {
l i s t . add ( ” Windows7 ” ) ;
}
i f ( l i s t . s i z e ( ) >= 20) {
l i s t . remove ( 0 ) ;
}
r e t u r n S e r v i c e . START NOT STICKY ;
}
@Override
p u b l i c I B i n d e r onBind ( I n t e n t arg0 ) {
r e t u r n mBinder ;
}
p u b l i c c l a s s MyBinder extends B i n d e r {
LocalWordService g e t S e r v i c e ( ) {
r e t u r n LocalWordService . t h i s ;
}
}
p u b l i c L i s t<S t r i n g> g e t W o r d L i s t ( ) {
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Un dernier
p u b l i c c l a s s MyScheduleReceiver extends BroadcastReceiver {
/ / r e s t a r t s e r v i c e every 30 seconds
p r i v a t e s t a t i c f i n a l l o n g REPEAT TIME = 1000 ∗ 3 0 ;
@Override
p u b l i c v o i d onReceive ( Context c o n t e x t , I n t e n t i n t e n t ) {
AlarmManager s e r v i c e = ( AlarmManager ) c o n t e x t
. getSystemService ( Context . ALARM SERVICE ) ;
I n t e n t i = new I n t e n t ( c o n t e x t , M y S t a r t S e r v i c e R e c e i v e r . c l a s s ) ;
P e n d i n g I n t e n t pending = P e n d i n g I n t e n t . g e t B r o a d c a s t ( c o n t e x t , 0 , i ,
P e n d i n g I n t e n t . FLAG CANCEL CURRENT ) ;
Calendar c a l = Calendar . g e t I n s t a n c e ( ) ;
/ / s t a r t 30 seconds a f t e r boot completed
c a l . add ( Calendar .SECOND, 3 0 ) ;
/ / f e t c h every 30 seconds
/ / I n e x a c t R e p e a t i n g a l l o w s Android t o o p t i m i z e t h e energy consumption
s e r v i c e . s e t I n e x a c t R e p e a t i n g ( AlarmManager .RTC WAKEUP,
c a l . g e t T i m e I n M i l l i s ( ) , REPEAT TIME , pending ) ;
/ / s e r v i c e . s e t R e p e a t i n g ( AlarmManager .RTC WAKEUP, c a l . g e t T i m e I n M i l l i s ( ) ,
/ / REPEAT TIME , pending ) ;
}
}
p u b l i c c l a s s M y S t a r t S e r v i c e R e c e i v e r extends BroadcastReceiver {
@Override
p u b l i c v o i d onReceive ( Context c o n t e x t , I n t e n t i n t e n t ) {
I n t e n t s e r v i c e = new I n t e n t ( c o n t e x t , LocalWordService . c l a s s ) ;
context . startService ( service ) ;
}
}
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Un dernier
p u b l i c c l a s s M a i n A c t i v i t y extends L i s t A c t i v i t y {
p r i v a t e LocalWordService s ;
@Override
p u b l i c v o i d onCreate ( Bundle s a v e d I n s t a n c e S t a t e ) {
super . onCreate ( s a v e d I n s t a n c e S t a t e ) ;
setContentView (R . l a y o u t . main ) ;
w o r d L i s t = new A r r a y L i s t<S t r i n g >();
a d a p t e r = new ArrayAdapter<S t r i n g >(t h i s ,
android .R. l a y o u t . s i m p l e l i s t i t e m 1 , android .R. i d . text1 ,
wordList ) ;
s e t L i s t A d a p t e r ( adapter ) ;
}
@Override
p r o t e c t e d v o i d onResume ( ) {
super . onResume ( ) ;
I n t e n t i n t e n t = new I n t e n t ( t h i s , LocalWordService . c l a s s ) ;
b i n d S e r v i c e ( i n t e n t , mConnection ,
Context . BIND AUTO CREATE ) ;
}
@Override
p r o t e c t e d v o i d onPause ( ) {
super . onPause ( ) ;
u n b i n d S e r v i c e ( mConnection ) ;
}
Threads, IntentService, ASyncTask
Quelques rappels
Services et communication simple
Un dernier
p r i v a t e S e r v i c e C o n n e c t i o n mConnection = new S e r v i c e C o n n e c t i o n ( ) {
p u b l i c v o i d onServiceConnected ( ComponentName className ,
IBinder binder ) {
LocalWordService . MyBinder b = ( LocalWordService . MyBinder ) b i n d e r ;
s = b . getService ( ) ;
Toast . makeText ( M a i n A c t i v i t y . t h i s , ” Connected ” , Toast . LENGTH SHORT)
. show ( ) ;
}
p u b l i c v o i d onServiceDisconnected ( ComponentName className ) {
s = null ;
}
};
p r i v a t e ArrayAdapter<S t r i n g> a d a p t e r ;
p r i v a t e L i s t<S t r i n g> w o r d L i s t ;
p u b l i c v o i d o n C l i c k ( View view ) {
i f ( s != n u l l ) {
Toast . makeText ( t h i s , ” Number o f elements ” + s . g e t W o r d L i s t ( ) . s i z e ( ) ,
Toast . LENGTH SHORT ) . show ( ) ;
wordList . clear ( ) ;
wordList . addAll ( s . getWordList ( ) ) ;
a d a p t e r . notifyDataSetChanged ( ) ;
}
}
}
Threads, IntentService, ASyncTask