Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 服务和加速计_Android_Service_Sensors_Live Wallpaper - Fatal编程技术网

Android 服务和加速计

Android 服务和加速计,android,service,sensors,live-wallpaper,Android,Service,Sensors,Live Wallpaper,在尝试了我所想的一切之后,在我完全放弃之前,我会尝试看看这里的人是否知道我的问题所在。所以我想做的是让我的图像滑到这个“旋转立方体”后面。例如,如果我将手机向右倾斜,它就会开始向右滑动,反之亦然 这是代码。这是一个很长的问题,有很多没有意义的代码,但我想给出完整的,忽略那些不重要的部分。这是sdk中提供的CubeWallpaper1示例。我刚刚修改了它,并试图添加加速计,使其工作 如果你能看一下,告诉我它有什么问题 public class LiveWall extends WallpaperS

在尝试了我所想的一切之后,在我完全放弃之前,我会尝试看看这里的人是否知道我的问题所在。所以我想做的是让我的图像滑到这个“旋转立方体”后面。例如,如果我将手机向右倾斜,它就会开始向右滑动,反之亦然

这是代码。这是一个很长的问题,有很多没有意义的代码,但我想给出完整的,忽略那些不重要的部分。这是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);
            }
        }

    }

}

您不仅必须实现
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
,其中也有一些很好的示例。

我正在墙纸服务中获取加速计数据。这是我的密码:

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();
    }
}

}

我仍然无法让它工作,如果你能看一下,我更新了我的代码。我想做的是让我的绘图能够根据加速度计的值在屏幕上左右移动。我知道,这样我将无法让它移动超过9.8左右,但这就是我现在想要的。我只想看到我的代码为nowc.drawBitmap(drawable,0+xAxis,0+yAxis,mpain)工作;这是我用来画图像的代码你得到了什么?是否渲染了可绘制对象,但不移动?尝试在onSensorChanged()中记录x、y、z值,以查看是否调用了该值以及得到的值。此外,也许您应该将c.drawBitmap放在c.save()之前,因为它们使用此和下面的c.translate()在画布的中心绘制立方体。图像在中心绘制,但不会移动。好的,我现在试着换一下