2012-08-12 1 views
0

После того, как я попытался все, что я думал, я попытаюсь посмотреть, знает ли кто-нибудь, в чем моя проблема, прежде чем полностью отказаться. Так что я пытаюсь сделать, чтобы мое изображение скользило за этим «вращающимся кубом». Например, если я наклоняю свой телефон вправо, он начинает скользить вправо и наоборот.ОбоиСервис и акселерометр

Вот код. Это очень длинный и получил много бессмысленного кода для этого вопроса, но я подумал, что даю ему полную информацию, игнорируя части, которые не являются импортными. Это пример CubeWallpaper1, предоставленный в sdk. Я только что изменил его и попытался добавить к нему акселерометр и заставить его работать.

Итак, если вы можете взглянуть и сказать мне, что с этим не так.

public class LiveWall extends WallpaperService implements SensorEventListener { 

    float xAxis,yAxis,zAxis; 
    private SensorManager mSensorManager; 
    private Sensor mAccelerometer; 
    Bitmap drawable; 


    private final Handler mHandler = new Handler(); 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 
     mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
     drawable = BitmapFactory.decodeResource(getResources(),R.drawable.bg); 
     mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 

    } 



    public void onAccuracyChanged(Sensor arg0, int arg1) { 
     // TODO Auto-generated method stub 

    } 

    public void onSensorChanged(SensorEvent event) { 
     xAxis = event.values[0]; 
     yAxis = event.values[1]; 
     zAxis = event.values[2]; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
    } 

    @Override 
    public Engine onCreateEngine() { 
     return new CubeEngine(); 
    } 



    class CubeEngine extends Engine { 

     private final Paint mPaint = new Paint(); 
     private float mOffset; 
     private float mTouchX = -1; 
     private float mTouchY = -1; 
     private long mStartTime; 
     private float mCenterX; 
     private float mCenterY; 

     private final Runnable mDrawCube = new Runnable() { 
      public void run() { 
       drawFrame(); 
      } 
     }; 
     private boolean mVisible; 

     CubeEngine() { 
      // Create a Paint to draw the lines for our cube 
      final Paint paint = mPaint; 
      paint.setColor(Color.GREEN); 
      paint.setAntiAlias(true); 
      paint.setStrokeWidth(15); 
      paint.setStrokeCap(Paint.Cap.ROUND); 
      paint.setStyle(Paint.Style.STROKE); 

      mStartTime = SystemClock.elapsedRealtime(); 
     } 

     @Override 
     public void onCreate(SurfaceHolder surfaceHolder) { 
      super.onCreate(surfaceHolder); 

      // By default we don't get touch events, so enable them. 
      setTouchEventsEnabled(true); 
     } 

     @Override 
     public void onDestroy() { 
      super.onDestroy(); 
      mHandler.removeCallbacks(mDrawCube); 
     } 

     @Override 
     public void onVisibilityChanged(boolean visible) { 
      mVisible = visible; 
      if (visible) { 
       drawFrame(); 
      } else { 
       mHandler.removeCallbacks(mDrawCube); 
      } 
     } 

     @Override 
     public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
      super.onSurfaceChanged(holder, format, width, height); 
      // store the center of the surface, so we can draw the cube in the right spot 
      mCenterX = width/2.0f; 
      mCenterY = height/2.0f; 
      drawFrame(); 
     } 

     @Override 
     public void onSurfaceCreated(SurfaceHolder holder) { 
      super.onSurfaceCreated(holder); 
     } 

     @Override 
     public void onSurfaceDestroyed(SurfaceHolder holder) { 
      super.onSurfaceDestroyed(holder); 
      mVisible = false; 
      mHandler.removeCallbacks(mDrawCube); 
     } 

     @Override 
     public void onOffsetsChanged(float xOffset, float yOffset, 
       float xStep, float yStep, int xPixels, int yPixels) { 
      mOffset = xOffset; 
      drawFrame(); 
     } 

     /* 
     * Store the position of the touch event so we can use it for drawing later 
     */ 
     @Override 
     public void onTouchEvent(MotionEvent event) { 
      if (event.getAction() == MotionEvent.ACTION_MOVE) { 
       mTouchX = event.getX(); 
       mTouchY = event.getY(); 
      } else { 
       mTouchX = -1; 
       mTouchY = -1; 
      } 
      super.onTouchEvent(event); 
     } 

     /* 
     * Draw one frame of the animation. This method gets called repeatedly 
     * by posting a delayed Runnable. You can do any drawing you want in 
     * here. This example draws a wireframe cube. 
     */ 
     void drawFrame() { 
      final SurfaceHolder holder = getSurfaceHolder(); 

      Canvas c = null; 
      try { 
       c = holder.lockCanvas(); 
       if (c != null) { 
        // draw something 
        drawCube(c); 
        drawTouchPoint(c); 
       } 
      } finally { 
       if (c != null) holder.unlockCanvasAndPost(c); 
      } 

      // Reschedule the next redraw 
      mHandler.removeCallbacks(mDrawCube); 
      if (mVisible) { 
       mHandler.postDelayed(mDrawCube, 1000/25); 
      } 
     } 

     /* 
     * Draw a wireframe cube by drawing 12 3 dimensional lines between 
     * adjacent corners of the cube 
     */ 
     void drawCube(Canvas c) { 
      c.save(); 
      c.translate(mCenterX, mCenterY); 
      c.drawColor(0xff000000); 
      c.drawBitmap(drawable, 0+xAxis,0+yAxis, mPaint); 
      drawLine(c, -400, -400, -400, 400, -400, -400); 
      drawLine(c, 400, -400, -400, 400, 400, -400); 
      drawLine(c, 400, 400, -400, -400, 400, -400); 
      drawLine(c, -400, 400, -400, -400, -400, -400); 

      drawLine(c, -400, -400, 400, 400, -400, 400); 
      drawLine(c, 400, -400, 400, 400, 400, 400); 
      drawLine(c, 400, 400, 400, -400, 400, 400); 
      drawLine(c, -400, 400, 400, -400, -400, 400); 

      drawLine(c, -400, -400, 400, -400, -400, -400); 
      drawLine(c, 400, -400, 400, 400, -400, -400); 
      drawLine(c, 400, 400, 400, 400, 400, -400); 
      drawLine(c, -400, 400, 400, -400, 400, -400); 
      c.restore(); 
     } 

     /* 
     * Draw a 3 dimensional line on to the screen 
     */ 
     void drawLine(Canvas c, int x1, int y1, int z1, int x2, int y2, int z2) { 
      long now = SystemClock.elapsedRealtime(); 
      float xrot = ((float)(now - mStartTime))/1000; 
      float yrot = (0.5f - mOffset) * 2.0f; 
      float zrot = 0; 

      // 3D transformations 

      // rotation around X-axis 
      float newy1 = (float)(Math.sin(xrot) * z1 + Math.cos(xrot) * y1); 
      float newy2 = (float)(Math.sin(xrot) * z2 + Math.cos(xrot) * y2); 
      float newz1 = (float)(Math.cos(xrot) * z1 - Math.sin(xrot) * y1); 
      float newz2 = (float)(Math.cos(xrot) * z2 - Math.sin(xrot) * y2); 

      // rotation around Y-axis 
      float newx1 = (float)(Math.sin(yrot) * newz1 + Math.cos(yrot) * x1); 
      float newx2 = (float)(Math.sin(yrot) * newz2 + Math.cos(yrot) * x2); 
      newz1 = (float)(Math.cos(yrot) * newz1 - Math.sin(yrot) * x1); 
      newz2 = (float)(Math.cos(yrot) * newz2 - Math.sin(yrot) * x2); 

      // 3D-to-2D projection 
      float startX = newx1/(4 - newz1/400); 
      float startY = newy1/(4 - newz1/400); 
      float stopX = newx2/(4 - newz2/400); 
      float stopY = newy2/(4 - newz2/400); 

      c.drawLine(startX, startY, stopX, stopY, mPaint); 
     } 

     /* 
     * Draw a circle around the current touch point, if any. 
     */ 
     void drawTouchPoint(Canvas c) { 
      if (mTouchX >=0 && mTouchY >= 0) { 
       c.drawCircle(mTouchX, mTouchY, 80, mPaint); 
      } 
     } 

    } 

} 

ответ

2

Вы не только должны реализовать SensorEventListener, но вы также должны зарегистрировать слушатель (ваша активность в данном случае) с SensorManager.

В вашем методе onStart сделать это:

SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 
sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 

В onStop (или) не забудьте отменить:

SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); 
sensorMgr.unregisterListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)); 

Вы могли бы также прочитать documentation из SensorManager с имеет хорошие примеры тоже.

+0

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

+0

c.drawBitmap (drawable, 0 + xAxis, 0 + yAxis, mPaint); это код, который я использую, чтобы нарисовать свое изображение. –

+0

Что вы получаете вообще? Является ли рисоваемое вообще рендерингом и просто не двигается? Попробуйте записать значения x, y, z в onSensorChanged(), чтобы узнать, вызвана ли она и какие значения вы получаете. – Ridcully

0

Я получаю данные акселерометра в обозревателе обоев. Вот мой код:

public class MyWallpaperService extends WallpaperService { 

Context context; 

public void onCreate() { 
    context = this; 
    super.onCreate(); 
} 

public void onDestroy() { 
    super.onDestroy(); 
} 

public Engine onCreateEngine() { 
    return new MyWallpaperEngine(); 
} 

class MyWallpaperEngine extends Engine implements SensorEventListener { 

    private final Handler handler = new Handler(); 
    private final Runnable drawRunner = new Runnable() { 
     @Override 
     public void run() { 
      draw(); 
     } 
    }; 
    private boolean visible = true; 

    private SensorManager mSensorManager; 
    private Sensor mAccelerometer; 
    private Display mDisplay; 

    private Bitmap mBackground; 

    private float mSensorX; 
    private float mSensorY; 
    private float mSensorZ; 

    MyWallpaperEngine() { 

     mBackground = BitmapFactory.decodeResource(getResources(), R.drawable.background); 

     mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); 
     mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
     WindowManager mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
     mDisplay = mWindowManager.getDefaultDisplay(); 

     BitmapFactory.Options opts = new BitmapFactory.Options(); 
     opts.inDither = true; 
     opts.inPreferredConfig = Bitmap.Config.RGB_565; 
     mBackground = BitmapFactory.decodeResource(getResources(), R.drawable.grass, opts); 
    } 

    public void registerSensors() { 
     Log.d(TAG, "registerSensors()"); 
     mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI); 
    } 

    public void unregisterSensors() { 
     Log.d(TAG, "unregisterSensors()"); 
     mSensorManager.unregisterListener(this); 
    } 

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

     switch (mDisplay.getRotation()) { 
      case Surface.ROTATION_0: 
       mSensorX = event.values[0]; 
       mSensorY = event.values[1]; 
       break; 
      case Surface.ROTATION_90: 
       mSensorX = -event.values[1]; 
       mSensorY = event.values[0]; 
       break; 
      case Surface.ROTATION_180: 
       mSensorX = -event.values[0]; 
       mSensorY = -event.values[1]; 
       break; 
      case Surface.ROTATION_270: 
       mSensorX = event.values[1]; 
       mSensorY = -event.values[0]; 
       break; 
     } 
     mSensorZ = event.values[2]; 
     //This is your Accelerometer X,Y,Z values 
     Log.d(TAG, "X: " + mSensorX + ", Y: " + mSensorY + ", Z: " + mSensorZ); 
    } 

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

    } 


    public void onCreate(SurfaceHolder surfaceHolder) { 
     super.onCreate(surfaceHolder); 
     registerSensors(); 
    } 

    @Override 
    public void onVisibilityChanged(boolean visible) { 
     this.visible = visible; 
     // if screen wallpaper is visible then draw the image otherwise do not draw 
     if (visible) { 
      handler.post(drawRunner); 
     } else { 
      handler.removeCallbacks(drawRunner); 
     } 
    } 

    @Override 
    public void onSurfaceDestroyed(SurfaceHolder holder) { 
     super.onSurfaceDestroyed(holder); 
     this.visible = false; 
     handler.removeCallbacks(drawRunner); 
    } 

    public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) { 
     final SurfaceHolder holder = getSurfaceHolder(); 


      draw(); 
    } 

    void draw() { 
     final SurfaceHolder holder = getSurfaceHolder(); 

     Canvas c = null; 
     try { 
      c = holder.lockCanvas(); 
      // clear the canvas 
      c.drawColor(Color.BLACK); 

      if (c != null) { 
       c.drawBitmap(mBackground, 0, 0, null); 

      } 
     } 
     finally { 
      if (c != null) 
       holder.unlockCanvasAndPost(c); 
     } 

     handler.removeCallbacks(drawRunner); 
     if (visible) { 
      handler.postDelayed(drawRunner, 10); // delay 10 mileseconds 
     } 

    } 

    @Override 
    public void onDestroy() { 
     unregisterSensors(); 
     super.onDestroy(); 
    } 
} 

}

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

  • Нет связанных вопросов^_^