Catégories
Développement Android

Tutoriel sur le système de fichier Android : Enregistrement des données dans la mémoire interne et dans la carte SD

 

 

Nous verrons dans ce tuto qu’il existe 2 façons de sauvegarder des données dans un fichier sur Android. Vous êtes prêt ? Alors c’est parti !

 

 

Tout d’abord, on peut faire une sauvegarde interne dans la mémoire du téléphone ou bien faire une sauvegarde externe dans la carte SD de l’utilisateur.

Il faut savoir que les informations enregistrées dans la carte mémoire externe du terminal mobile sont accessibles par l’ensemble des applications.

Alors que les données sauvegardées en mémoire interne peuvent ou non être partagé en lecture ou/et en écriture avec les autres applications.

 

Voici la liste des différentes permissions pour la création d’un fichier dans la mémoire interne :

 MODE_PRIVATE crée un fichier (ou remplace l’existant), le fichier ne sera disponible que pour notre application.

 MODE_APPEND crée un fichier (concatène si le fichier existe)

 MODE_WORLD_READABLE accès en lecture par les autres applications

 MODE_WORLD_WRITEABLE accès en écriture par les autres applications

 MODE_WORLD_READABLE|MODE_WORLD_WRITEABLE accès en lecture et écriture par tous

Pour l’écriture nous allons utiliser la méthode openfileoutput qui va renvoyer un FileOUtputStream,

Pour la lecture il faut utiliser la méthode openFileInput qui renvoie un FileInputStream.

 

Nous allons mettre en place une application toute simple qui va jouer le rôle d’un bloc note.

L’utilisateur pourra écrire dans un fichier, mais également l’ouvrir et l’éditer.

En termes d’interface nous aurons :

  • juste une zone de saisie.
  • Un bouton pour enregistrer les modifications.
  • Un bouton pour afficher le contenu de notre fichier.
  • Un autre bouton pour vider la zone de saisie.

 

Ce qui se résume à ce code là :

 

<LinearLayout xmlns:android=« http://schemas.android.com/apk/res/android »

    android:layout_width=« fill_parent »

    android:layout_height=« fill_parent »

    android:orientation=« vertical » >

 

   <EditText

        android:id=« @+id/texte »

        android:layout_width=« fill_parent »

        android:layout_height=« wrap_content »

        android:lines=« 5 »

         android:gravity=« top|left » android:inputType=« textMultiLine »

        android:scrollHorizontally=« false » />

   

   <LinearLayout xmlns:android=« http://schemas.android.com/apk/res/android »

    android:layout_width=« fill_parent »

    android:layout_height=« fill_parent »

    android:orientation=« horizontal » >

    <Button android:id=« @+id/btn »

    android:layout_width=« wrap_content »

    android:layout_height=« wrap_content »

    android:text=« Sauvegarder » />

   

    <Button android:id=« @+id/btn2 »

    android:layout_width=« wrap_content »

    android:layout_height=« wrap_content »

    android:text=« Afficher » />

   

        <Button android:id=« @+id/btn3 »

    android:layout_width=« wrap_content »

    android:layout_height=« wrap_content »

    android:text=« Vider » />

 

</LinearLayout>

 

</LinearLayout>

 

 

 

Pour l’enregistrement d’un fichier dans la mémoire interne du téléphone, Les deux méthodes qui vont nous intéresser sont

           

Pour l’écriture :

 

private void ecrireFicher(String nomFichier,String monText) {

             BufferedWriter writer = null;

             try {

                    File dir = getDir(« ToutMesFichiers »,MODE_PRIVATE);

                    File newfile = new File(dir.getAbsolutePath() + File.separator + nomFichier);

                    newfile.createNewFile();

                    writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newfile)));

                    writer.write(monText);

             } catch (Exception e) {

                    e.printStackTrace();

             } finally {

                    if (writer != null) {

                           try {

                                  writer.close();

                           } catch (IOException e) {

                                  e.printStackTrace();

                           }

                    }

             }

       }

 

 

 Pour la lecture :

 

 private String lireFichier(String nomFichier) {

             File dir = getDir(« ToutMesFichiers »,MODE_PRIVATE);

             File newfile = new File(dir.getAbsolutePath() + File.separator + nomFichier);

             String monText= » »;

             BufferedReader input = null;

             try {

               input = new BufferedReader(new InputStreamReader( new FileInputStream(newfile)

                    ));

               String line;

               StringBuffer buffer = new StringBuffer();

               while ((line = input.readLine()) != null) {

                    buffer.append(line);

               }

                monText = buffer.toString();

             } catch (Exception e) {

                    e.printStackTrace();

             } finally {

             if (input != null) {

               try {

                    input.close();

                    } catch (IOException e) {

                           e.printStackTrace();

                    }

               }

             }

           return monText;

           }

 

 

Voici ce que le téléphone va créer dans le répertoire /data/data/ :

 

 Il faut ensuite mettre les écouteurs d’évènements à nos boutons. Voici le contenu de la méthode oncreate.

 

 

 

public void onCreate(Bundle savedInstanceState) {

             super.onCreate(savedInstanceState);

             setContentView(R.layout.main);

             final EditText text = (EditText) findViewById(R.id.texte);

 

             Button valider = (Button) findViewById(R.id.btn);

 

             valider.setOnClickListener(new OnClickListener() {                

                    public void onClick(View v) {                        

                           ecrireFicher(« monFichier.txt », text.getText().toString());

                    }

             });

 

             Button afficher = (Button) findViewById(R.id.btn2);

             afficher.setOnClickListener(new OnClickListener() {               

                    public void onClick(View v) {                        

                           text.setText(lireFichier(« monFichier.txt »));

                    }

             });

            

             Button vider = (Button) findViewById(R.id.btn3);

             vider.setOnClickListener(new OnClickListener() {                  

                    public void onClick(View v) {                        

                           text.setText(«  »);

                    }

             });

         }

 

 

Voici le résultat d’un scénario d’utilisation :

 

  1. Un utilisateur rentre du texte 
  2. Il sauvegarde le texte dans le fichier
  3. Il vide le contenu de la zone de saisie
  4. Il affiche le contenu de son fichier
  5. Il modifie ce contenu
  6. Il sauvegarde la modification
  7. Il vide le contenu de la zone de saisie
  8. Il affiche le contenu de son fichier

 

 Voici des images issues d’un autre scénario ou l’utilisateur n’enregistre pas ses modifications.

 

 

                                    

 

 

Utilisation de la carte SD

 

Nous pouvons faire la même application, mais les fichiers seront sauvegardés dans la mémoire externe du téléphone.

 

Ajouter la permission dans le manifest :

<uses-permission android:name= »android.permission.WRITE_EXTERNAL_STORAGE » />

 

NB : Pour les personnes utilisant l’émulateur, il faut monter une carte SD.

Rappel de la commande (à exécuter dans tools/) :

mksdcard 1024M sdcard.img
Dans runconfiguration, ajouter :
-sdcard C:\android-sdk-windows\tools\sdcard.img
 
Nous allons modifier nos deux méthodes :


Pour l'écriture :

private void ecrireFicher(String nomFichier,String monText) {
        
        File sdLien = Environment.getExternalStorageDirectory(); 
        File monFichier = new File(sdLien , "monFichier.txt");
        BufferedWriter writer = null;        
        try {
        FileWriter out = new FileWriter(monFichier); 
         writer = new BufferedWriter(out);          
         writer.write(monText); 
        } catch (Exception e) {
                       e.printStackTrace();
        } finally {
          if (writer != null) {
               try {
                       writer.close();
               } catch (IOException e) {
                       e.printStackTrace();
               }
          }
        }
  }
 
Pour la lecture :
 
 
private String lireFichier(String nomFichier) {
        String monText='';
        File sdLien = Environment.getExternalStorageDirectory(); 
        File monFichier = new File(sdLien + "/" +nomFichier); 
        if (!monFichier.exists()) {
               throw new RuntimeException("Fichier innéxistant dur la carte sd");
        } 
        BufferedReader reader = null;
        try {
               reader = new BufferedReader(new FileReader(monFichier));
               StringBuilder builder = new StringBuilder();
               String line;
               while ((line = reader.readLine()) != null) {
                       builder.append(line);
               }
             monText = buffer.toString();
        } catch (Exception e) {
               e.printStackTrace();
        } finally {
               if (reader != null) {
                       try {
                               reader.close();
                       } catch (IOException e) {
                               e.printStackTrace();
                       }
               }
        }
        return monText;
    }
 
 
 
Voici le contenu du répertoire /mnt/sdcard/



 

En répétant les mêmes scénarios d’utilisation que précédemment, nous obtiendrons les mêmes résultats.

 

 

 

Voilà ce qu’il en est de la sauvegarde de fichiers sur Android, j’espère que ce petit tuto vous servira pour vos applications futures  Content

 




Catégories
Développement Android

Améliorer la performance et l’expérience utilisateur d’une application avec la classe AsyncTask

Android Speed imageDans ce tuto, nous allons voir comment il est possible, comme le titre l’indique, d’améliorer notre navigation sur notre smartphone Android préféré en utilisant des tâches asynchrones via la classe AsyncTask ! Sur Android, l’ensemble des éléments graphiques sont gérés à partir d’un thread principal que certaines appellent « UI thread« . Il est donc déconseillé d’utiliser ce thread pour des opérations coûteuses ( requêtes en base, chargement d’éléments depuis le web … ).

 Il faut considérer que toute opération nécessitant un temps de traitement supérieur à 5 secondes sera considérée comme nuisible. Une boite de dialogue s’ouvrira alors pour informer l’utilisateur que l’activité ne répond pas. Pour mieux comprendre ce comportement, nous allons réaliser une petite application dont le but est de provoquer un ARN ( … et non ce n’est pas une maladie, ou un genre de crise ), ARN signifie simplement « Activity not Responding ». Content

 

Voici notre main.xml :

main.xml
<?xml version="1.0" encoding="utf-8"?>   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >      <Button android:id="@+id/btn"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:text="Valider" />      <EditText    android:id="@+id/edittext"    android:layout_width="fill_parent"    android:layout_height="wrap_content"/>   </LinearLayout>

 

Comme on peut le voir, on aura un bouton qui va lancer une opération et une zone de saisie qu’on va essayer d’utiliser durant le traitement de l’opération. 

Voici maintenant le code de notre activité :

Code de l’activité
public class AsyncTastActivity extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    Button btn = (Button) findViewById(R.id.btn);    btn.setOnClickListener(new OnClickListener() {    public void onClick(View v) {    dormir();    }    });    }     private void dormir(){     try {     Thread.sleep(10000);     } catch (InterruptedException e) {     }     }    }

 

Testez maintenant votre code :

Lancez le programme, cliquez sur le bouton puis aussitôt, essayez de saisir un mot dans la zone de saisie. Vous verrez donc apparaître la fameuse boite de dialogue Activitiy not Responding.

 

 

 

Pendant le traitement, on ne peut pas faire autre chose comme taper du texte dans un champ.

Pour résoudre ce problème, on peut utiliser la classe AsyncTask. Cette classe sera notre carte maîtresse pour réaliser des tâches de manière asynchrone. Elle crée un deuxième thread de manière à ne pas bloquer le thread principal !

La classe prend 3 paramètres d’entrées.

 

  • La paramètre fourni à la tâche de fond
  • Le type de donnée à transmettre pendant la progression de la tâche
  • Le type de donnée renvoyé par la tâche

La méthode doInBackground ( le traitement se fait dans cette méthode ) doit absolument être implémentée.

Les méthodes onPreExecute ( méthode appelée avant le début du traitement ), onProgressUpdate ( appelée durant le traitement ), onPostExecute ( appelée à la fin du traitement ) sont facultatives !

 

Reprenons donc notre application avec la classe AsyncTask :

Classe AsyncTask
public class AsyncTastActivity extends Activity {    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    Button btn = (Button) findViewById(R.id.btn);    btn.setOnClickListener(new OnClickListener() {    public void onClick(View v) {    new UseTaskasync().execute();    }    });    }    private class UseTaskasync extends AsyncTask< Void, Void,Void >{         @Override     protected void onPreExecute() {    Toast.makeText(getApplicationContext(), "Début du traitement", Toast.LENGTH_LONG).show();     }      @Override     protected Void doInBackground(Void... params) {     try {     Thread.sleep(10000);     } catch (InterruptedException e) {     }     return null;     }     @Override     protected void onPostExecute(Void l) {     Toast.makeText(getApplicationContext(), "Fin du traitement", Toast.LENGTH_LONG).show();    }     } 

 

Relancez votre application, il est maintenant possible d’utiliser la zone de saisie tout de suite après le clic sur le bouton ! Ceci prouve bien que le traitement n’est pas réalisé par le thread principal mais par le deuxième créé par la classe AsyncTask.

 

 

La classe AsyncTask et ses méthodes permet donc de naviguer dans notre application ( rentrer du texte dans un champ ) tout en éxécutant une tâche au moyen de tâches asyncrones !

Merci d’avoir suivi ce tutoriel ! N’oublie surtout pas de VOTER et de la PARTAGER !!

Catégories
Développement Android

Utilisation de l’API google places, Geocoding et parsage de Json

A la lecture de ce titre, vous vous doutez bien que nous allons aborder plusieurs choses pendant ce tuto :

 

  • Obtention d’une clé pour l’api google places
  • Récupération d’un ou plusieurs lieux ( banque, bar … ) dans un périmètre de 500m selon un point donné
  • Utilisation de la classe geocoder pour transformer une adresse en une coordonnée
  • traitement du résultat renvoyé sous forme de Json

 

 

 

 

 

Tout d’abord, afin d’utiliser l’api google places, il nous faut obtenir une clé de service google places, accessible ici :

https://code.google.com/apis/console/b/0/

 

Dans l’onglet Api access, créez un nouveau compte puis récupérer l’api key.

Dans l’onglet Services, activez « Places API« .

 

Pour pouvoir récupérer les lieux dans les 500m aux environs d’un point ( latitude/ longitude ), il faut appeler une url de ce type en remplaçant le key par la vôtre :

 

https://maps.googleapis.com/maps/api/place/search/json?location=48.9344042,2.3535862&radius=500&types=food&sensor=false&key=METTRE ICI VOTRE KEY



A la racine du Json renvoyé se trouve « results« . Il va contenir une liste de lieux, à un lieu est associé des attributs tels que ( id, name … )

Dans le cadre de ce tutoriel, nous allons nous contenter de demander à un utilisateur de rentrer une adresse, de sélectionner un type de lieu puis de les afficher à l’écran.

 

 

 

Créons donc le layout :

 

<?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 »

  >

 

    <EditText  android:id=« @+id/addr »

        android:layout_width=« fill_parent »

        android:layout_height=« wrap_content »/>

   

 <RadioGroup

     android:id=« @+id/rg1 »

  android:layout_width=« fill_parent »

   android:layout_height=« wrap_content »

   android:orientation=« horizontal »>

   <RadioButton

    android:id=« @+id/option1 »

    android:layout_width=« wrap_content »

    android:layout_height=« wrap_content »

    android:text=« bank » />

   <RadioButton

    android:id=« @+id/option2 »

    android:layout_width=« wrap_content »

    android:layout_height=« wrap_content »

    android:text=« bar » />

   <RadioButton

    android:id=« @+id/option3 »

    android:layout_width=« wrap_content »

    android:layout_height=« wrap_content »

    android:text=« restaurant » />

 </RadioGroup>

 

 <TextView

android:id=« @+id/maTextView »

android:layout_marginTop=« 25px »

android:layout_width=« wrap_content »

android:layout_height=« wrap_content »

android:gravity=« center »/>

 

</LinearLayout>

 

 

 

 

Redéfinition de la méthode OnCreate :


 
 

public void onCreate(Bundle savedInstanceState) {

             super.onCreate(savedInstanceState);

             setContentView(R.layout.main);

             RadioGroup rgroup = (RadioGroup) findViewById(R.id.rg1);

 

 

       //On écoute un changement d’évènement sur les boutons radio

             rgroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                    public void onCheckedChanged(RadioGroup group, int checkedId) {

 

                           try {

                                  //on créé une instance de geocoder

                                  Geocoder gc = new Geocoder(JsonParsingActivity.this);

                                  EditText adress = (EditText) findViewById(R.id.addr);

                                  List<Address> foundAdresses;

                                  /*On récupère l’adresse saisie par l’utilisateur

                                  Pour ceux qui ont suivi le tuto de géolocalisation,il peut etre intéressant de vérifier

                                  qu’une adresse a été saisie,si ce n’est pas fait alors prendre comme adresse la position actuelle de l’utilisateur

                                  */

                                  String addressInput = adress.getText().toString();

                                  //On récupère une liste d’adresse grace à la classe geocoder

                                  foundAdresses = gc.getFromLocationName(addressInput, 5);

                    //On ne s’interesse qu’à la première adresse de la liste,il est cependant possible d’afficher à l’utilisateur

                                  //une liste déroulante d’adresse possible pour qu’il sélectionne la bonne adresse

                                  Address x = foundAdresses.get(0);

                                 //on récupère la latitude et longitude correspondante à l’adresse

                                  final double lat = x.getLatitude();

                                  final double lng = x.getLongitude();

 

                    //on récupère le bouton radio sélectionné

                                  RadioButton rb = (RadioButton) findViewById(checkedId);

                                  //on demande à gogole les lieux avoisinantes correspondant au type sélectionné par l’utilisateur

                                  String  places = getPlaces(rb.getText().toString(),lat,lng);

                                  StringBuilder builder = new StringBuilder();

                                  try {

 

                                         //On parse le Json renvoyé

                                        JSONObject jsonObj = new JSONObject(places);

                                        //l’attribut results est une liste d’objet json donc on le récupère avec getJsonArray

                                        JSONArray results = jsonObj.getJSONArray(« results »);

 

                                        for (int i = 0; i < results.length(); i++) {  

                                               //Pour chaque jsonObjet du jsonArray results on récupère la valeur de l’attribut name

                                               builder.append(results.getJSONObject(i).getString(« name »).toString()).append(« \n »);

                                        }

                                  } catch (Exception e) {

                                        e.printStackTrace();

                                  }

 

                                  ((TextView)findViewById(R.id.maTextView)).setText(builder.toString());

                           } catch (IOException e1) {

                                  // TODO Auto-generated catch block

                                  e1.printStackTrace();

                           }

                    }

             });

 

       }

 

 


On effectue maintenant un appel de l’api places de google :




//google limite le nombre de requettes à 1000 tout les 24h pour un api key donné

       public String getPlaces(String type,double lat,double lng) {

 

             //Url pour la requette

             String url = « https://maps.googleapis.com/maps/api/place/search/json?location= »+lat+ », »+lng+ »&radius=500&types= »+type+ »&sensor=false&key=AIzaSyA5J_JPOa5jtuXaOgbTeHqmNzh61u54hSs »;

 

             StringBuilder builder = new StringBuilder();

             HttpClient client = new DefaultHttpClient();

             HttpGet httpGet = new HttpGet(url);

             try {

                    HttpResponse response = client.execute(httpGet);

                    StatusLine statusLine = response.getStatusLine();

                    int statusCode = statusLine.getStatusCode();

                    //200 pour dire que la requette s’est bien déroulée

                    if (statusCode == 200) {

                           HttpEntity entity = response.getEntity();

                           InputStream content = entity.getContent();

                           BufferedReader reader = new BufferedReader(

                                        new InputStreamReader(content));

                           String line;

                           while ((line = reader.readLine()) != null) {

                                  builder.append(line);

                           }

                    } else {

                           Log.i(JsonParsingActivity.class.toString(), « Erreur de chargement »);

                    }

             } catch (ClientProtocolException e) {

                    e.printStackTrace();

             } catch (IOException e) {

                    e.printStackTrace();

             }

             return builder.toString();

       }

 

 

 

 Et c’est ainsi que s’achève notre tuto sur la géolocalisation via google places !

Bon code à tous 😀

 

 

 

 

 

Catégories
Développement Android

Optimisation de la performance dans les listes déroulantes ( filtrage des listes )

Nous allons dans ce tutoriel voir comment optimiser une liste déroulante afin d’en améliorer la performance et nous verrons comment ajouter un filtre sur une liste qui permettra à l’utilisateur de rechercher l’élément qu’il souhaite afficher. 

  Un exemple de liste avec filtre :

 


Optimisation de la liste déroulante ou le recyclage des items :

 

Un solution d’optimisation d’une liste déroulante comme celle-ci est le recyclage des éléments de la liste.

Même si la liste contient plusieurs éléments, elle ne peut parfois pas tous les afficher si on ne scroll pas, les éléments les plus utiles sont ceux qui sont visibles !

Le principe est simple, à chaque fois qu’une ligne sort de l’écran, nous la recyclons et l’affectons au prochain élément de la liste.

 

Un schéma vaut parfois mieux que des explications ! Voilà qui devrait vous aider à comprendre le principe du recyclage !

 

 

Nous allons maintenant voir comment modéliser tout ça au niveau de nos classes,

 


Modélisation :

 

 

 

La liste déroulante est obtenue grâce à la classe ListView.

Les données de la liste et le layout à utiliser pour les éléments de la liste sont définies par l’adapter.

Pour notre exemple, nous allons définir un CustomAdapter qui va hériter d’un ArrayAdapter ( il en existe d’autres mais nous utiliserons celui-là ).

A chaque ligne de la liste, une méthode getView() sera appelée. A chaque appel, une vue composée de deux vues ( ImageView et Textview ) sera générée.

Toutefois la création d’un objet est coûteux en performance, il faudra donc redéfinir cette méthode pour optimiser la liste ! Notre astuce consistera donc à garder en mémoire la vue sortante et de la recycler comme l’illustre le schéma plus haut.

La vue qu’on souhaite recycler est envoyé en paramètre de la méthode getView en tant que convertView.

Il suffit juste de remplacer son contenu avec le nouveau. On éviter ainsi de créer une nouvelle vue. Un test de nullité doit être effectué sur convertView car ce dernier peut être null.

L’utilisation de la classe static ViewHolder va nous apporter une amélioration supplémentaire. En effet, même si les vues sont recyclés, il faut tout de même récupérer chaque élément de la vue ( ImageView et TextView ) avec la méthode findViewById. L’appel à cette méthode est très couteux en performance. Mais grâce à ViewHolder, chaque vue sera référenciée avec la méthode setTag. On peut donc récupérer les vues des éléments recyclées avec la méthode getTag de la classe ViewHolder, on n’a donc pas recours à la méthode findViewById !

Pour pouvoir filtrer la liste, nous alloons mettre un listener sur notre EditText. L’adapter sera notifié à chaque changement de contenu de l’EditText, la méthode filter() de l’adapter sera appelée.

Bon assez parlé, maintenant place à l’implémentation de tout ça !

 

 

 Implémentation :

 

Le main.xml

c’est ici qu’on déclare nos vues

main.xml
<EditText    android:id="@+id/filtre"    android:layout_width="fill_parent"    android:layout_height="wrap_content"/>      <ListView    android:id="@+id/list"    android:layout_width="fill_parent"    android:layout_height="wrap_content" />

 

Le listitem.xml

on définit les vues contenues dans un élément de la liste

Listitem.xml
<ImageView    android:id="@+id/icon"    android:layout_width="50px"    android:layout_height="50px"    android:layout_marginLeft="4px"    android:layout_marginRight="10px"    android:layout_marginTop="4px" >    </ImageView>        <TextView    android:id="@+id/nom" android:gravity="center"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:textSize="20px" >    </TextView>

 

L’activité principale

 C’est ici que toutes les classes dont nous avons besoin seronts instanciées

Activité principale
adapter = new CustomAdapter(this, Listnoms);    listView = (ListView) findViewById(R.id.list);    listView.setAdapter(adapter);     listView.setTextFilterEnabled(true);      EditText filterEditText = (EditText) findViewById(R.id.filtre);    filterEditText.addTextChangedListener(new TextWatcher() {    @Override    public void onTextChanged(CharSequence s, int start, int before,    int count) {     }    @Override    public void beforeTextChanged(CharSequence s, int start, int count,    int after) {    }    @Override    public void afterTextChanged(Editable s) {    adapter.getFilter().filter(s.toString());     }    });

 

 

Le customAdapter

Cette classe contient toutes les méthodes nécessaires pour le recyclage de vue, les méthodes de ViewHolder qui évite qu’on crée un nouvel élément à chaque fois qu’on navigue dans la liste et le filtre.

CustomAdapter
private final Activity context;    List<String> arrayList;     List<String> listeNom;      static class ViewHolder {    public TextView text;    public ImageView image;    }      public CustomAdapter(Activity context, List<String> listeNom) {    super(context, R.layout.listitem, listeNom);    this.context = context;    this.listeNom = listeNom;    this.arrayList= listeNom;    }      @Override    public View getView(int position, View convertView, ViewGroup parent) {    View rowView = convertView;    if (rowView == null) {    LayoutInflater inflater = context.getLayoutInflater();    rowView = inflater.inflate(R.layout.listitem, null);    ViewHolder viewHolder = new ViewHolder();    viewHolder.text = (TextView) rowView.findViewById(R.id.nom);    viewHolder.image = (ImageView) rowView    .findViewById(R.id.icon);    rowView.setTag(viewHolder);    }      ViewHolder holder = (ViewHolder) rowView.getTag();    String s = listeNom.get(position);    holder.text.setText(s);    holder.image.setImageResource(R.drawable.ic_launcher);    return rowView;    }    @Override    public int getCount() {    return listeNom.size();    }        @Override    public String getItem(int position) {    return listeNom.get(position);    }      @Override    public Filter getFilter() {    return new Filter() {      @SuppressWarnings("unchecked")    @Override    protected void publishResults(CharSequence constraint, FilterResults results) {    listeNom = (ArrayList<String>) results.values;    CustomAdapter.this.notifyDataSetChanged();    }    @Override    protected FilterResults performFiltering(CharSequence constraint) {    ArrayList<String> filteredResults = getFilteredResults(constraint);    FilterResults results = new FilterResults();    results.values = filteredResults;    return results;    }    private ArrayList<String> getFilteredResults(CharSequence constraint) {    ArrayList<String> filteredTeams = new ArrayList<String>();    for(int i=0;i< arrayList.size();i++){    if(arrayList.get(i).toLowerCase().startsWith(constraint.toString().toLowerCase())){    filteredTeams.add(arrayList.get(i));    }    }    return filteredTeams;    }    };    }

 

Et c’est ainsi que s’achève notre tuto sur l’optimisation de liste ! Bonne implémentation à tous et n’oubliez pas de VOTER et de PARTAGER cet article! 

Catégories
Développement Android

Utilisation du Geocoder Android

Google Places LogoGeocoding, Google places API, Parsing Json, http request

Le but de ce tuto est de voir le parsing d’un fichier JSON récupéré à partir d’une requette sur un serveur. Mais nous allons également profiter de ce tuto pour voir rapidement l’API de google, places qui permet d’obtenir différents types de lieux (bar, banque…) autour d’un point donnés. Profitons également de ce tuto pour utiliser la classe geocoder afin de transformer une adresse en un point (lat,long).

Utiliser Google API

 
Obtenir une clé pour le service de google places
https://code.google.com/apis/console/b/0/

Dans l’onglet  API Access  créer un nouveau compte puis récupérer l’API Key.
Dans l’onglet services, activer Places API.

Pour pouvoir récupérer les lieux dans les 500m aux environs d’un point (lat/long), il faut appeler une url de ce type en remplaçant le key par le votre
https://maps.googleapis.com/maps/api/place/search/json?location=48.9344042,2.3535862&radius=500&types=food&sensor=false&key=METTRE ICI VOTRE KEY

A la racine du JSON renvoyé se trouve results. Il va contenir une liste de lieux. A chaque lieu est associé un ensemble d’attributs (id, name…)

 

Création de la vue

Dans le cadre de ce tutoriel nous allons nous contenter de demander à un utilisateur de rentrer une adresse, de sélectionner un type de lieu puis de les afficher à l’écran.
 
Créons le layout :
 
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  >    <EditText android:id="@+id/addr"  android:layout_width="fill_parent"  android:layout_height="wrap_content"/>   <RadioGroup  android:id="@+id/rg1"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:orientation="horizontal">  <RadioButton  android:id="@+id/option1"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="bank"/>  <RadioButton  android:id="@+id/option2"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="bar"/>  <RadioButton  android:id="@+id/option3"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="restaurant"/> </RadioGroup>   <TextView android:id="@+id/maTextView" android:layout_marginTop="25px" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center"/>   </LinearLayout>

 

Redéfinition de la méthode Oncreate

Rédéfinition de la méthode OnCreate
publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); RadioGroup rgroup = (RadioGroup) findViewById(R.id.rg1);      //On écoute un changement d'évènement sur les boutons radio rgroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { publicvoid onCheckedChanged(RadioGroup group, int checkedId) {    try { //on créé une instance degeocoder Geocoder gc = new Geocoder(JsonParsingActivity.this); EditText adress = (EditText) findViewById(R.id.addr); List<Address> foundAdresses; /*On récupère l'adresse saisie par l'utilisateur Pour ceuxquiontsuiviletutodegéolocalisation,ilpeutetreintéressantdevérifier qu'une adresse a étésaisie,sice n'est pas faitalorsprendrecommeadressela position actuellede l'utilisateur */ String addressInput = adress.getText().toString();  //On récupèreuneliste d'adresse grace à laclassegeocoder foundAdresses = gc.getFromLocationName(addressInput, 5);  //On ne s'interesse qu'à lapremièreadressedelaliste,ilestcependant possible d'afficher à l'utilisateur //unelistedéroulante d'adresse possible pour qu'il sélectionnelabonneadresse Address x = foundAdresses.get(0); //on récupèrela latitude et longitude corréspondante à l'adresse finaldouble lat = x.getLatitude(); finaldouble lng = x.getLongitude();    //on récupère le bouton radio sélectionné RadioButton rb = (RadioButton) findViewById(checkedId); //on demande à gogoleleslieuxavoisinantescorrespondantau type sélectionné par l'utilisateur String places = getPlaces(rb.getText().toString(),lat,lng); StringBuilder builder = new StringBuilder(); try {   //On parse leJsonrenvoyé JSONObject jsonObj = new JSONObject(places);  //l'attribut results estuneliste d'objet jsondonc on lerécupèreavec getJsonArray JSONArray results = jsonObj.getJSONArray("results");   for (int i = 0; i < results.length(); i++) { //Pour chaque jsonObjet du jsonArray results on récupèrelavaleurde l'attribut name builder.append(results.getJSONObject(i).getString("name").toString()).append("\n"); } } catch (Exception e) { e.printStackTrace(); }   ((TextView)findViewById(R.id.maTextView)).setText(builder.toString());  } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }  }  });    }

 

Appel de l’API places de google

API Google
//google limite le nombrederequettes à 1000 tous les 24h pour un api key donné public String getPlaces(String type,double lat,double lng) {   //Url pour la requête String url = "https://maps.googleapis.com/maps/api/place/search/json?location="+lat+","+lng+"&radius=500&types="+type+"&sensor=false&key=AIzaSyA5J_JPOa5jtuXaOgbTeHqmNzh61u54hSs";   StringBuilder builder = new StringBuilder(); HttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); try { HttpResponse response = client.execute(httpGet); StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); //200 pour dire que la requette s'est bien déroulée if (statusCode == 200) { HttpEntity entity = response.getEntity(); InputStream content = entity.getContent(); BufferedReader reader = new BufferedReader( new InputStreamReader(content)); String line; while ((line = reader.readLine()) != null) { builder.append(line); } } else { Log.i(JsonParsingActivity.class.toString(), "Erreur de chargement"); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return builder.toString(); }

 

Catégories
Développement Android

Tutoriel google maps de géolocalisation en temps réel

Vous-êtes vous déjà demander comment faire pour afficher sa position en temps réel via un GPS sur son smartphone ? Et bien cet article vous l’expliquera pas à pas !

Attention, ce tuto s’adresse aux gens qui s’y connaissent déjà en programmation android et qui possède certaines bases !

Nous allons développer une application de géolocalisation via Google maps ( rien de très original ). La particularité de notre appli sera de pouvoir savoir à quel adresse on se trouve en temps réel grâce à un simple clic sur l’icône indiquant notre position.

 

Pré-requis pour cette application :

  • Connaissance en programmation orientée objet ( POO )
  • Connaissance du cycle de vie d’une activity
  • Récupérer un apiKey pour l’utilisation du google map ( voir le tuto Obtention d’une clé pour l’api google map )


<p >Rappel de la commande :

keytool -list -alias androiddebugkey \

<p >-keystore <chemin_du_debug_keystore>debug.keystore \

-storepass android -keypass android

 

 Dans le manifest.xml, il vous faudra ajouter les permissions suivantes :

 

– Les permissions pour l’accès à internet : <uses-permission android:name= »android.permission.INTERNET » />

 – Access_fine_location : <uses-permission android:name= »android.permission.ACCESS_FINE_LOCATION » />

– Access-coarse_location : <uses-permission android:name= »android.permission.ACCESS_COARSE_LOCATION » />

– Il faut également ajouter la librairie de google map : <uses-library android:name= »com.google.android.maps » />


Dans votre layout/ main.xml, ajoutez le layout suivant :

main.xml
<com.google.android.maps.MapView     android:id="@+id/mapview"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:apiKey="Votre cle google map" /> 


Modélisation :

 

La classe que nous devons créée héritera de la classe abstraite MapActivity pour pouvoir afficher la carte.

On implémentera également LocationListener qui permettra de mettre à jour la carte lorsqu’une nouvelle position est détectée.

Une instance de la classe LocationManager nous permettra d’accéder aux services de localisation.

Si on souhaite également afficher une boussole et un rond bleu autour de notre point, on devra utiliser une instance de la carte MyLocationOverlay.

 

voici un diagramme de classe présentant les interactions entre les classes :

 

 

Implémentation :

 Voici donc le code de notre activité principale !

Activité principale
public class GmapActivity extends MapActivity implements LocationListener{        private MapController mapController;    private MapView mapView;    private LocationManager locationManager;    MyLocationOverlay myLocationOverlay;   private MyOverlays itemizedoverlay;       public void onCreate(Bundle bundle) {    super.onCreate(bundle);    setContentView(R.layout.main);       mapView = (MapView) findViewById(R.id.mapview);    mapView.setBuiltInZoomControls(true);    mapView.setSatellite(true);         mapController = mapView.getController();     mapController.setZoom(18);         locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, this);         myLocationOverlay = new MyLocationOverlay(this, mapView);    mapView.getOverlays().add(myLocationOverlay);        myLocationOverlay.runOnFirstFix(new Runnable() {    public void run() {    mapView.getController().animateTo(    myLocationOverlay.getMyLocation());    }    });        Drawable drawable = this.getResources().getDrawable(R.drawable.ic_launcher);    itemizedoverlay = new MyOverlays(drawable, mapView);    afficherMarker();    }         @Override    protected void onResume() {    super.onResume();    myLocationOverlay.enableMyLocation();    myLocationOverlay.enableCompass();    }        @Override    protected void onPause() {    super.onResume();    myLocationOverlay.disableMyLocation();    myLocationOverlay.disableCompass();    }       @Override    protected boolean isRouteDisplayed() {     return false;    }         @Override     public void onLocationChanged(Location location) {     int lat = (int) (location.getLatitude() * 1E6);     int lng = (int) (location.getLongitude() * 1E6);     GeoPoint point = new GeoPoint(lat, lng);         mapController.animateTo(point);    mapController.setCenter(point);     afficherMarker();    }        @Override    public void onProviderDisabled(String provider) {    }         @Override     public void onProviderEnabled(String provider) {     }         @Override     public void onStatusChanged(String provider, int status, Bundle extras) {     }     private void afficherMarker() {    GeoPoint p = mapView.getMapCenter();     Geocoder gcd = new Geocoder(GmapActivity.this, Locale.getDefault());    String addr ="";    List<Address> addresses;    try {    addresses = gcd.getFromLocation( (p.getLatitudeE6() / 1E6) , (p.getLongitudeE6() / 1E6) ,1);        if (addresses.size() > 0 && addresses != null) {    addr = addresses.get(0).getAddressLine(0);     OverlayItem overlayitem = new OverlayItem(p, "Adress",addr);    itemizedoverlay.addOverlay(overlayitem);    mapView.getOverlays().add(itemizedoverlay);    }    } catch (IOException e) {    e.printStackTrace();    }     }    }

 

Voici maintenant la classe MyOverLays qui hérite de la classe abstraite ItemizedOverlay<OverlayItem>. Cette classe permet de gérer l’affichage des overlays sur la carte ( curseur, etc … )

Deux méthodes abstraites ( createItem et size ) de la classe Itemized<OverlayItem> ainsi que la méthode onTap ( détection du clic sur l’overlay ) devront être redéfinies.

 

Modélisation de ces classes :

 

 

 

 

Implémentation :

 

public class MyOverlays extends ItemizedOverlay<OverlayItem> {    private OverlayItem overlays[] = new OverlayItem[1];     //private ArrayList<OverlayItem> m_overlays = new ArrayList<OverlayItem>();    private Context c;        public MyOverlays(Drawable defaultMarker, MapView mapView) {    super(boundCenterBottom(defaultMarker));    c = mapView.getContext();    }        public void addOverlay(OverlayItem overlay) {    overlays[0] = overlay;     populate();    }        @Override    protected OverlayItem createItem(int i) {    return overlays[i];    }        @Override    public int size() {    return overlays.length;    }        @Override    protected boolean onTap(int index) {    OverlayItem overlayItem = overlays[index];    Toast.makeText(c,overlayItem.getSnippet() , Toast.LENGTH_LONG)    .show();    return true;    };       }

 

Ainsi s’achève ce tuto sur la géolocalisation sur google maps ! Bonne implémentation à vous !

Il est possible de récupérer le zip du projet associé à ce tuto sur demande ! ( Postez des commentaires 😉 )

Catégories
Développement Android

Optimiser son site mobile pour les téléphones Android

Android pour le Web MobileIl est important, en développant un site mobile, de tenir compte de l’expérience utilisateur. Votre application se démarquera toujours de celles des autres grâce à ce petit truc en plus que ressent le mobinaute en utilisant votre application. Vous souhaitez passer de…rien du tout, au top 10 ? Alors pensez à vos utilisateurs. Cette idée s’applique au développement d’applications en générale, mais dans cet article nous nous limiterons au développement de sites mobiles, en étudiant ce que préconise Google en la matière.

Tous les smartphones actuels, et Android en particulier, parlent couramment le HTML, le CSS et bien sûr, le Javascript. Cependant, et à la différence de l’iPhone, la résolution d’écran d’un smartphone est variable d’un constructeur à l’autre. Rappelons que Google ne propose d’un OS, et non le smartphone tout en entier. Donc, il faut pouvoir gérer ces nombreuses résolutions d’écran, qui souvent posent des soucis d’esthétiques.

Deux facteurs fondamentaux sont a étudier de près quand on souhaite optimiser sa page web pour Android :

  • La taille de l’écran et l’échelle de la page
  • La densité de l’écran

Gérer la taille de l’écran et l’échelle de la page avec la métadonée viewport

Par défaut, lorsque le navigateur d’Android charge une page Web, elle est chargé en mode « Vue d’ensemble » (Overview mode), qui demande bien souvent de cliquer sur le bouton de zoomage pour mieux afficher ce que l’on souhaite regarder. Il est très facile surcharger ce comportement par défaut en précisant la taille initiale de la page, tout en offrant la possibilité ou non de zoomage.

Pour ce faire, on utilise une métadonnée nommée viewport. Le viewport en lui-même est l’espace dans lequel votre page web est dessinée (canvas), c’est à dire le nombre de pixels de la page web. Il est toujours supérieur ou égal à la taille de l’écran lui-même. Cependant, la partie visible du viewport est toujours égale à la taille de l’écran. Ce qui fait que pour un viewport supérieur à la taille de l’écran on ait un affichage peu visible, nécessitant un zoom de la page.

Ce problème se résout facilement en décidant que la taille du viewport soit exactement égale à la taille de l’écran du device (width=device-width). Dans l’entête HTML il suffit d’écrire :

Metadonnée viewport
1 2 3 4 
<head>  <title>Une page optimisée pour Android</title>  <meta name="viewport" content="width=device-width, user-scalable=no" /> </head>

Le paramètre user-scalable=no précise qu’il n’est pas possible de zoomer ou même de dézoomer. la métadonnée viewport peut prendre plusieurs paramètres, chacun étant séparé par une virgule.

Utilisation avancée du viewport
1 2 3 4 5 6 7 8 9 10 11 
<meta name="viewport"  content="  height = [valeur_en_pixel | device-height] ,  width = [valeur_en_pixel | device-width ] ,  initial-scale = valeur_numérique_float ,  minimum-scale = valeur_numérique_float ,  maximum-scale = valeur_numérique_float ,  user-scalable = [yes | no] ,  target-densitydpi = [dpi_value | device-dpi |  high-dpi | medium-dpi | low-dpi]  " />

Il en résulte un affichage automatique de la page, fonction du viewport. Ci-dessous, le résultat de l’affichage d’une image pour des d’écrans différentes, grande (gauche) et petite (droite) :

Android viewport

Il dans ce cas important de mettre l’échelle de l’écran à 1, ce qui permet un affichage direct du contenu de la page. On aura donc finalement :

Utilisation de la metadonnée viewport
1 
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

 

valeur_en_pixel

Gérer la densité de l’écran

L’OS Android gère trois densités d’écran différentes en dpi (dots per inch, point par pouce en français), fonctions du device utilisé :

  • ldpi
  • mdpi
  • hdpi

Par défaut, le navigateur Android utilise la densité mdpi pour afficher une page web. Ainsi, si l’on essai d’afficher une image basse résolution, sur un smartphone de densité mdpi ou hdpi, on aura un affichage semblable au dessin de gauche, contre celui de droite pour une optimisation de l’affichage :

Android densité

Pour optimiser sa page, en fonction de la densité ciblée, on utilise des propriétés CSS particulières appelées media queries:

Optimisation en fonction de la densité
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 
#contenu {  background:url(medium-density-image.png); }   @media screen and (-webkit-device-pixel-ratio: 1.5) {  /* CSS optimisé pour un affichage hdpi */  #contenu {  background:url(high-density-image.png);  } }   @media screen and (-webkit-device-pixel-ratio: 0.75) {  /* CSS optimisé pour un affichage ldpi */  #contenu {  background:url(low-density-image.png);  } }

 

On peut également utiliser la métadonnée viewport, pour un affichage automatique fonction de la densité du device :

Optimisation de la densité en HTML
1 
<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />

 

Pour en savoir plus :

Catégories
Développement Android

Titanium Android – Faire son parseur Json

JSONBonjour tout le monde ! Aujourd’hui encore une fois un tuto sur Titanium ! Nous allons voir Comment parser un fichier json sur notre plateforme adorée 😀 

Le parseur sur Titanium est plus simple à réaliser que le parseur Android, en effet il suffit de quelques fonctions et le tour est joué !

Pour parser un fichier json, la règle de base c’est ….

1. Avoir un fichier json à parser !

Pour ce tutoriel, nous allons utiliser le fichier json suivant :

 

{« Id »: »221″, »Nom »: »video_221″, »Url_miniature »: »http://www.interieurs.fr/hwdvideos/thumbs/remote-1277.jpg », »Url_video »: »http://www.pocketjourney.com/downloads/pj/video/famous.3gp », »Date_publication »: »27/06/11″, »Categorie »: »Relooking »},
{« Id »: »220″, »Nom »: »video_220″, »Url_miniature »: »http://www.interieurs.fr/hwdvideos/thumbs/remote-1277.jpg », »Url_video »: »http://www.pocketjourney.com/downloads/pj/video/famous.3gp », »Date_publication »: »27/06/11″, »Categorie »: »Sortie »}]

 

le fichier json est disponible à cette url : http://www.michaelfabien.com/interieurs/video.json.

Un item de ce fichier json se présente avec les attributs suivants :id, nom, url_miniature, url_video, date_publication.

Pour ce tuto, nous allons utiliser uniquement les attributs nom, url_miniature et date de publication. 

 

Afin de récupérer ces données dans notre appli, il est maintenant temps d’utiliser ….

 

 

2. Le parseur !

Nous allons maintenant attaquer la fonction du parseur json, nous allons procéder comme ceci : la fonction va prendre le fichier json, le parser, puis présenter les données dans un tableview.

Voilà le début de notre code :

 

var win = Titanium.UI.createWindow(); //on crée une fenêtre

 

Voilà la fonction qui va tout faire !

function loadVideos(){

var loader = Titanium.Network.createHTTPClient(); //la méthode createHttpClient() de Titanium qui va nous permettre de faire des requêtes sur le serveur ou est stocké le fichier json.

var rowData = []; //l’array où sera stocké chaque ligne du tableview.

//on indique quel type de requête on va utiliser et l’url de notre fichier json
loader.open(« GET », »http://www.michaelfabien.com/interieurs/video.json »);

 

//une fois le fichier json récupéré, on éxécute une fonction
loader.onload = function()
{

On stocke le fichier json dans une variable, à ce stade le fichier Json est DEJA PARSE !!!

var res = eval(‘(‘+this.responseText+’)’);

 

Maintenant que nous avons notre json parsé dans la variable res, il serait bien de pouvoir récupérer les attributs qui nous intéressent pour chaque video, c’est-à-dire le nom de la video, la miniature et la date de publication,

Pour se faire nous allons utiliser une boucle for !

 

//on fait une boucle afin de récupérer les attributs qu’on veut de chaque item
for (var i = 0; i < res.length; i++)    
{

//on récupère uniquement le attributs qui nous intéressent
var nom_video = res[i].Nom;//on récupère le nom
var url_image = res[i].Url_miniature;//l’url de la miniature
var date = res[i].Date_publication;//on récupère la date de publication

 

Nous avons les variables pour le nom, la miniature et la date de publication de la video, il nous faut maintenant le présenter dans une vue qu’on va appeler post_view,

La miniature se situera à gauche, le nom et la date à sa droite.

Nous ajouterons ensuite le post_view à une variable appelée row.

 

//on crée une row et on définit sa taille sur auto
var row = Titanium.UI.createTableViewRow({height:’auto’});

//on crée une vue qui va contenir le nom et la miniature de la video
var post_view = Titanium.UI.createView({ height:’auto’ });

 

Une fois post_view et row prêt, il nous faut maintenant créer un ImageView pour afficher une miniature de video, créer des labels pour afficher le nom et la date de publication.

 

//on crée une ImageView qui contiendra la miniature de la video 
var video_image = Titanium.UI.createImageView({ 
url:url_image, //url_image, c’est l’attribut qu’on a récupéré plus haut
top:0, 
left:0, 
height:75, 
width:75 
});

//on ajoute video_image à post_view
post_view.add(video_image); 

 

//on crée maintenant le label avec le nom de la video 
var nom_label = Titanium.UI.createLabel({ 
text:nom_video, //nom_video a été récupéré plus haut également
left:100, 
width:120, 
top:5, 
height:’auto’, 
textAlign:’left’, 
color:’black’, 
font:{ 
fontSize:20,fontWeight:’bold’ 

});

post_view.add(nom_label); // on ajoute au postview également

 

//On crée le label pour une date
var date_label = Titanium.UI.createLabel({ 
text: date,//la variable date plus haut 
color:’black’,
left: 100, 
top: 30,  
height: ‘auto’, 
width: 120, 
textAlign: ‘left’, 
color:’black’, 
font:{ fontSize:16 } 
}); 

post_view.add(date_label);

 

Une fois le post_view « complet », on l’ajoute à la row ! Row est ensuite ajouté à rowData à chaque fois que la boucle for tourne !

row.add(post_view);

//on ajoute row dans notre tableau rowData
rowData[i] = row;

 

Ceci marque la fin de notre boucle !

}

Et pour finir !

On crée le tableview qui montrera toutes les lignes stockées dans rowData, il ne restera plus qu’à ajouter le tableview à notre window. Attention le code suivant n’est plus dans la boucle for mais est toujours dans la fonction onload !

 

//On crée le tableview avec comme données celles contenues dans rowData 
var table_video = Titanium.UI.createTableView( { data : rowData });

//On ajoute la tableview à la window 
win.add(table_video);

}

Il ne reste plus qu’à envoyer la requête pour finir la fonction loadVideos !

loader.send();

}

Et surtout ne pas oublier d’appeler la fonction loadVideos à la fin 😉

loadVideos();

Vous devriez maintenant avoir un tableau qui s’affiche avec toutes les données contenues dans rowData de manière assez bien présenté 😀

 

Merci d’avoir suivi ce tuto j’espère qu’il vous a été très utile ! A vous de coder maintenant !

Catégories
Développement Android

Titanium Android – Créer un formulaire et l’envoyer

Salut tout le monde ! Aujourd’hui nous allons voir comment créer un formulaire tout simple sur Titanium et envoyer le contenu de ce formulaire sur une autre page ! Rapellons très rapidement que Titanium est un framework de développement d’applications mobiles cross-plateform. Il est possible en effet grâce à Titanium de développer une application native iPhone et Android, à partir d’un seul projet.

Ici nous allons faire simple, en créant un simple formulaire, histoire de voir comment un mecanisme d’authentification peut être implémenter avec Titanium

Rien de bien compliqué en somme, voyons d’abord comment faire un login/mot de passe avec bouton d’envoi !

 

Premièrement on crée notre window et notre vue dans un fichier form.js :

form.js
1 2 3 
var win = Titanium.UI.createWindow();   var view_form = Titanium.UI.createView();

 

On crée ensuite nos 2 Textfields, un pour le login et un pour le mot de passe !

 

form.js – textfields
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
//textfield pour le login   var login = Titanium.UI.createTextField({   hintText:"Login" // permet d'indiquer à quel valeur correspond le champ de textte à l'utilisateur, ici au login borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED, // on applique un style au bordure du textfield width:200, // taille horizontal du textfield top:180 // on place le textfield à 180 pixels du haut de la fenêtre   });   //textfield pour le mot de passe   var password = Titanium.UI.createTextField({   hintText:"Password", //on indique que la valeur à entrer est le mot de passe borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED, width:200, top:250, passwordMask:true //on masque les caractères qui seront tapés ( comme les mots de passe en génréral )   });   //bouton d'envoi   var button = Titanium.UI.createButton({   title:'Se connecter', // le nom du bouton top:340, height:'auto' // on lui attribue une taille automatique   });

 

Voila pour le formulaire, maintenant il faut pouvoir gérer le passage de variables vers une autre page:

Il faut créer un évènement qui s’active au clic de la souris sur le bouton d’envoi du formulaire, pour cela on fait :

 

button.addEventListener(‘click’,function(){

 

On récupère ensuite les valeurs des textfields dans des variables :

var loginUser = login.value ; //on attribue le login entré par l’utilisateur à cette variable

var passwordUser = password.value ; // on attribue le mot de passe entré par l’utilisateur à cette variable

 

Cela se passe comme ceci, on crée un array, ici myArray

var myArray = [value1,value2 ]; // avec value1 et value2 les variables qu’on souhaite faire passer

Dans notre cas, cela donne :

var myArray = [loginUser,passwordUser];

 

On crée ensuite la window à laquelle nous allons envoyer les variables :

Passage de variables
1 2 3 4 5 6 7 8 
var win_confirmation = Titanium.UI.createWindow({   url:'confirmation.js', //on précise la page vers laquelle on va être redirigé myarray:myArray // on passe en paramètre myArray, l'autre page devrait être en mesure de récupérer les données !   });   win_confirmation.open(); // on ouvre ensuite la fenêtre.

 

Et voilà on en a donc fini pour l’envoi de paramètres !!! Voilà le code global de la page form.js :

form.js – Code complet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 
var view_form = Titanium.UI.createView();

var win = Titanium.UI.createWindow();
  //textfield pour le login   var login = Titanium.UI.createTextField({   hintText:"Login" // permet d'indiquer à quel valeur correspond le champ de textte à l'utilisateur, ici au login borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED, // on applique un style au bordure du textfield width:200, // taille horizontal du textfield top:180 // on place le textfield à 180 pixels du haut de la fenêtre   });   //textfield pour le mot de passe   var password = Titanium.UI.createTextField({   hintText:"Password", //on indique que la valeur à entrer est le mot de passe borderStyle:Titanium.UI.INPUT_BORDERSTYLE_ROUNDED, width:200, top:250, passwordMask:true //on masque les caractères qui seront tapés ( comme les mots de passe en génréral )   });   //bouton d'envoi   var button = Titanium.UI.createButton({   title:'Se connecter', // le nom du bouton top:340, height:'auto' // on lui attribue une taille automatique   });   button.addEventListener('click',function(){   var loginUser = login.value ; //on attribue le login entré par l'utilisateur à cette variable   var passwordUser = password.value ; // on attribue le mot de passe entré par l'utilisateur à cette variable   var myArray = [loginUser,passwordUser];   var win_confirmation = Titanium.UI.createWindow({   url:'confirmation.js', //on précise la page vers laquelle on va être redirigé myarray:myArray // on passe en paramètre myArray, l'autre page devrait être en mesure de récupérer les données !   });   win_confirmation.open(); // on ouvre ensuite la fenêtre.   });   //on oublie pas d'ajouter le tout à la vue !   view_form.add(login);   view_form.add(password);   view_form.add(button);   // ... et la vue à la window !   win.add(view_form);   win.open(); // on ouvre la fenêtre

 

Il nous reste maintenant à faire la page où les données seront récupérés, ne vous inquiétez pas, c’est loin d’être le plus compliqué ! 😀

1 2 3 4 5 6 7 8 
var win = Titanium.UI.currentWindow;   //On récupère les paramètres de notre variable myArray var data = win.myarray; //on attribue l'array qu'on récupère à la variable data   var login = data[0]; // data[0] correspond au login, on l'attribue à une variable   var password = data[1]; // data[1] correspond au mot de passe, on l'attribue à une variable également

 

Maintenant il faut afficher le tout 😉

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 
//on crée une vue   var view = Titanium.UI.createView();   //on affiche le login var message_login = Titanium.UI.createLabel({   text:login, //la valeur du texte est égale à login top:100, color:'black', textAlign:'center', font:{fontSize:20,fontStyle:'bold'},   });   //on affiche le mot de passe var message_password = Titanium.UI.createLabel({   text:password, //on affiche le mot de passe top:150, color:'black', textAlign:'center', font:{fontSize:20,fontStyle:'bold'},   });

 

Ce qui donne au final ce code là 😀

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 
var win = Titanium.UI.currentWindow;   //On récupère les paramètres de notre variable myArray var data = win.myarray; //on attribue l'array qu'on récupère à la variable data   var login = data[0]; // data[0] correspond au login, on l'attribue à une variable   var password = data[1]; // data[1] correspond au mot de passe, on l'attribue à une variable également   //on affiche le login var message_login = Titanium.UI.createLabel({   text:login, //la valeur du texte est égale à login top:100, color:'black', textAlign:'center', font:{fontSize:20,fontStyle:'bold'},   });   //on affiche le mot de passe var message_password = Titanium.UI.createLabel({   text:password, //on affiche le mot de passe top:150, color:'black', textAlign:'center', font:{fontSize:20,fontStyle:'bold'},   });   view.add(message_login);   view.add(message_password);   win.add(view);   win.open();

 

Et voilà ainsi s’achève ce tuto sur comment envoyer des données d’un formulaire ( ou les données en général ) vers une autre page sur Titanium !!! Néanmoins, vous remarquerez que dans ce tuto, nous n’avons pas vraiment insisté sur la sécurité, le but étant avant tout de montrer comment ça marche 😛

Je vous dis donc à la prochaine pour unnouveau tuto sur Titanium chers mobinautes !

var view_form = Titanium.UI.createView();
Catégories
Développement Android

Publier une application sur le market

Android Market LogoAfin de publier une application sur le market, il faut avoir au préalable un compte Android Market. Si ce n’est pas le cas, referez-vous au tutoriel concernant l’ouverture d’un compte Market –> ici !.

Tout d’abord, rendez-vous à l’adresse suivante : https://market.android.com/publish/

Vous devez être connecté sur le compte google avec lequel vous avez ouvert le compte market. De toute façon si ce n’est pas le cas, il vous sera demandé de vous connecter.

Enfin si vous n’avez pas de compte Market, il vous proposera d’en créer un.

 

 

 

Vous pouvez donc ajouter une nouvelle appli en cliquant sur le bouton « Publier une application » comme il est indiqué ci-dessus.

 

 

 

On se trouve maintenant sur l’interface de publication d’une application, il vous sera demandé de renseigner « quelques » informations avant de publier votre article ( et oui sinon ça serait trop facile Content ) :

 

 

  1. Sélectionnez votre fichier apk ( bien sélectionné le fichier signé avec la clé privée et non celui signé par défaut avec le debug ). J’insiste une nouvelle fois signez votre application avec une clé privée avant de faire cette opération ( tuto –> ici ) .
  2. Importez le fichier apk.
  3. Il vous faut quelques captures d’écran de votre application, ces captures seront visibles sur la page dédiée à votre application sur le market.
  4. Importez vos captures d’écran.
  5. Tout comme les captures d’écran, il vous faut une icône pour votre application !!!
  6. Importez votre icône.

 

 

 

 

Il vous faudra également renseigner certaines informations sur l’application.

7. Choisissez la langue de l’application.

8. Un titre pour votre application ( logique me direz-vous !)

 

 

9. Sélectionner le type d’application, donc « applications »

10. Choisissez dans quel catégorie se situe votre application ( jeux, santé et remise en forme, etc…  )

11. Pour la suite, à vous de mettre ce que bon vous semble, en fonction de votre application.

 

 

 

 

Acceptez ensuite les deux conditions imposées en bas puis cliquez sur le bouton « Publier ».

Et voilà votre application est disponible maintenant sur le Market et téléchargeable !

Rendez-vous donc sur le market avec votre mobile pour rechercher votre application !

 

Je vous dis donc salut et à très bientôt pour de prochaines tutos ! Cool