Utiliser l’accéléromètre avec Android Donut

closeCet 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.

création de l'application

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,

main 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),

droidseb

droidseb

Pour installer l’application vous pouvez utiliser l’apk ci-dessous à l’aide de cette commande :

adb install DroidSeb.apk

http://www.bordel-de-nerd.net/wp-content/plugins/downloads-manager/img/icons/default.gif télécharger: DroidSeb (B)
ajouté: 11/10/2009
clics: 752
description: DroidSeb est un clone de iSebastien pour smartphone Android

Trackback URL

, , ,

4 Comments on "Utiliser l’accéléromètre avec Android Donut"

  1. julien
    17/02/2010 at 20 h 34 min Permalink

    euh le lien est mort pour prendre l’application en bas

  2. julien
    18/02/2010 at 18 h 13 min Permalink

    c bon le lien marche nikel sur mon galaxy spica

  3. Jérôme
    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).

  4. Jérôme
    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.

Hi Stranger, leave a comment:

ALLOWED XHTML TAGS:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">

Subscribe to Comments
Get Adobe Flash playerPlugin by wpburn.com wordpress themes