2016-07-01 1 views
1

Je suis en train de développer un lecteur de musique Android qui effectuera les actions suivantes une fois qu'une action de secousse est détectée. Actions: 1. Ne rien faire 2. Jouer ou mettre en pause 3. Chanson suivante 4. Chanson précédenteLe codage d'accéléromètre ne fonctionne pas dans tous les téléphones

J'ai créé une classe de service pour l'action de secousse et c'est comme suit.

public class Shaker extends Service implements SensorEventListener { 

    SharedPreferences sharedPreferences; 
    private static final int MIN_TIME_BETWEEN_SHAKES_MILLISECS = 1000; 
    private long mLastShakeTime; 
    private SensorManager sensorManager; 
    private static final String SHAKE_ACTION_PREFERENCE = "shake_action_preference"; 
    private static final String SHAKE_THRESHOLD_PREFERENCE = "shake_threshold_preference"; 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    public void onCreate() { 

     sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 
     super.onCreate(); 
    } 

    public void onDestroy() { 
     super.onDestroy(); 
     sensorManager.unregisterListener(this); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
     sensorManager.registerListener(this, sensorManager 
      .getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); 

     return START_STICKY; 
    } 

    public void onStart(Intent intent, int startId) { 
     sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 
     sensorManager.registerListener(this, sensorManager 
      .getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 

    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 

     if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
      long curTime = System.currentTimeMillis(); 
      if ((curTime - mLastShakeTime) > MIN_TIME_BETWEEN_SHAKES_MILLISECS) { 

       float x = event.values[0]; 
       float y = event.values[1]; 
       float z = event.values[2]; 

       double acceleration = Math.sqrt(Math.pow(x, 2) + 
        Math.pow(y, 2) + 
        Math.pow(z, 2)) - SensorManager.GRAVITY_EARTH; 
      Log.d("Acceleration", "Acceleration is " + acceleration + "m/s^2"); 

       String threshold = sharedPreferences.getString(SHAKE_THRESHOLD_PREFERENCE, "medium"); 

       float SHAKE_THRESHOLD; 
       if(threshold.equals("high")) 
        SHAKE_THRESHOLD = 40.5f; 
       else if(threshold.equals("low")) 
        SHAKE_THRESHOLD = 15.5f; 
       else 
        SHAKE_THRESHOLD = 25.5f; 
       if (acceleration > SHAKE_THRESHOLD) { 
        mLastShakeTime = curTime; 
        Log.d("Shake", "Shake, Rattle, and Roll"); 

        String opt = sharedPreferences.getString(SHAKE_ACTION_PREFERENCE, "nothing"); 
        Log.d("SharedPreference", opt); 
        Log.d("SharedPreference", threshold); 
        if(opt.equals("play")) { 
         MusicPlayer.playOrPause(); 
        } else if(opt.equals("next")) { 
         MusicPlayer.next(); 
        } else if(opt.equals("prev")) { 
         MusicPlayer.previous(getApplicationContext(), false); 
        } 
       } 
      } 
     } 
    } 
} 

Mais quand je lance les fichiers apk dans les dispositifs réels, la fonction secousse ne fonctionne que sur certains téléphones et ne fonctionne pas pour tous les mobiles.

J'ai essayé sur différents mobiles en utilisant le même système d'exploitation Android, mais il fonctionne dans un et ne fonctionne pas dans l'autre.

Je ne pouvais pas comprendre pourquoi c'est comme ça. Quelqu'un peut-il suggérer une solution pour cela?

+0

Merci de nous avoir dit. Quelle est la question? – Henry

+0

Désolé de ne pas inclure ma question avant. – Frontier2016

+0

Ce qui ne fonctionne pas? N'avez-vous pas de données accélérométriques? L'obtenez-vous, mais ce n'est pas aussi élevé que prévu? Est-il plus lent que prévu? Autre chose? Nous avons besoin de plus de détails. –

Répondre

0

J'ai eu ce problème. La méthode onSensorChanged est appelée pour tous les changements mais dans certains appareils, elle est appelée plus d'une fois. Cela provoque des problèmes dans la logique du code. J'ai résolu ce problème en ajoutant une variable booléenne statique privée. (Elle provoque cette méthode appelée une fois). Une fois cette méthode exécutée, cette variable devient true.

@Override 
    public void onSensorChanged(SensorEvent event) { 
     if(!variable) { 
      variable=true; 
      ... 
      ... 
      variable=false; 
      } 
     } 
+0

J'ai ajouté une variable booléenne statique privée au codage mmy. Cela ne fonctionne toujours pas – Frontier2016

+0

Définissez-vous une variable false à la fin? J'ai mis à jour mon code –

+0

Shokouhix merci pour votre soutien continu, Non je n'ai pas mis la variable false à la fin. Je le ferai ce soir et je vous ferai part de vos commentaires. Mon mobile est Android 5.1 et mon mobile d'amis est également le même OS. Mais le code fonctionne dans son mobile et ne fonctionne pas dans mon mobile. – Frontier2016