0

I have a Live Wallpaper which I'd like to add gestures to but I can't seem to find where to actually add the listener. What is considered the 'view' in a live wallpaper which i can add setOnGestureListener() to please?

here is the code for my engine

class HexClockEngine extends Engine
{
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private static final float LINE_WIDTH = 275f;
    private static final float TEXT_SIZE_DP = 70f;
    private static final String TAG = "WallpaperEngine";

    private final   Handler     _handler        = new Handler();
    private final   Paint       _borderPaint    = new Paint();
    private final   Paint       _shadowPaint    = new Paint();
    private final   Paint       _textPaint      = new Paint();
    private final   Runnable    _draw       = new Runnable() {
                                public void run()
                                {
                                    drawFrame();
                                }
                            };
    class HexGestureListener extends SimpleOnGestureListener
    {
        @Override 
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 
        {
            Log.i("fling", TAG);

            try
            {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                    return false;

                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
                {
                    Log.i(TAG, "swipe left");
                    return true;
                }
                else if (e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
                {
                    Log.i(TAG, "swipe right");
                    return true;
                }
            }
            catch (Exception e)
            {
                Log.e(TAG, e.toString());
            }

            return false;
        }

        @Override
        public boolean onDown(MotionEvent e) 
        {
            Log.i(TAG, "onDown");
            return true;
        }
    }
    private GestureDetector         _gestureDetector;
    private View.OnTouchListener    _gestureListener;

    private         Rect            _border;
    private         Rect            _screenBounds;
    private         boolean         _isVisible;
    private final   float           _scale;


    HexClockEngine()
    {
        DisplayMetrics metrics = new DisplayMetrics();
        Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
        display.getMetrics(metrics);

        // initialise drawables
        _scale = metrics.density;

        Log.i(TAG, "adding gestures");
        _gestureDetector = new GestureDetector(new HexGestureListener());
        _gestureListener = new View.OnTouchListener()
        {
            public boolean onTouch(View v, MotionEvent e)
            {
                if (_gestureDetector.onTouchEvent(e)) return true;
                else return false;
            }
        };

    }

    @Override
    public void onCreate(SurfaceHolder surfaceHolder)
    {
        super.onCreate(surfaceHolder);
        surfaceHolder.setFormat(android.graphics.PixelFormat.RGBA_8888);
        setTouchEventsEnabled(true);
    }

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

    @Override
    public void onVisibilityChanged(boolean visible)
    {
        _isVisible = visible;

        if (_isVisible)
        {
            drawFrame();
        }
        else
        {
            _handler.removeCallbacks(_draw);
        }
    }

    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format,
            int width, int height)
    {
        super.onSurfaceChanged(holder, format, width, height);

        drawFrame();
    }

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

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder)
    {
        super.onSurfaceDestroyed(holder);
        _isVisible = false;
        _handler.removeCallbacks(_draw);
    }

    @Override
    public void onOffsetsChanged(float xOffset, float yOffset, float xStep,
            float yStep, int xPixels, int yPixels)
    {

        drawFrame();
    }


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

        Canvas c = null;
        try
        {
            c = holder.lockCanvas();

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

        _handler.removeCallbacks(_draw);

        if (_isVisible)
        {
            _handler.postDelayed(_draw, 1000);
        }
    }
}

Thanks in advance

obie

obie
  • 578
  • 7
  • 23
  • note, the gesture code for this live wallpaper has been heavily influenced by [this](http://stackoverflow.com/questions/937313/android-basic-gesture-detection) thread – obie May 10 '11 at 16:24

3 Answers3

2

Live wallpaper works somewhat differently from normal Android stuff. You don't get a view. All you get is a canvas, and you have to structure things differently...essentially you are coordinating with the launcher. The Cube example in the SDK is a good point of departure: it enables touch events in onCreate, and then overrides the onTouchEvent method. Bear in mind that any gestures you get this way will also be processed by the launcher. If all you need is simple screen taps, it is better practice to use onCommand and check for android.wallpaper.tap as described here.

Ahmad
  • 69,608
  • 17
  • 111
  • 137
George Freeman
  • 2,260
  • 1
  • 15
  • 22
  • Hi George. Thanks for the response and the great explanation of how the live wallpapers work - that's helped me out no end. I'm actually after a swipe up and down so ill basically have to roll my own gestures using the touch example from the cube sample. Thanks again – obie May 11 '11 at 18:13
1

I've had the same problem, i found a workaround for my wallpaper by adding a touch event in an array each time the onTouchEvent is called, then i process the data in the array via polling. It is far from an optimal solution but it works for what i need in the wallpaper. However it would be great to have the full gestures listener as it would allow for great flexibility.

warhead
  • 11
  • 1
0

You can pass the MotionEvent from onTouchEvent to a GestureDetector.SimpleOnGestureListener to detect double taps, etc, and then confirm that the event is intended for the wallpaper using the onCommand method as Muzei does.

Jamie Kitson
  • 3,973
  • 4
  • 37
  • 50