在尝试了所有的事情后,我想我会试着看看这里有人知道我的问题是什么,然后我完全放弃了。所以我要做的是让我的图像在这个“旋转立方体”后面滑动。例如,如果我将手机向右倾斜,则开始向右滑动,反之亦然。
这是代码。对于这个问题,它很长并且得到了很多无意义的代码,但是我想把它完整,忽略那些不重要的部分。它是sdk中提供的CubeWallpaper1示例。我刚刚修改了它并尝试添加加速度计并使其工作。
所以,如果你能看看并告诉我它有什么问题。
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);
}
}
}
}
答案 0 :(得分:2)
您不仅必须实施SensorEventListener
,还必须使用SensorManager
注册听众(在本案例中为您的活动)。
在onStart
方法中执行此操作:
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
在onStop
(或onPause
)中,不要忘记取消注册:
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorMgr.unregisterListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER));
你也可以阅读SensorManager
的{{3}},但也有一些很好的例子。
答案 1 :(得分:0)
我在Wallpaper Service中获得加速计数据。这是我的代码:
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();
}
}
}