2011-08-12 10 views
12

Tôi đã vật lộn với việc định hướng thực tế thiết bị của mình bằng cách sử dụng getOrientation. Lấy các chỉ số gia tốc và từ trường thông qua TYPE_ACCELEROMETER và TYPE_MAGNETIC_FIELD là đơn giản như đang định hướng qua TYPE_ORIENTATION. Nhưng nhận định hướng theo hệ tọa độ thế giới sử dụng getOrientation. Có một số hướng dẫn tốt ngoài đó herehere nhưng tôi chưa đặt tất cả lại với nhau. Để đạt được mục tiêu đó, tôi đã phát triển một ứng dụng đơn giản nhổ ra Accelerometer, Magnetic Field, dữ liệu Định hướng thô và dữ liệu Định hướng từ getOrientation. Tôi đã đính kèm mã nhưng nó liên tục thất bại trên điện thoại của tôi. Bất kỳ đề xuất?getRotationMatrix và hướng dẫn getOrientation

package com.sensorall; 


import com.sensorall.R; 
import android.hardware.*; 
import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 



public class OrientationAccelerometer extends Activity { 

    SensorManager sensorManager; 
    float[] mGravs = new float[3]; 
    float[] mGeoMags = new float[3]; 
    float[] mRotationM = new float[16]; 
    float[] mInclinationM = new float[16]; 
    float[] mOrientation = new float[3]; 
    float[] mOldOreintation = new float[3]; 
    String[] mAccelerometer = new String[3]; 
    String[] mMagnetic = new String[3];  
    String[] mRotation = new String[16]; 
    String[] mInclination = new String[16]; 
    String[] mOrientationString = new String[3]; 
    String[] mOldOreintationString = new String[3]; 


    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.orientationaccelerometer); 
     sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 

    } /* End onCreate activity */ 

    private SensorEventListener sensorEventListener = new SensorEventListener() { 

     public void onAccuracyChanged(Sensor sensor, int accuracy) { 

     } 


     /* Get the Sensors */ 
     public void onSensorChanged(SensorEvent event) { 

       switch (event.sensor.getType()) { 
        case Sensor.TYPE_ACCELEROMETER: 
           System.arraycopy(event.values, 0, mGravs, 0, 3); 
           break; 
        case Sensor.TYPE_MAGNETIC_FIELD: 
           System.arraycopy(event.values, 0, mGeoMags, 0, 3); 
           break; 
        case Sensor.TYPE_ORIENTATION: 
          System.arraycopy(event.values, 0, mOldOreintation, 0, 3); 
         break; 

        default: 
           return; 
      } 

       // If mGravs and mGeoMags have values then find rotation matrix 
       if (mGravs != null && mGeoMags != null) { 

        // checks that the rotation matrix is found 
        boolean success = SensorManager.getRotationMatrix(mRotationM, mInclinationM, mGravs, mGeoMags); 
        if (success) { 
         /* getOrientation Values */ 
         SensorManager.getOrientation(mRotationM, mOrientation); 

          for(int i=0; i<2; i++){ 
           mAccelerometer[i] = Float.toString(mGravs[i]); 
           mMagnetic[i] = Float.toString(mGeoMags[i]); 
           mOrientationString[i] = Float.toString(mOrientation[i]); 
           mOldOreintationString[i] = Float.toString(mOldOreintation[i]); 
          } 

          /* Make everything text to show on device */ 
          TextView xaxisAccelerometerText = (TextView)findViewById(R.id.xaxisAccelerometer); 
          xaxisAccelerometerText.setText(mAccelerometer[0]);  
          TextView yaxisAccelerometerText = (TextView)findViewById(R.id.yaxisAccelerometer); 
          yaxisAccelerometerText.setText(mAccelerometer[1]); 
          TextView zaxisAccelerometerText = (TextView)findViewById(R.id.zaxisAccelerometer); 
          zaxisAccelerometerText.setText(mAccelerometer[2]);  
          TextView xaxisMagneticText = (TextView)findViewById(R.id.xaxisMagnetic); 
          xaxisMagneticText.setText(mMagnetic[0]);  
          TextView yaxisMagneticText = (TextView)findViewById(R.id.yaxisMagnetic); 
          yaxisMagneticText.setText(mMagnetic[1]); 
          TextView zaxisMagneticText = (TextView)findViewById(R.id.zaxisMagnetic); 
          zaxisMagneticText.setText(mMagnetic[2]); 
          TextView xaxisOrientationText = (TextView)findViewById(R.id.xaxisOrientation); 
          xaxisOrientationText.setText(mOrientationString[0]);  
          TextView yaxisOrientationText = (TextView)findViewById(R.id.yaxisOrientation); 
          yaxisOrientationText.setText(mOrientationString[1]); 
          TextView zaxisOrientationText = (TextView)findViewById(R.id.zaxisOrientation); 
          zaxisOrientationText.setText(mOrientationString[2]); 
          TextView xaxisOldOrientationText = (TextView)findViewById(R.id.xaxisOldOrientation); 
          xaxisOldOrientationText.setText(mOldOreintationString[0]);  
          TextView yaxisOldOrientationText = (TextView)findViewById(R.id.yaxisOldOrientation); 
          yaxisOldOrientationText.setText(mOldOreintationString[1]); 
          TextView zaxisOldOrientationText = (TextView)findViewById(R.id.zaxisOldOrientation); 
          zaxisOldOrientationText.setText(mOldOreintationString[2]); 

        }else{ 

         /* Make everything text to show on device even if getRotationMatrix fails*/ 
          String matrixFailed = "Rotation Matrix Failed"; 
          TextView xaxisAccelerometerText = (TextView)findViewById(R.id.xaxisAccelerometer); 
          xaxisAccelerometerText.setText(mAccelerometer[0]);  
          TextView yaxisAccelerometerText = (TextView)findViewById(R.id.yaxisAccelerometer); 
          yaxisAccelerometerText.setText(mAccelerometer[1]); 
          TextView zaxisAccelerometerText = (TextView)findViewById(R.id.zaxisAccelerometer); 
          zaxisAccelerometerText.setText(mAccelerometer[2]);  
          TextView xaxisMagneticText = (TextView)findViewById(R.id.xaxisMagnetic); 
          xaxisMagneticText.setText(mMagnetic[0]);  
          TextView yaxisMagneticText = (TextView)findViewById(R.id.yaxisMagnetic); 
          yaxisMagneticText.setText(mMagnetic[1]); 
          TextView zaxisMagneticText = (TextView)findViewById(R.id.zaxisMagnetic); 
          zaxisMagneticText.setText(mMagnetic[2]); 
          TextView xaxisOrientationText = (TextView)findViewById(R.id.xaxisOrientation); 
          xaxisOrientationText.setText(matrixFailed);  
          TextView yaxisOrientationText = (TextView)findViewById(R.id.yaxisOrientation); 
          yaxisOrientationText.setText(matrixFailed); 
          TextView zaxisOrientationText = (TextView)findViewById(R.id.zaxisOrientation); 
          zaxisOrientationText.setText(matrixFailed); 
          TextView xaxisOldOrientationText = (TextView)findViewById(R.id.xaxisOldOrientation); 
          xaxisOldOrientationText.setText(mOldOreintationString[0]);  
          TextView yaxisOldOrientationText = (TextView)findViewById(R.id.yaxisOldOrientation); 
          yaxisOldOrientationText.setText(mOldOreintationString[1]); 
          TextView zaxisOldOrientationText = (TextView)findViewById(R.id.zaxisOldOrientation); 
          zaxisOldOrientationText.setText(mOldOreintationString[2]); 





        } 
       } 


     } 
    }; 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
     sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL); 
     sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL); 
    } 


    protected void onPause() { 
     super.onPause(); 
     sensorManager.unregisterListener(sensorEventListener); 
    }  

} 
+1

Bạn có ý gì khi 'không thành công'? Có phải bạn đang gặp lỗi, bạn không thấy dữ liệu/dữ liệu sai? – arunkumar

+0

Tôi nhận được thông báo: Ứng dụng SensorAll đã dừng không mong đợi. Vui lòng thử lại. Sau đó, bạn phải Buộc đóng nó –

+2

Vui lòng cung cấp một stacktrace từ logcat để chúng tôi có thể giúp bạn tốt hơn. –

Trả lời

-2

Việc tiếp nhận sự kiện không tuân theo quy trình thực hiện chương trình tuyến tính. Để tránh các sự cố, bạn nên đặt mã liên quan đến việc tiếp nhận các sự kiện cảm biến trong một khối loại trừ lẫn nhau.

Ý tôi là:

public void onSensorChanged(SensorEvent event) { 
    synchronized (this) { 
     ... 
    } 
} 

Hope this helps.

+1

Không đúng sự thật. Trừ khi được chỉ định khác, tất cả các cuộc gọi lại của bộ cảm biến sẽ xuất hiện trên luồng chính. – Dorje

+0

Bất kỳ liên kết hoặc tham chiếu đến bất kỳ tài liệu nào để chứng thực điều đó? – jap1968

+0

Điều này được thảo luận [ở đây] (http://stackoverflow.com/questions/17681870/android-which-thread-calls-onsensorchanged) trên stackoverflow. Bạn có thể tham khảo [mã nguồn cho SensorManager] (https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/hardware/SensorManager.java) – Aditya

1

Điều này có thể không áp dụng cho mã của bạn, nhưng về mặt sử dụng getRotationMatrix() nói chung, nó có thể giải quyết các vấn đề của người khác.

Tôi không chắc chắn nếu điều này là một vấn đề versioning đứng về phía tôi, nhưng tôi đã kiểm tra ra mã nguồn cho các phương pháp getRotationMatrix() và, không giống như những gì các tài liệu nói về các thông số R[]I[], họ KHÔNG THỂ được null . Sau tuyên bố của tôi RI như thế này:

float[] r = new float[9];

float[] i = new float[9];

Phương pháp này hoạt động một cách chính xác.

SensorManager.getRotationMatrix(r,i,gravity,geomagnetic) ->true

... lỗi tài liệu kỳ lạ.

3

Sau đây từng làm việc với tôi:

float[] r = new float[**16**]; 

Sử dụng rỗng cho tôi

float[] mOrientation = new float[4]; 

Có không . Tuy nhiên bạn chỉ sử dụng 3.

SensorManager.getRotationMatrix(rotationMatrix, null, accelVals, magVals); 

This code làm việc cho tôi.

0

Trong câu trả lời cho ứng dụng của bạn yêu cầu lực lượng đóng, có vẻ như tôi đang làm quá nhiều vào chuỗi giao diện người dùng quá thường xuyên. Bạn đang nhận dữ liệu từ 3 cảm biến khác nhau với độ trễ là SENSOR_DELAY_NORMAL. Mặc dù khoảng 5 lần đọc/giây, tôi đã thấy nó có thể có hơn 20 lần đọc mỗi giây (vì độ trễ của cảm biến chỉ là độ trễ được đề xuất). Vì vậy, bạn có thể nhận được hơn 60 lần đọc mỗi giây cho tất cả 3 cảm biến.cho mỗi lần đọc, bạn đang cập nhật 12 TextView, vì vậy bạn có thể thực hiện hơn 720 cập nhật giao diện người dùng mỗi giây. Điều này làm cho điện thoại của tôi bị hỏng. Thử đặt thời gian tối thiểu giữa các cập nhật giao diện người dùng:

long currentTime = System.currentTimeMillis(); 
if ((currentTime - lastUpdateTime) >= MIN_TIME_BETWEEN_UPDATES) { 
    // Update UI 
    lastUpdateTime = currentTime; 
} 

Bạn có thể lưu trữ dữ liệu trong khoảng thời gian nhanh để sử dụng nếu cần, nhưng làm chậm cập nhật giao diện người dùng.