Cet article a été publié il y a 2 ans 7 mois 30 jours, il est donc possible qu’il ne soit plus à jour. Les informations proposées sont donc peut-être expirées.Dans ce tutoriel je vais expliquer comment utiliser l’accéléromètre avec Android donut 1.6
Pour commencer il faut déjà installer eclipse et le sdk 1.6 Android.
Une fois fait on peut donc créer notre application Android qui utilise l’accéléromètre.
Pour notre exemple j’ai pensé que reprendre le principe d’un application Iphone existante serait parfait.
Cette application est isebastien et elle à le mérite de convenir parfaitement à un exemple d’utilisation de l’accéléromètre.
Nous pouvons donc créer notre application, appelons la DroidSeb qui doit être capable de jouer un morceau de musique uniquement lorsque le téléphone bouge.
Voici ensuite le xml de l’interface de l’application (/res/layout/main.xml)
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 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/widget30" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" > <TextView android:id="@+id/widget32" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:text="JgeekBlog utilisation de l'acelerometre"> </TextView> <Gallery android:id="@+id/Gallery01" android:layout_height="380px" android:scrollbarAlwaysDrawHorizontalTrack="true" android:animationDuration="20" android:layout_width="wrap_content" android:clickable="false" android:fitsSystemWindows="true" android:gravity="center"> </Gallery> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/progress" android:text="Volume :" android:layout_marginRight="5px" android:layout_marginLeft="5px"> </TextView> <SeekBar android:id="@+id/SeekBar01" android:fitsSystemWindows="true" android:scrollbarAlwaysDrawHorizontalTrack="true" android:minWidth="320px" android:layout_height="wrap_content" android:layout_marginRight="30px" android:layout_width="wrap_content"> </SeekBar> </LinearLayout> </LinearLayout> |
Qui nous donne ceci dans le constructeur d’interface,
La source du fichier AndroidManifest.xml qui définit l’application et ses droits.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.jgeek.DroidSeb" android:versionName="0.1" android:versionCode="0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name="DroidSeb" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="3" /> </manifest> |
Dans /res/drawable il nous faut 3 images pour la galerie, seb1.jpg, seb2.jpg, seb3.jpg et le fichier icône de l’application icon.png.
Nous avons également besoin d’un fichier son par image sélectionné, geulle.mp3, mousse.mp3, tourner.mp3 dans /res/raw/.
Maintenant nous pouvons passer au code Java de l’application.
En plus de la classe principale de ce programme (DroidSeb.java) nous avons besoin de deux autres classes, une pour contrôler le volume via la seekbar :
fichier VolumeDialog.java
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 | package org.jgeek.DroidSeb; import android.app.Activity; import android.content.Context; import android.media.AudioManager; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; public class VolumeDialog implements OnSeekBarChangeListener { protected VolumeDialog(Activity parent) { final AudioManager audio = (AudioManager) parent.getSystemService(Context.AUDIO_SERVICE); final SeekBar systemSeek = (SeekBar) parent.findViewById(R.id.SeekBar01); systemSeek.setMax(audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC)); systemSeek.setProgress(audio.getStreamVolume(AudioManager.STREAM_MUSIC)); systemSeek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { //ingnorer } public void onStartTrackingTouch(SeekBar seekBar) { //ingnorer } public void onStopTrackingTouch(SeekBar seekBar) { final int setVolFlags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE | AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE; audio.setStreamVolume(AudioManager.STREAM_MUSIC, seekBar.getProgress(), setVolFlags); //Réglage du volume à l'aide de la seekbar } }); } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // TODO Auto-generated method stub } public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } } |
L’autre classe qui sert elle à détecter si le téléphone est en mouvement ou non,
c’est la classe principale de notre exemple elle est capable detecter que le mobile est en action en fonction d’un seuil de force prédéfini, voici son code :
AccelerometerListener.java :
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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | package org.jgeek.DroidSeb; import java.util.List; import android.app.Activity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; public class AccelerometerListener implements SensorEventListener { public float currenForce; private SensorManager sensorManager; private List<Sensor> sensors; private Sensor sensor; private long lastUpdate = -1; private long currentTime = -1; private float last_x, last_y, last_z; private float current_x, current_y, current_z; private static final int FORCE_THRESHOLD = 1300; private final int DATA_X = SensorManager.DATA_X; private final int DATA_Y = SensorManager.DATA_Y; private final int DATA_Z = SensorManager.DATA_Z; public AccelerometerListener(Activity parent) { SensorManager sensorService = (SensorManager) parent.getSystemService(Context.SENSOR_SERVICE); this.sensorManager = sensorService; this.sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); if (sensors.size() > 0) { sensor = sensors.get(0); } } public void start () { if (sensor!=null) { sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_GAME); } } public void stop () { sensorManager.unregisterListener(this); } public void onAccuracyChanged(Sensor s, int valu) { } public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER || event.values.length < 3) return; currentTime = System.currentTimeMillis(); if ((currentTime - lastUpdate) > 100) { long diffTime = (currentTime - lastUpdate); lastUpdate = currentTime; current_x = event.values[DATA_X]; current_y = event.values[DATA_Y]; current_z = event.values[DATA_Z]; currenForce = Math.abs(current_x+current_y+current_z - last_x - last_y - last_z) / diffTime * 10000; if (currenForce < 800) { if ( DroidSeb.mp.isPlaying()) { DroidSeb.mp.pause(); } } if (currenForce > FORCE_THRESHOLD) { // Le téléphone à été secoué donc si le mp3 ne // joue pas, le démarrer ... Log.d("JgeekLog","FORCE > FORCE_THRESHOLD, force = " + currenForce); if ( DroidSeb.mp.isPlaying() != true) { DroidSeb.mp.start(); } } last_x = current_x; last_y = current_y; last_z = current_z; } } } |
Enfin pour terminer on met en place le point d’entrée de l’application dans le fichier DroidSeb.java, ici on construit la galerie avec les 3 images et on lance l’écoute sur l’accéléromètre.
Voici le code :
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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | package org.jgeek.DroidSeb; import java.io.IOException; import android.app.Activity; import android.content.Context; import android.content.res.TypedArray; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Gallery; import android.widget.ImageView; import android.widget.AdapterView.OnItemSelectedListener; public class DroidSeb extends Activity { public static MediaPlayer mp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); mp = MediaPlayer.create(this , R.raw.tourner); mp.setOnCompletionListener(new OnCompletionListener() { public void onCompletion(MediaPlayer mp) { // Quand fin mp3 preparer et relancer try { mp.prepare(); mp.start(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }); setContentView(R.layout.main); Gallery g = (Gallery) findViewById(R.id.Gallery01); g.setAdapter(new ImageAdapter(this)); g.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View v, int position, long id) { // Action quand un item de la galerie est séléctionné switch (position) { case 0: mp = MediaPlayer.create(DroidSeb.this , R.raw.tourner); break; case 1: mp = MediaPlayer.create(DroidSeb.this , R.raw.mousse); break; case 2: mp = MediaPlayer.create(DroidSeb.this , R.raw.geulle); break; default: break; } } public void onNothingSelected(AdapterView<?> arg0) { // ingnorer } }); Debut(); } private void Debut() { @SuppressWarnings("unused") VolumeDialog vdiag = new VolumeDialog(this); //On lance l'écoute à l'aide de la classe AccelerometerListener AccelerometerListener acl = new AccelerometerListener(this); acl.start(); } @Override protected void onStop() { super.onStop(); } public class ImageAdapter extends BaseAdapter { int mGalleryItemBackground; public ImageAdapter(Context c) { mContext = c; TypedArray a = obtainStyledAttributes(R.styleable.Gallery1); mGalleryItemBackground = a.getResourceId( R.styleable.Gallery1_android_galleryItemBackground, 0); a.recycle(); } public int getCount() { return mImageIds.length; } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } private Context mContext; public View getView(int position, View convertView, ViewGroup parent) { ImageView i = new ImageView(mContext); i.setImageResource(mImageIds[position]); i.setBackgroundResource(mGalleryItemBackground); return i; } private Integer[] mImageIds = { R.drawable.seb, R.drawable.seb2, R.drawable.seb3, }; } } |
Quand on compile l’application voici ce à quoi elle ressemble (galerie avec 3 images),
Pour installer l’application vous pouvez utiliser l’apk ci-dessous à l’aide de cette commande :
adb install DroidSeb.apk|
|
télécharger: DroidSeb (B) ajouté: 11/10/2009 clics: 752 description: DroidSeb est un clone de iSebastien pour smartphone Android |




17/02/2010 at 20 h 34 min Permalink
euh le lien est mort pour prendre l’application en bas
18/02/2010 at 18 h 13 min Permalink
c bon le lien marche nikel sur mon galaxy spica
19/02/2010 at 2 h 08 min Permalink
Bonsoir Julien,
Merci pour l’info, j’ai quand même un soucis avec le plugin wordpress download manager qui « bloque » dans certain cas depuis la récente mise à jour du blog.
Je vais voir de plus prêt dès que possible.
Ton message aura aussi eu le mérite de me faire connaitre le terminal spica dont je ne connaissais pas l’existence (je connais que son grand frère le galaxy).
19/02/2010 at 2 h 28 min Permalink
Problème définitivement résolu.
J’avais un téléchargement qui pointait sur une adresse inexistante ce qui générait d’énormes lenteurs.