RSS Feed

Archives de la catégorie ‘Développement’

Créer un dépôt git sur un mutualisé OVH

27 December 2011 par SeB Pas de commentaire »

Ça fait un petit moment que je cherche à avoir une gestion de configuration locale et distante avec un accès privé. Git permet de faire de la gestion de configuration locale assez facilement. De plus, je viens d’apprendre récemment que les serveurs mutualisés d’OVH proposent l’utilitaire git ! :-o

La version disponible sur les serveurs mutualisés semble assez ancienne et je n’ai pas trouvé la bonne méthode pour créer correctement un dépôt partagé. Cependant, je suis tombé sur la méthode de Nicolas Thouven pour créer un dépôt git sur un mutualisé OVH. Sa méthode consiste à créer localement un dépôt mutualisé puis à le déposer sur le serveur pour enfin le cloner localement ! Ça fonctionne très bien ainsi.

J’ai tellement de projets à passer sous git que j’ai même créé un script shell pour migrer un projet sous git avec un dépôt distant chez OVH. Voici le script que j’utilise et qui être adapté selon vos besoins :

#!/bin/bash
if (($#!=2)); then
echo "ligne de commande : $0 projet_source projet_destination"
exit -1
fi

WORKSPACE_DIR="/f/android/workspace-android"
GIT_REMOTE_PATH="monloginovh@mondomainovh.com:~/git_folder/"
GIT_URL="ssh://$GIT_REMOTE_PATH"

PROJECT_SRC=$1
PROJECT_SRC_DIR="$WORKSPACE_DIR/$PROJECT_SRC"
PROJECT_NAME=$2
PROJECT_GIT_NAME="$2.git"
PROJECT_DST_DIR="$WORKSPACE_DIR/$PROJECT_NAME"
PROJECT_TMP_DIR="~/$PROJECT_GIT_NAME"
PROJECT_URL="$GIT_URL$PROJECT_GIT_NAME"

echo "Creation d'un projet GIT pour $PROJECT_SRC_DIR"
cd $PROJECT_SRC_DIR
echo "bin" > .gitignore
git init
git add .
git commit -m "Version initiale"

echo "Creation du depot de reference dans $PROJECT_TMP_DIR"
cd $PROJECT_SRC_DIR
git clone --bare . $PROJECT_TMP_DIR
cd $PROJECT_TMP_DIR
git --bare update-server-info
cd hooks/
mv post-update.sample post-update
chmod a+x post-update

echo "Copie sur le serveur $GIT_REMOTE_PATH"
scp -r $PROJECT_TMP_DIR $GIT_REMOTE_PATH
cd $WORKSPACE_DIR
rm -Rf $PROJECT_TMP_DIR

echo "Utilisation du depot de reference $PROJECT_URL pour $PROJECT_DST_DIR"
git clone $PROJECT_URL
cd $PROJECT_DST_DIR
touch README
git add README
git commit -m "Ajout du fichier README"
git push

Vous allez pouvoir créer maintenant vos dépôts privés en toute simplicité ! ;-) Il ne me reste plus qu’à trouver un plugin git pour Eclipse digne de ce nom…

 

Au coeur du système Android – permettre l’installation sur la carte mémoire avec Froyo 2.2

3 November 2010 par SeB Pas de commentaire »

Continuons le tour du système Android avec un sixième billet dans la série sur Au coeur du système Android.

Introduction

L’une des grandes nouveautés apportées avec la version Froyo 2.2 est la possibilité d’installer les applications sur la carte mémoire plutôt que dans la mémoire interne de l’appareil. Cette fonctionnalité permet de ne plus saturer la mémoire du téléphone. Pour installer une application sur la carte mémoire, il faut que les développeurs l’autorisent. Une mise à jour des applications est donc nécessaire pour ajouter ce comportement.

Solution

Pour que les utilisateurs puissent installer vos applications sur la carte mémoire, il faut donc les déclarer comme installables sur ce support. Ceci ce fait dans le fichier AndroidManifest.xml en y modifiant la déclaration du tag suivant :

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 android:installLocation="auto"
 ...>

L’attribut installLocation peut prendre les valeurs auto, preferExternal ou internalOnly. Attention, cette balise n’est disponible que depuis Android 2.2. Alors, si vous développez une application compatible avec Android 1.5 il faut modifier la configuration du SDK dans le fichier AndroidManifest.xm comme ceci :

<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />

Prenez garde à toujours utiliser du code compatible avec l’API 3 (ie. Android 1.5).

Il n’est pas recommandé d’installer des applications sur la carte mémoire si elle utilise des fonctionnalités telles que les services, les alertes, les IME, les papiers peints animés, les widgets, etc…

Conclusion

Après une mise à jour de votre application sur l’Android Market, vos utilisateurs pourront la déplacer sur la carte mémoire.

 

Au coeur du système Android – rendre visible son application sur l’Android Market pour les HTC Wildfire

11 October 2010 par SeB Pas de commentaire »

Continuons le tour du système Android avec un cinquième billet dans la série sur Au coeur du système Android.

Introduction

Toutes les applications que j’ai pu réaliser sont compatibles avec Android 1.5 et supérieur. Or de nombreux utilisateurs, possédant un HTC Widlfire,m’ont signalé qu’ils ne les voyaient sur l’Android Market. Après quelques recherches, je me suis rendu compte que ce téléphone a un écran de taille réduite qui restreint l’accès aux applications sur le Market.

Solution

Pour que les HTC Wildfire puissent voir vos applications sur l’Android Market, il faut donc les déclarer comme compatibles avec les téléphones ayant un écran de taille réduite. Ceci ce fait dans le fichier AndroidManifest.xml en y ajoutant les lignes suivantes :

<supports-screens android:smallScreens="true"
 android:normalScreens="true"
 android:anyDensity="true"
 android:largeScreens="true"
 android:resizeable="true" />

Attention, cette balise n’est disponible que depuis Android 1.6. Alors, si vous développez une application compatible avec Android 1.5 il faut modifier la configuration du SDK dans le fichier AndroidManifest.xm comme ceci :

<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="4" />

Prenez garde à toujours utiliser du code compatible avec l’API 3 (ie. Android 1.5).

Conclusion

Après une mise à jour de votre application sur l’Android Market, elle sera visible des HTC Wildfire.

 

Java – impossible de supprimer des éléments dans une liste

2 September 2010 par SeB 3 commentaires »

Parfois, le Java peut nous rendre quelque peu perplexe. Prenons par exemple le code suivant :

String s[] = {"1","2","3","4"};
List<String> l = Arrays.asList(s);
l.remove("1");

Ces lignes de code Java semblent correctes. Pourtant, à l’exécution, elles vont lever l’exception suivante :

java.lang.UnsupportedOperationException
java.util.AbstractList.remove(Unknown Source)
java.util.AbstractList$Itr.remove(Unknown Source)
java.util.AbstractCollection.remove(Unknown Source)

Mais pourquoi la classe List propose une méthode remove() qui n’est pas supportée ? Rappelons que List est une interface. En fait, la faute revient à la méthode Arrays.asList() qui retourne une liste liée à un tableau et donc non modifiable. Si vous voulez modifier une liste créée à partir de cette méthode, il faut utiliser le code suivant :

List<String> l = new ArrayList<String>(Arrays.asList(s));

La liste obtenue est modifiable. Vous pouvez y ajouter ou y enlever des éléments sans risquer une exception. ;-)

 

JAXB – ignorer les espaces inutiles dans les fichiers XML

19 August 2010 par SeB 2 commentaires »

JAXB permet de générer des classes Java à partir de XSD pour manipuler du XML plus facilement. En clair, il permet de générer un parseur et un générateur de flux XML en Java. Ce qui fait gagner énormément de temps en développement.

En revanche, par défaut, le parseur JAXB n’ignore pas les espaces inutiles (appelés whitespaces). Pas de panique, l’API JAXB permet de le faire assez simplement. Il faut seulement créer un filtre et l’appliquer lors de la lecture du flux XML.

Le code du filtre ressemble à ceci :

public class WhitespaceFilter implements EventFilter {
	public boolean accept(XMLEvent event) {
		return !(event.isCharacters() && ((Characters)event).isWhiteSpace());
	}
}

Ensuite, pour l’appliquer il suffit d’instancier votre parseur de cette façon :

	JAXBContext jc = JAXBContext.newInstance("mon.package");

	// instancie le parseur XML pour ignorer les espaces inutiles
	XMLInputFactory inputFactory = XMLInputFactory.newInstance();
	XMLEventReader eventReader = inputFactory.createXMLEventReader(new FileInputStream("/monrepertoire/monfichier.xml"));
	eventReader = inputFactory.createFilteredReader(eventReader, new WhitespaceFilter());

	// parse le fichier XML
	Unmarshaller u = jc.createUnmarshaller();
	grid = (PCCADGRID)u.unmarshal(eventReader);

Cet exemple supprimer les espaces inutiles entre les balises XML. En revanche, les espaces inutiles sont toujours présents dans les valeurs. Pour supprimer ces derniers, il faut mettre en place un adaptateur. Voici son code :

public class NormalizedStringAdapter extends XmlAdapter {
	public String marshal(String text) {
		return text.trim();
	}

	public String unmarshal(String v) throws Exception {
		return v.trim();
	}
}

Il y a trois méthodes pour l’appliquer. Soit lors de l’initialisation du parseur :

Unmarshaller u = jc.createUnmarshaller();
u.setAdapter(new NormalizedStringAdapter());

Soit avec une annotation sur les champs concernés :

@XmlElement(required=true)
@XmlJavaTypeAdapter(NormalizedStringAdapter.class)
String name;

Soit avec une annotation dans les classes package-info pour l’appliquer à tous les champs du type chaine de caractère :

@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(value=NormalizedStringAdapter.class,type=String.class)
package mon.package;

Une fois cet adaptateur mis en place, les données XML que vous chargerez ne seront plus polluées par des espaces, retours à la ligne, tabulations, etc…

Notez qu’il existe également un adapteur qui permet de compacter les espaces. Comme ci-dessus, il supprime les espaces en début et fin de chaine mais réduit les multiples occurrences d’espace à un seul espace. Si vous le cherchez, c’est : javax.xml.bind.annotation.adapters.CollapsedStringAdapter.

 

Au coeur du système Android – enregistrer les pièces jointes des MMS

23 March 2010 par SeB Pas de commentaire »

Continuons le tour du système Android avec un quatrième billet dans la série sur Au coeur du système Android.

Introduction

Aujourd’hui, nous allons nous pencher sur l’enregistrement des pièces jointes des MMS. Encore une fois, l’accès à ces fichiers n’est pas très documenté.

Solution

En partant du principe que nous savons lister les MMS et récupérer la liste des identifiants des pièces jointes pour un MMS, je vous propose le code à utiliser pour enregistrer ces fameuses pièces jointes (sur la carte mémoire par exemple).

try {
	//Récupère le flux de données de la pièce jointe à partir de son identifiant "partId"
	Uri partURI = Uri.parse("content://mms/part/" + partId);
	InputStream is = context.getContentResolver().openInputStream(partURI);
	//Génère le flux d'écriture de la pièce jointe
	OutputStream out = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/"+partId));
	byte[] buffer = new byte[512];
	int len = is.read(buffer);
	while (len >= 0) {
		out.write(buffer, 0, len);
		len = is.read(buffer);
	}
	out.close();
	is.close();
} catch (IOException e) {
	e.printStackTrace();
}

Il existe différentes façon de lister les SMS/MMS et donc de récupérer leur identifiant. Ceci est vrai également pour les pièces jointes d’un MMS. C’est pourquoi, je n’ai pas traité cette partie qui est suffisamment documentée dans la documentation officielle.

Conclusion

En résolvant ce problème, je me suis rendu-compte que les colonnes des fournisseurs de contenu dont le nom est “_data” sont des flux de données et doivent donc être récupérées de la même façon que les pièces jointes des MMS. Vous êtes donc paré pour affronter les méandres des fournisseurs de contenu et enregistrer tout un tas d’information comme les pièces jointes des MMS.

 

Au coeur du système Android – enregistrer une application dans un fichier APK

22 March 2010 par SeB 2 commentaires »

C’est au tour du troisième billet dans la série sur Au coeur du système Android.

Introduction

De très nombreuses personnes se demandent comment il est possible d’enregistrer une application installée sur un système Android dans un fichier au format APK.

Solution

Je vous propose un simple bout de code qui enregistre toutes les applications installées.

//Récupère la liste des applications installées
PackageManager appInfo = getPackageManager();
List<PackageInfo> list = appInfo.getInstalledPackages(PackageManager.GET_PROVIDERS);
for (PackageInfo pack : list) {
    if (pack.applicationInfo.publicSourceDir!=null) {
    	try {
 		//Construit le nom du fichier APK
 		String apkFileName = pack.applicationInfo.publicSourceDir.substring(pack.applicationInfo.publicSourceDir.lastIndexOf("/")+1);
 		InputStream in = new FileInputStream(new File (pack.applicationInfo.publicSourceDir));
 		//Enregistre le fichier APK sur la carte mémoire
 		OutputStream out = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/"+apkFileName));
 		int count = 0;
 		byte[] buf = new byte[512];
 		while ( (count = in.read(buf,0,512))!=-1) {
 			out.write(buf, 0, count);
 		}
 		out.close();
 		in.close();
 	} catch (FileNotFoundException e) {
 		e.printStackTrace();
 	} catch (IOException e) {
 		e.printStackTrace();
 	}
    }
}

Notez que seules les applications publiques peuvent être enregistrées sur la carte mémoire. En effet, Google propose moyennant finance de protéger une application publiée sur l’Android Market en la rendant privée. Ainsi, il n’est pas possible de l’enregistrer dans un fichier APK.

Conclusion

Ce genre de manipulation avec le système Android n’est pas très documentée. Beaucoup de développeurs se demandent comment le faire puisque certaines applications proposent de sauvegarder les applications installées au format APK sur la carte mémoire. Et bien maintenant vous saurez le faire ! ;-)

 

Au coeur du système Android – lister les applications installées

21 March 2010 par SeB 4 commentaires »

Voici le second billet dans la série sur Au coeur du système Android.

Introduction

Dès lors que l’on commence à écrire des applications système, il s’avère souvent utile de connaitre la liste des applications installées sur Android.

Solution

Je vous propose un simple bout de code qui trie et liste par nom toutes les applications installées.

//Récupère la liste des applications installées
PackageManager appInfo = getPackageManager();
List<ApplicationInfo> list = appInfo.getInstalledApplications(0);
//Trie les applications par leur nom d'affichage
Collections.sort(list, new ApplicationInfo.DisplayNameComparator(appInfo));

for (ApplicationInfo applicationInfo : list) {
  //Récupère le nom de l'application
  Log.i("ApplicationList", "application="+getPackageManager().getApplicationLabel(applicationInfo));
}

Rien de plus simple, non ? ;-)

Conclusion

Il existe plusieurs méthodes pour récupérer la liste des applications présentes sur le système Android. Cependant, toutes ces méthodes ne permettent pas d’afficher le nom des applications installées. Alors plutôt que de chercher dans la vaste API Android,vous avez maintenant un code simple pour lister des applications présentes sur votre téléphone Android.

 

Au coeur du système Android – créer une application cachée

20 March 2010 par SeB 2 commentaires »

Voici le premier billet dans la série sur Au coeur du système Android.

Introduction

Il y a quelques temps, je vous avais expliqué comment accéder à un menu caché dans Android. Cette astuce a sûrement donné des idées à certains d’entre vous. Et vous vous demandez donc : comment créer une application cachée dans Android ?

Solution

Partons du tutoriel officiel : Hello World. Il faut créer un récepteur d’écouter et traiter “les codes secrets” saisis sur le téléphone :

package com.example.helloandroid;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class HelloWorldReceiver extends BroadcastReceiver {
  private static String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";

  public void onReceive(Context context, Intent intent) {
    Log.i("HelloWorldReceiver", "intent.action="+intent.getAction());
    if (intent.getAction().equals(SECRET_CODE_ACTION)) {
      Intent i = new Intent(Intent.ACTION_MAIN);
      i.setClass(context, HelloWorld.class);
      i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      context.startActivity(i);
    }
  }
}

Vous pouvez voir que c’est le récepteur qui se charge de lancer l’application HelloWorld.

Ensuite, il faut modifier le fichier AndroidManifest.xml pour cacher l’application HelloWorld et paramétrer le code qui permet de lancer l’application :

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.helloandroid"
      android:versionCode="1"
      android:versionName="1.0 (secret)">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".HelloWorld"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <!-- category android:name="android.intent.category.LAUNCHER" /-->
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <receiver android:name=".HelloWorldReceiver">
            <intent-filter>
                 <action android:name="android.provider.Telephony.SECRET_CODE" />
                 <data android:scheme="android_secret_code" android:host="1337" />
            </intent-filter>
       </receiver>
    </application>
    <uses-sdk android:minSdkVersion="3" />
</manifest>

L’application HelloWorld ne fait alors plus partie de la catégorie “launcher” mais “default”. Cela a pour conséquence qu’elle n’est plus visible dans la liste des applications du lanceur d’application.

Pour lancer l’application, il suffi d’ouvrir l’application de téléphonie et de composer le numéro suivant : *#*#1337#*#*. L’application HelloWorld se lance alors.

Conclusion

Vous êtes maintenant armé pour créer des applications invisibles. Il suffira juste d’indiquer à vos utilisateurs le code à saisir pour démarrer cette dernière. ;-)

 

Au coeur du système Android

19 March 2010 par SeB Pas de commentaire »

J’avais précédemment lancé coup sur coup deux séries d’articles intitulées Les bonnes pratiques avec Struts et Les bonnes pratiques avec Struts 2. A force de développer sur l’environnement Android, j’ai pensé à écrire une série du même type pour Android. Cependant, je ne suis pas encore convaincu de connaitre les bonnes pratiques. :-) Alors je vais l’appeler “A coeur du système Android”. Au final, cela revient au même puisque je vais partager avec vous des astuces et j’espère les bonnes pratiques que je peux utiliser lorsque je travaille sur Android.

L’objectif est double :

  • réaliser un aide mémoire sur l’utilisation d’Android
  • partager et confronter les expériences de chacun sur cette plateforme mobile

Liste des billets :

En attendant, prenez soin de vos petits androids ! ;-)