0

Я пытаюсь реализовать MovementDetector на своей мягкой клавиатуре, но я получаю эта ошибка. Когда я компилирую свой код, все работает, но когда я начинаю использовать свою клавиатуру, он показывает ошибку в logcat. Вот мой код:ОШИБКА: попытка вызвать виртуальный метод 'java.lang.Object android.content.Context.getSystemService (java.lang.String)' на ссылке нулевого объекта

public class MovementDetector implements SensorEventListener { 

protected final String TAG = getClass().getSimpleName(); 
private Sensor accelerometer; 
private SensorManager mSensorMgr; 
public static Context mContext; 
float [] history = new float[2]; 
public static String [] direction = {"NONE","NONE"}; 

private MovementDetector(Context context) { 
    mContext = context; 
} 

private static MovementDetector mInstance; 

public static MovementDetector getInstance() { 
    if (mInstance == null) { 
     mInstance = new MovementDetector(mContext); 
     mInstance.init(); 
    } 
    return mInstance; 
} 

private HashSet<Listener> mListeners = new HashSet<MovementDetector.Listener>(); 

private void init() { 
    mSensorMgr = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); 
    accelerometer = mSensorMgr.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION); 
} 

public void start() { 
    mSensorMgr.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL); 
} 

public void stop() { 
    mSensorMgr.unregisterListener(this); 
} 

public void addListener(Listener listener) { 
    mListeners.add(listener); 
} 

@Override 
public void onSensorChanged(SensorEvent event) { 
    if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) { 

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

     float xChange = history[0] - event.values[0]; 
     float yChange = history[1] - event.values[1]; 

     history[0] = event.values[0]; 
     history[1] = event.values[1]; 

     float diff = (float) Math.sqrt(x * x + y * y + z * z); 
     if (diff > 0.5) 
      if (xChange > 2){ 
       direction[0] = "LEFT"; 
      }else if (xChange < -2){ 
       direction[0] = "RIGHT"; 
      } 

      if (yChange > 2){ 
       direction[1] = "DOWN"; 
      }else if (yChange < -2){ 
       direction[1] = "UP"; 
      } 

     for (Listener listener : mListeners) { 
      listener.onMotionDetected(event, diff); 
     } 
    } 
} 

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

} 

public interface Listener { 
    void onMotionDetected(SensorEvent event, float acceleration); 
} 

}

Я получаю ошибку в этой строке:

mSensorMgr = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE); 

я начинаю MovementDetector в OnCreateInputView() и остановить его в OnDestory(), но это не проблема. Проблема заключается в классе MovementDetector. Может кто-нибудь, пожалуйста, скажите мне, что я должен делать и что я сделал неправильно? Заранее спасибо. На самом деле нужно, чтобы этот MovementDetector работал.

+0

Ваш '' mContext переменная равна нулю. Его не передают должным образом в конструкторе. Поместите точку останова в конструкторе и посмотрите, получаете ли вы там значение. – Antrromet

+0

Извините, я новичок в разработке Android, и я не много узнал о Context и Instance. Вот что я пробовал, но это не сработало: 'private MovementDetector (контекст контекста) { if (context! = Null) { mContext = context; } } ' – jelic98

+0

Это нормально. Но убедитесь, что вы правильно передаете «context» конструктору. Проверьте место, где вы инициализируете «MovementDetector». – Antrromet

ответ

1

Хорошо, поэтому, основываясь на ваших вложениях выше в комментариях, я смог идентифицировать проблему. Кажется, что класс MovementDetector использует шаблон одноэлементного дизайна.

Чтобы получить экземпляр MovementDetector вы используете следующий код

MovementDetector.getInstance() 

и метод getInstance() в MovementDetector определяется как

public static MovementDetector getInstance() { 
    if (mInstance == null) { 
     mInstance = new MovementDetector(mContext); 
     mInstance.init(); 
    } 
    return mInstance; 
} 

Теперь, когда этот код (getInstance()) называется для в первый раз mInstance имеет значение null, поэтому он создает экземпляр.

mInstance = new MovementDetector(mContext); 

Но проблема в том, что выше mContext равна нулю, и именно поэтому вы получаете ошибку! Чтобы решить вашу проблему, вы должны передать context методу getInstance(). Это должно выглядеть примерно так.

public static MovementDetector getInstance(Context context) { 
     if (mInstance == null) { 
      mInstance = new MovementDetector(context); 
      mInstance.init(); 
     } 
     return mInstance; 
    } 

И где бы вы вызываете этот метод getInstance() он должен изменить что-то вроде

MovementDetector.getInstance(context).start(); 
+1

Большое вам спасибо. Это работает :) – jelic98

+1

Рад, что я смог Помогите! Счастливое кодирование :) – Antrromet