2012-06-08 75 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從服務中恢復值,而Listener接口允許服務在新值準備好時通知Activity。如有需要,隨時提出問題。

+0

對不起,回覆一堆答案,我收到一些錯誤。首先,在上面的YourActivity中,我收到錯誤,「ServiceComputeFinal無法解析爲類型」,以及MyService.java中的MyBinder。我也想知道如何在我的MyGame類中使用它們,因爲它不是一個真正的活動。但是,我打開它使用另一個名爲MyGameActivity的活動,這是我應該綁定該服務?對於持續的問題感到抱歉,但我對所有這些東西都很陌生,而且我還沒有使用過服務。並感謝上面的代碼! – Owen2014

+0

ServiceComputeFinal - > MyService。顯然忘了改變這個名字。至於活動:如果它綁定到服務並且有一個MyGame類的實例,則可以使用is將加速計數據推送到您的類。正如谷歌API所說,「注意:只有活動,服務和內容提供者才能綁定到服務」。總結:MyService <-> MyActivity <-> MyGame – PeterGriffin

+0

它是怎麼回事? – PeterGriffin

0

您使用的方法看起來真的很奇怪,我。實際上,您在繪圖類中拉動加速度計值。就像你創建了一個加速度計類的實例,然後立即拿走他的值(不用等待真正的加速度計實際檢索值),然後嘗試繪製它。無論如何,這可能是您的問題,您可以繪製起始加速度計值並在更改時不刷新它們。我不知道代碼的其餘部分是什麼,但是如果您多次調用onDraw,則只需創建一個新類的實例,並且再次從中取出的值沒有時間由傳感器更改讀數。

您最好使用push方法,在加速度計類中實現偵聽器接口,以便每當檢索到新的加速度值時,都會通知繪圖類並獲取新值,然後繪製它們。

編輯:我強烈建議你爲你的加速度計使用更快的延遲(最快的時候會這樣做)。請記住,加速器的耗電量較低。

+0

對不起,再次提問,但我已經嘗試了許多不同的事情,只是爲了得出你說得對的結論。來自加速度計的值在發送到其他課程之前不會更新。現在的問題是,我無法弄清楚如何在更新時發送它們。我也擺脫了我的三種方法(getValueX,getValueY和getValueZ),並使用AccelerationReader.ax。再幫助會很棒!另外,我有點新,所以如果你可以發佈一些代碼示例,我會很棒!對不起,我不試圖聽起來像我只是要求整個代碼,只是小部分 – Owen2014

+0

事情是,因爲你想加速度計值被檢索沒有中斷,你會希望它不會阻止你的活動。我建議你使用一個將在後臺運行並更新值的服務。我會給你一個合適的代碼。 – PeterGriffin