2016-07-01 10 views
1

Я занимаюсь разработкой музыкального плеера Android, который будет выполнять следующие действия после обнаружения дрожания. Действия: 1. Ничего не делать 2. Воспроизвести или приостановить 3. Следующая песня 4. Предыдущая композицияКодирование акселерометра не работает во всех телефонах

Я создал класс обслуживания для действия тряски, и это выглядит следующим образом.

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); 
        } 
       } 
      } 
     } 
    } 
} 

Но когда я запускать APK файлы в реальных устройствах, функция встряхивания работает только на некоторых телефонах и не работает на всех мобильных телефонах.

Я пробовал на разных мобильных телефонах с использованием той же ОС Android, но работает в одном и не работает в другом.

Я не мог понять, почему это так. Может ли кто-нибудь предложить решение для этого?

+0

Спасибо, что сообщили нам. Что за вопрос? – Henry

+0

Извините, что не рассматривал мой вопрос раньше. – Frontier2016

+0

Что не работает? Вы не получаете данные акселерометра? Вы получаете его, но это не так высоко, как вы ожидаете? Это идет медленнее, чем вы ожидаете? Что-то другое? Нам нужно больше деталей. –

ответ

0

У меня была эта проблема. onSensorChanged метод вызывается для любых изменений, но в некоторых устройствах он вызывается более одного раза. Это вызывает проблему в логике кода. Я решил эту проблему, добавив частную статическую логическую переменную. (Этот метод вызывает один раз). Когда этот метод выполняется, эта переменная становится истинной.

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

Я добавил частную статическую логическую переменную в mmy-кодировании. Все еще не работает – Frontier2016

+0

Установили ли вы переменную false в конце? Я обновил свой код –

+0

Shokouhix Спасибо за вашу постоянную поддержку, нет. Я не установил переменную false в конце. Я сделаю это сегодня вечером и дам вам знать отзывы. Мой мобильный телефон - Android 5.1, а мои мобильные телефоны - это тоже ОС. Но код работает на своем мобильном устройстве и не работает на моем мобильном телефоне. – Frontier2016