Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8104477
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 5, 20262026-06-05T23:51:23+00:00 2026-06-05T23:51:23+00:00

I recently posted a question about screen rotation in my live wallpaper. To test

  • 0

I recently posted a question about screen rotation in my live wallpaper. To test why I was having these problems, I created the simple program below:

package com.live.waller;

import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class LiveWallpaperService extends WallpaperService {


/** Called when the activity is first created. */

@Override
public Engine onCreateEngine() {
    // TODO Auto-generated method stub
    return new LiveWallerEngine();
}


class LiveWallerEngine extends Engine {

    SurfaceHolder holder;
    private Handler mHandle;

    LiveWallerEngine() {
        mHandle = new Handler();
        holder = getSurfaceHolder();
    }


    private Runnable runner = new Runnable() {

        public void run() {
            // TODO Auto-generated method stub
            drawFrame();
        }

    };

    public void drawFrame() {
        while(isVisible()) {
            if(!holder.getSurface().isValid())
                continue;

            Canvas c = null;

            try{
                c = holder.lockCanvas();

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

    public void drawSurface(Canvas c) {


        c.save();

        c.drawColor(Color.argb(255, 100, 200, 124));

        c.restore();

    }

    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {
        // TODO Auto-generated method stub
        super.onCreate(surfaceHolder);

        setTouchEventsEnabled(true);
        mHandle.post(runner);

    }

    @Override
    public void onOffsetsChanged(float xOffset, float yOffset,
            float xOffsetStep, float yOffsetStep, int xPixelOffset,
            int yPixelOffset) {
        // TODO Auto-generated method stub
        super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
                xPixelOffset, yPixelOffset);
    }

    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format,
            int width, int height) {
        // TODO Auto-generated method stub
        super.onSurfaceChanged(holder, format, width, height);

        mHandle.post(runner);
    }

    @Override
    public void onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        super.onTouchEvent(event);
    }

    @Override
    public void onVisibilityChanged(boolean visible) {
        // TODO Auto-generated method stub
        super.onVisibilityChanged(visible);

    }

    @Override
    public void setTouchEventsEnabled(boolean enabled) {
        // TODO Auto-generated method stub
        super.setTouchEventsEnabled(enabled);
    }   
}

}

And when I rotate my wallpaper, I am greeted with a blank screen. Does anyone know what is wrong with my code?

When I run the wallpaper, I get these errors in logcat:

ActivityManager: force stopping package com.live.waller uid=10046
PackageManager: Not granting permission android.permission.BIND_WALLPAPER to package com.live.waller (protectionLevel=3 flags=0xbe46)
dalvikvm: GC_CONCURRENT freed 609K, 43% free 4604K/8071K, external 904K/1222K, paused 6ms+7ms
dalvikvm: GC_EXPLICIT freed 320K, 44% free 4561K/8071K, external 904K/1222K, paused 138ms
dalvikvm: GC_EXTERNAL_ALLOC freed 197K, 51% free 2955K/6023K, external 1736K/1742K, paused 78ms

What’s strange is that I get a force stop message in logcat but not on the emulator when I set my wallpaper.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-05T23:51:25+00:00Added an answer on June 5, 2026 at 11:51 pm

    Your drawFrame()-method will be stuck in an infinite loop, as long as isVisible() returns true. There is no need for a while-statement to loop through the locking and posting of your freshly painted Canvas, when you got a Runnable with a Handler.

    A better implementation of drawFrame() can be found in the Cube Live Wallpaper example in the SDK.

    private void drawFrame() {
        Canvas c = null;
    
        try {
            // Get a Canvas from the surfaceHolder, so we got something to paint on
            c = holder.lockCanvas();
    
            // Make sure we got a valid (non-null) canvas.
            if(c != null) {
                // Draw something onto the canvas
                drawSurface(c);
            }
        } finally {
            if(c != null) 
                // Notify the SurfaceHolder that we are done painting the canvas,
                // and we want it shown on the screen
                holder.unlockCanvasAndPost(c);
        }
    
        // If your wallpaper is going to have animated objects, you will have to tell
        // the handler to schedule new runs on your Runnable object.
    
        // First we remove any pending task in the Handlers message queue
        mHandle.removeCallbacks(runner);
    
        // Then we tell the Handler to schedule a new run some time in the future. The 
        // time we specify here will decide how often the screen updates, or in other words
        // the FPS of your wallpaper. If the wallpaper is not visible, there is no reason to update wallpaper. So we only schedule a new run, if mIsVisible is true.    
        if(mIsVisible) { 
            mHandle.postDelayed(runner, 1000 / desiredFPS);
        }
    }
    

    Now, we use Engine.onVisibilityChanged() to decide whether or not the wallpaper is visible.

    @Override
    public void onVisibilityChanged(boolean visible) {
        // Set mIsVisible equal to visible, so that drawFrame() can decide wheter to reschedule run or not.
        mIsVisible = visible;
    
        if (visible) {
            // Since drawFrame() tells the handler to schedule new runs, we only need to call drawFrame() once. In drawFrame(), mHandle.postDelayed() will then continuously update the screen, as long as its visible.
            drawFrame();
        } else {
            // If not, remove any pending posts, since we no longer need to update the wallpaper.
            mHandle.removeCallbacks(runner);
        }
    }
    

    If the Surface we paint to somehow gets destroyed (Ex.: If the user sets a new background), we also want to remove any pending posts. So in Engine.onSurfaceDestroyed(), we do

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
        super.onSurfaceDestroyed(holder);
        mHandle.removeCallbacks(runner);
    }
    

    Regarding the force close issue:
    What API-level are your trying to run the Wallpaper on?

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I recently posted a question here about some memory issues I was having. I've
I recently posted a question about centering a page with CSS. I figured out
I recently posted a question about getting a NullPointerException whenever I called an array
I recently posted a question about splitting a string when a character is instanced.
I recently posted a question about getting last 3 results in table in the
I recently posted a question about optimizing the algorithm to compute the Levenshtein Distance,
I posted recently a question about the memory overhead due to virtuality in C++.
I recently posted a question about reading Word files here . The app runs
Recently i posted a question about what the variable is of a file which
I recently posted this question about summing arrays in JavaScript using d3.nest() I got

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.