2012-06-08 3 views
1

Итак, у меня есть код, ниже которого я не могу работать. Я пытаюсь, чтобы один класс (AccelerometerReader) прочитал значения акселерометра моего телефона, а затем я вызываю эти значения в другом классе (MyGame), который я использую для печати этих значений на экране. Все в коде кажется прекрасным, и я не получаю никаких значений, кроме значений, которые я печатаю всего, просто говорю 0.0 и не меняю. Я знаю, что в моем телефоне есть акселерометр. Любая помощь будет оценена!Акселерометр не меняет значения

Спасибо, Оуэн

AccelerometerReader Класс

import android.app.Activity; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.os.Bundle; 

public class AccelerometerReader extends Activity implements SensorEventListener{ 
private SensorManager sensorManager; 
float ax,ay,az; // these are the acceleration in x, y and z axes 

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE); 
     sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
    } 

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

    @Override 
    public void onSensorChanged(SensorEvent event) { 
     if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER) 
      return; 

     if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){ 
      ax=event.values[0]; 
      ay=event.values[1]; 
      az=event.values[2]; 
     } 
    } 


public float getValueX() { 
    return ax; 
} 

public float getValueY() { 
    return ay; 
} 

public float getValueZ() { 
    return az; 
} 
} 

Внутри MyGame класса

@Override 
protected void onDraw(Canvas canvas) { 
    // TODO Auto-generated method stub 
    super.onDraw(canvas); 
    leftWall = new Rect(-100,0,0,canvas.getHeight()); 
    rightWall = new Rect(canvas.getWidth(), 0, (canvas.getWidth() + 100), canvas.getHeight()); 
    floor = new Rect(0,canvas.getHeight(),canvas.getWidth(),(canvas.getHeight() + 100)); 
    ceiling = new Rect(0,-100,canvas.getWidth(),0); 

    AccelerometerReader acc = new AccelerometerReader(); 
    float ax = acc.getValueX(); 
    float ay = acc.getValueY(); 
    float az = acc.getValueZ();  

    canvas.drawColor(Color.rgb(red,green,blue)); //0 or 51?, 51, 102 

    Rect player = new Rect(xPos,yPos,xPos+100,yPos+100); 
    Paint myPaint = new Paint(); 
    myPaint.setColor(Color.rgb(0, 102, 255)); 
    canvas.drawRect(player, myPaint); 
    myPaint.setColor(Color.rgb(0, 0, 0)); 
    canvas.drawRect(xPos + 5, yPos + 5, xPos + 95, yPos +95, myPaint); 
    myPaint.setColor(Color.WHITE); 
    myPaint.setTextSize(20); 
    canvas.drawText("" + Math.round(ySpeed), 75, 50, myPaint); 
    canvas.drawText(ax +", "+ ay +", "+ az, 300, 50, myPaint); 
    if(gameStarted == false) { 
     myPaint.setTextSize(30); 
     myPaint.setTextAlign(Align.CENTER); 
     canvas.drawText("Touch screen to begin!", canvas.getWidth()/2, canvas.getHeight()/2, myPaint); 
    } 
    int r = Math.round(rand.nextInt(canvas.getHeight() - 150)); 
    if(needsRand == true) { 
     blockY = r; 
     myPaint.setColor(Color.rgb(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255))); 
    } 


    //if(isAlive == true) { 
     Rect block = new Rect(blockX,blockY,(blockX+100),(blockY+100)); // left, top, right, bottom 
     myPaint.setColor(Color.WHITE); 
     canvas.drawRect(block, myPaint); 
     blockX--; 
    //} 


    if(player.intersect(leftWall)) { 
     xSpeed = Math.abs(xSpeed); 
    } else if(player.intersect(rightWall)) { 
     xSpeed = -(xSpeed); 
    } else if(player.intersect(floor)) { 
     yPos = canvas.getHeight() - 150; 
     ySpeed = -(ySpeed)*.75; 
    } else if(player.intersect(ceiling)) { 
     ySpeed = Math.abs(ySpeed); 
    } else if(player.intersect(block)) { 
     ySpeed = 0; 
    } 
    if(blockX <= -100) { 
     blockX = canvas.getWidth() + 100; 
     needsRand = true; 
    } else { 
     needsRand = false; 
    } 

    canvas.drawText("" + r, 300, 100, myPaint); 

    physics(); 
    invalidate(); 
} 

ответ

0

MyService.java

public class MyService extends Service implements SensorEventListener { 
     public void onCreate() { 
       super.onCreate(); 
       sm = (SensorManager) getSystemService(SENSOR_SERVICE); 
       sm.unregisterListener(this); 
       sm.registerListener(this,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_FASTEST); 
     } 
     public void onDestroy() { 
       super.onDestroy(); 
       sm.unregisterListener(this); 
     } 

// Creates a new binder 
@Override 
public IBinder onBind(Intent intent) { 
     return new MyBinder<MyService>(this); 
} 

public void onSensorChanged(SensorEvent event) { 
     ax=event.values[0];       
     ay=event.values[1];       
     az=event.values[2];     
     for (Listener listener : listeners) listener.handleNewAccelValue(this); 
} 

public interface Listener { 
     // Actions to take when a new position has been added to the model 
     void handleNewAccelValue(MyService sender); 
} 

// List of all the ongoing listeners bound to the Model 
private List<Listener> listeners = new ArrayList<Listener>(); 

// Binds a listener from the View to the Model 
public void addListener(Listener listener) { 
     this.listeners.add(listener); 
} 

// Removes a listener from the View to the Model 
public void removeListener(Listener listener) { 
     this.listeners.remove(listener); 
} 

YourActivity.java

public class YourActivity implements MyService.Listener{ 
public void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     // Binds to the created service 
     doBindService(); 
} 

// Creating the controller and the model 
private ServiceComputeFinal controller; 

// Creates the connection with a MyService service 
ServiceConnection connection = new ServiceConnection(){ 
    public void onServiceConnected(ComponentName name, IBinder binder) { 
     controller = ((MyBinder<MyService>) binder).getService();   
    } 

    public void onServiceDisconnected(ComponentName name) { 
     controller = null; 
    } 
}; 

// Binds to the created service 
void doBindService(){ 
    bindService(new Intent(this, MyService.class), connection, Context.BIND_AUTO_CREATE); 
} 

// And finally recover the accelerometer data that interest you 
public void handleNewAccelValue(MyService sender){ 
    DO_WHATEVER_YOU_WANT_WITH(controller.getAx()); 
} 

Я дал вам все инструменты, чтобы сделать то, что вы хотите. Попробуйте просмотреть этот код и понять, что он делает (это не очень сложно), ServiceConnection позволяет Activity для восстановления значений из интерфейса Service и Listener позволяет Службе уведомлять Activity, когда новые значения готовы. Не стесняйтесь спрашивать что-либо, если это необходимо.

+0

Извините, что вернусь с полной ответной рукой, я получаю некоторые ошибки. Во-первых, int YourActivity выше, я получаю сообщение об ошибке: «ServiceComputeFinal не может быть разрешен к типу» вместе с MyBinder в MyService.java. Мне также интересно, как использовать их в моем классе MyGame, так как это не действительно активность.Однако я открываю его с помощью другого действия, называемого MyGameActivity, это где я должен привязать службу? Извините за продолжение вопросов, но я довольно новичок во всем этом, и я еще не работал с услугами. И спасибо за вышеуказанный код! – Owen2014

+0

ServiceComputeFinal -> MyService. Забыл явно изменить это имя. Что касается Activity: если он привязан к Сервису и имеет экземпляр класса MyGame, вы можете использовать, чтобы выталкивать данные акселерометра в ваш класс. Как говорится в API Google, «Примечание. Только действия, службы и поставщики контента могут привязываться к сервису». Подводя итог: MyService <-> MyActivity <-> MyGame – PeterGriffin

+0

Как все прошло? – PeterGriffin

0

метод вы используете выглядит очень странно для меня. Фактически вы набираете значения акселерометра в своем классе рисования. Это похоже на то, что вы создаете экземпляр класса акселерометра, а затем сразу отбираете его значения (не дожидаясь реального акселерометра, чтобы фактически получить значения), затем попытайтесь его нарисовать. В любом случае, это, вероятно, ваша проблема, вы рисуете начальные значения акселерометра и не обновляете их при их изменении. Я не знаю, что представляет собой остальная часть вашего кода, но если вы вызываете onDraw несколько раз, вы просто создаете новый экземпляр вашего класса, и снова значения, которые вы вытаскиваете из него, не успели изменить датчик чтения.

Вам лучше использовать метод push, реализующий интерфейс слушателя в классе акселерометра, поэтому всякий раз, когда извлекается новое значение ускорения, класс чертежа уведомляется и получает новые значения, а затем рисует их.

Редактировать: Я настоятельно рекомендую вам использовать более быструю задержку для вашего акселерометра (самое быстрое это сделает). Имейте в виду, что ускоритель менее энергоемкий из всех.

+0

Извините, что спросить еще раз, но я попробовал несколько разных вещей, чтобы прийти к выводу, что вы правы. Значения акселерометра не обновляются до того, как они будут отправлены другому классу. Сейчас проблема заключается в том, что я не могу понять, как отправлять их при обновлении. Я также избавился от своих трех методов (getValueX, getValueY и getValueZ) и просто использовал AccelerationReader.ax. Больше помощи было бы здорово! Плюс, я вроде как новый, поэтому, если бы вы могли опубликовать несколько примеров кода, я был бы здорово! Извините, я не пытаюсь звучать так, как будто я просто просил весь код, просто небольшие части. – Owen2014

+0

. Дело в том, что, поскольку вы хотите, чтобы значения акселерометра извлекались без перерыва, вы хотите, чтобы это не блокировало ваши действия. Я предлагаю вам использовать Службу, которая будет работать в фоновом режиме и обновлять значения. Я дам вам подходящий код. – PeterGriffin

Смежные вопросы