0

Im new to andriod development. I have developed an app to set live wallpaper and wallpaper will change on intervals selected by user from dropdown. I have used WallpaperService to implement this. Handler with runnable is used to set the wallpaper and handler.postDelayed(runnable, WALLPAPER_DURATION); is used to trigger to change the wallpaper for selected interval. Problem is wallpaper rotates for the first selected interval, when user changes to another interval say from 5mins to 10mins, wallpaper should change for every 10mins, but my code is still changing it for 5mins.Im able to get the user changed interval in the service but im not able to kill the runnable in handler.postDelayed. I have used
handler.removeCallbacks(drawRunner); handler.removeCallbacksAndMessages(null); but dint help. I want to kill or update the runnable with new delay time(interval).

Runnable drawRunner = new Runnable() {
            @Override
            public void run() {
                System.out.println("TIMER SCHEDULED "+WALLPAPER_DURATION);
                drawFrame();
                incrementCounter();
            }

        };
        public MyWallpaperEngine() {
            System.out.println("MyWallpaperEngine ");
            mImagesArray = new int[] {R.drawable.one,R.drawable.two,R.drawable.three,
                    R.drawable.four,R.drawable.five,R.drawable.six,
                    R.drawable.seven,R.drawable.eight,R.drawable.nine,
                    R.drawable.ten};
            handler.post(drawRunner);
        }

        private void incrementCounter() {
            mImagesArrayIndex++;

            if (mImagesArrayIndex >= mImagesArray.length) {
                mImagesArrayIndex = 0;
            }
        }

        private void drawFrame() {
            System.out.println("inside draw frame");
            SurfaceHolder holder = getSurfaceHolder();
            System.out.println("holder Object " + holder);
            Canvas canvas = null;

            try {
                canvas = holder.lockCanvas();
                System.out.println("Canvas Object " + canvas);
                if (canvas != null) {
                    System.out.println("inside draw image");
                    drawImage(canvas);
                }
            } finally {
                if (canvas != null) {
                    holder.unlockCanvasAndPost(canvas);
                }
            }

            handler.postDelayed(drawRunner, WALLPAPER_DURATION);
            if(clearHandler){
                    System.out.println("inside remove callbacks");
                   handler.removeCallbacks(drawRunner);
                  handler.removeCallbacksAndMessages(null);
                  clearHandler=false;
            }
        }


        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            System.out.println("onSurfaceDestroyed is called");
            super.onSurfaceDestroyed(holder);
            //handler.removeCallbacks(drawRunner);
            //handler.removeCallbacksAndMessages(null);
        }

        private void drawImage(Canvas canvas)
        {
            Bitmap image = BitmapFactory.decodeResource(getResources(),
                    mImagesArray[mImagesArrayIndex]);
            Bitmap b=Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), true);
            canvas.drawBitmap(b, 0,0, null);
        }

        public void onDestroy(){
            super.onDestroy();
        //    handler.removeCallbacks(drawRunner);
          //  handler.removeCallbacksAndMessages(null);

        }
    }
LaJ
  • 45
  • 1
  • 7

1 Answers1

0

Use this base code.

private final Handler handler = new Handler();
        private final Runnable drawRunnable = new Runnable() {
            @Override
            public void run() {
                iteration();
                draw();
            }
        };
        protected void iteration(){
            handler.removeCallbacks( drawRunnable );
            if( visible ){
                handler.postDelayed( drawRunnable, 1000);
            }
        }
Style-7
  • 985
  • 12
  • 27
  • Can I know what's the difference between my code and Ur suggestion. U have called removecallbacks and postdelay in a method and I have put the same in draw method itself. Moreover I want wallpaper to get updated even the phone is in sleep mode. If I put postdelay inside visible it will be updated only when awake on home screen. Correct me if I'm wrong – LaJ Aug 21 '19 at 16:37
  • @Override public void onVisibilityChanged(boolean isVisible){ if( isVisible ){ handler.post( drawRunnable ); }else{ handler.removeCallbacks( drawRunnable ); } } – Style-7 Aug 21 '19 at 17:11
  • Onvisibitychanged will trigger only when awake right? I don't want this. I want wallpaper to set when on sleep mode to so I don't override this method – LaJ Aug 21 '19 at 17:21
  • I'm in very need and very important at earliest. Please help to solve this issue – LaJ Aug 21 '19 at 17:25