Projet Android (LI260) Cours 2 Nicolas Baskiotis Université Pierre et Marie Curie (UPMC) Laboratoire d Informatique de Paris 6 (LIP6) S2-2013/2014
Plan Les ressources Debug Communication entre activités
Ressources Répertoire res Contient toutes les ressources de l application : layout : interface graphique drawable : images values : constantes anim : animations menus : menus raw : autres types de ressources (sons, vidéos,... ) Le nom du répertoire est important!!
Exemple : constantes Dans le fichier ressource Le nom du fichier n a pas d importance! <?xml version="1.0" encoding="utf-8"?> <resources> <color name="bgcolor">#aa7b03</color> <integer name="nbmax">32</integer> <integer-array name="longueurs"> <item>64</item> <item>33</item> </integer-array> <string name="titre">un titre</string> <bool name="actif">true</bool> <dimen name="taille">55px</dimen> </resources> Dans le fichier xml Référence : @type/nom @color/bgcolor @integer/nbmax @array/longueurs @string/titre @bool/actif @dimen/taille
Exemple : constantes Référence dans le code int R.type.nom pour récupérer l identifiant R.color.bgcolor R.integer.nbmax R.array.longueurs R.string.titre R.bool.actif R.dimen.taille Objet associé Accès aux ressources : Resources getresources(), puis Color getcolor(int) int getinteger(int) int[] getarray(int) String getstring(int) boolean getboolean(int) float getdimension(int) Exemple : String titre= getresources().getstring(r.string.titre);
String formaté Astuce Dans le xml : <string name="welcome_message"> Hello, %1$s! You have %2$d new messages. </string> Dans le code : Resources res = getresources(); String text = String.format(res.getString(R.string.welcome_messages), username, mailcount);
Cas spécifique : layout <Button android:id="@+id/refresh" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="refresh" android:onclick="refreshme" /> <EditText android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputtype="textmultiline" > </EditText> @+id pour spécifier la création de l identifiant référence : @id/refresh, @id/list dans le code : (Button) findviewbyid(r.id.refresh)
Flexibilité : internationalisation et personalisation Qualifier un répertoire : <resource-name>-<qualifiers> possibilité de combiner les qualifiers dans les répertoires, les mêmes noms que dans le répertoire par défaut langage en, fr, ru, fr-rfr,... résolution sw320dp, sw720dp w720dp, h640dp taille small, normal, large, xlarge orientation port, land dpi ldpi, mdpi, hdpi,...
Plan Les ressources Debug Communication entre activités
Debug fenêtre de log dans eclipse très nombreux logs : il faut filtrer! classe :Log Log.v(String tag, String msg) verbose Log.d(String tag, String msg) debug Log.i(String tag, String msg) info Log.w(String tag, String msg) warning Log.e(String tag, String msg) error Log.wtf(String tag, String msg)...
Plan Les ressources Debug Communication entre activités
Démarrer une activité Je veux joindre mon meilleur ami! oui, mais... : par téléphone? par SMS? par email? par Skype?... En général, l activité source ne s en préoccupe pas! notion d Intent : déléguer une action à un autre composant. Intent explicite : spécifie le composant spécifique Intent implicite : type d action uniquement, qui veut s en charge
Exemple Button b = (Button)findViewById(R.id.Button01); b.setonclicklistener(new OnClickListener() { @Override public void onclick(view v) { Uri telnumber = Uri.parse("tel:0248484000"); Intent call = new Intent(Intent.ACTION_DIAL, telnumber); startactivity(call); );
Composition d un intent Un objet Intent contient les information suivantes le nom du composant ciblé (facultatif, explicite ou implicite) l action à réaliser les données : contenu MIME et URI (et le type de données) des données supplémentaires sous forme de paires clef/valeur une catégorie pour cibler un type d application des drapeaux (informations supplémentaires) Exemples d action ACTION MAIN, ACTION VIEW, ACTION CALL, ACTION ANSWER, ACTION DIAL, ACTION EDIT, ACTION SEND, ACTION WEB SEARCH Exemples de catégories CATEGORY DEFAULT, CATEGORY TAB, CATEGORY APP BROWSER, CATEGORY APP EMAIL, CATEGORY INFO, CATEGORY HOME Exemples de données : URI.parse(uri) content://contacts/people/1, tel:123, content://com.example.project:200/folder/sub
Données supplémentaires Méthode putextra(string key, XXX value) données récupérées par : getextras().getxxx(key) Intent emailintent = new Intent(android.content.Intent.ACTION_SEND); String[] recipients = new String[]{"my@email.com", "",; emailintent.putextra(android.content.intent.extra_email, recipients); emailintent.putextra(android.content.intent.extra_subject, "Test"); emailintent.putextra(android.content.intent.extra_text, "Message"); emailintent.settype("text/plain"); startactivity(intent.createchooser(emailintent, "Send mail...")); finish(); Pour le retour de données setresult(int, Intent) putextra() et pour l appli source : onactivityresult(int, int, Intent)
Cas d utilisation Démarrer une activité : startactivity(intent); si résultat attendu : startactivityforresult(intent,int requestcode) retour : callback : onactivityresult(int requestcode, int returncode, Intent data) Démarrer un service Envoyer un broadcast p r i v a t e void pickcontact ( ) { 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. ACTION PICK, Contacts. CONTENT URI ) ; s t a r t A c t i v i t y F o r R e s u l t ( i n t e n t, PICK CONTACT REQUEST ) ; @Override protected void 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 ) { i f ( resultcode == A c t i v i t y. RESULT OK &&\\ requestcode == PICK CONTACT REQUEST) { Cursor cursor = getcontentresolver ( ). query ( data. getdata ( ), new S t r i n g [ ] {Contacts. DISPLAY NAME, n u l l, n u l l, n u l l ) ; i f ( cursor. movetofirst ( ) ) { i n t columnindex = cursor. getcolumnindex ( Contacts. DISPLAY NAME ) ; S t r i n g name = cursor. g e t S t r i n g ( columnindex ) ; / / Do something with the selected contact s name...
Filtre d intents Quelle activité est sélectionnée? Mode explicite : il n y a aucun filtrage Mode implicite : filtre d actions : l une des actions indiquées dans l Intent doit correspondre à l une de celles du filtre de catégorie : toutes les catégories indiquées dans l Intent doivent apparaître dans le filtre de données : le type de données indiqué dans l Intent doit correspondre à celui du filtre <application android : icon= @drawable / app notes android : l a b e l = @string / app name > <provider class=. NotePadProvider android : authorities= com. google. provider. NotePad /> <a c t i v i t y class=. NotesList android : l a b e l = @string / t i t l e n o t e s l i s t > <i n t e n t f i l t e r > <action android :name= android. i n t e n t. action.main /> <category android :name= android. i n t e n t. category.launcher /> </i n t e n t f i l t e r > <i n t e n t f i l t e r > <action android :name= android. i n t e n t. action.view /> <action android :name= android. i n t e n t. action. EDIT /> <action android :name= android. i n t e n t. action. PICK /> <category android :name= android. i n t e n t. category.default /> <data android : mimetype= vnd. android. cursor. d i r / vnd. google. note /> </i n t e n t f i l t e r > <i n t e n t f i l t e r > <a c t i o n android :name= android. i n t e n t. a c t i o n.get CONTENT /> <category android :name= android. i n t e n t. category.default /> <data android : mimetype= vnd. android. cursor. item / vnd. google. note /> </i n t e n t f i l t e r > </ a c t i v i t y>
Exemple <receiver android:name="coucoureceiver"> <intent-filter> <action android:name="amoi.intent.action.coucou" /> </intent-filter> </receiver> public class CoucouReceiver extends BroadcastReceiver { private static final String NOM_USER = "amoi.intent.extra.nom"; @Override public void onreceive(context context, Intent intent) { if(intent.getaction().equals("action_coucou")) { String nom = intent.getextra(nom_user); Toast.makeText(context, "Coucou " + nom + "!", Toast.LENGTH_LONG).show();
Broadcast : exemple public class CoucouActivity extends Activity { private static final String COUCOU = "amoi.intent.action.coucou"; private IntentFilter filtre = null; private CoucouReceiver receiver = null; @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); filtre = new IntentFilter(COUCOU); receiver = new CoucouReceiver(); @Override public void onresume() { super.onresume(); registerreceiver(receiver, filtre); @Override public void onpause() { super.onpause(); unregisterreceiver(receiver);