3

我创建一个动态壁纸,我使用本教程为出发点:如何在设置更新后重新启动此壁纸引擎?

http://code.tutsplus.com/tutorials/create-a-live-wallpaper-on-android-using-an-animated-gif--cms-23088

我想添加一个设置菜单,让用户选择四种背景之一。我有一切工作使用SharedPreferences。唯一的问题是在设置菜单中更改设置后壁纸不会更新。如果重新启动应用程序,背景将使用所选的最后一个背景进行更新,但只有在壁纸重新启动后(即选择不同的壁纸,然后重新选择此壁纸)才能使用该背景。

我已经缩小了问题的范围,因为SharedPreference的值仅在onCreateEngine()方法中更新。一旦壁纸服务正在运行,onCreateEngine()方法不会被调用,所以即使SharedPreference的值已更改,它也不会在壁纸服务中更新。

我的问题是如何重新启动墙纸,以便在设置被更改后调用onCreateEngine()方法?再次,SharedPreferences正在工作,因为一切重新启动后工作。我知道我需要使用onsharedPreferenceChanged方法,但我不确定应该在哪里发生,或者该方法应该包含哪些代码才能重新启动壁纸引擎。

下面是示例代码。我的是除非注释所指示的一样:

import android.graphics.Canvas; 
    import android.graphics.Movie; 
    import android.os.Handler; 
    import android.service.wallpaper.WallpaperService; 
    import android.util.Log; 
    import android.view.SurfaceHolder; 

    import java.io.IOException; 

    public class GIFWallpaperService extends WallpaperService implements onsharedpreferencechangelistener { 

     // Variable I added to change background 
     String mBackgroundImage = null; 

     // Method I added to update background image 
     public void updatedBackgroundImage(){ 
      // code that sets mBackgroundImage based upon value of shared preference file. 
     } 

     @Override 
     public WallpaperService.Engine onCreateEngine() { 

      // I call this method to change the value of mBackgroundImage 
      updateBackgroundImage(); 

      try { 
       Movie movie = Movie.decodeStream(
         getResources().getAssets().open("mBackgroundImage")); 

       return new GIFWallpaperEngine(movie); 
      }catch(IOException e){ 
       Log.d("GIF", "Could not load asset"); 
       return null; 
      } 
     } 

     @Override 
     public void onSharedPreferenceChanged(SharedPreferences sp, String key) { 
    // What do I do? How do I make the wallpaper engine restart when settings are changed? 
     } 

     private class GIFWallpaperEngine extends WallpaperService.Engine { 

      private final int frameDuration = 20; 

      private SurfaceHolder holder; 
      private Movie movie; 
      private boolean visible; 
      private Handler handler; 

      public GIFWallpaperEngine(Movie movie) { 
       this.movie = movie; 
       handler = new Handler(); 
      } 

      @Override 
      public void onCreate(SurfaceHolder surfaceHolder) { 
       super.onCreate(surfaceHolder); 
       this.holder = surfaceHolder; 
      } 

      private Runnable drawGIF = new Runnable() { 
       public void run() { 
        draw(); 
       } 
      }; 


      private void draw() { 
       if (visible) { 
        Canvas canvas = holder.lockCanvas(); 
        canvas.save(); 
         // Adjust size and position so that 
         // the image looks good on your screen 
         canvas.scale(3f, 3f); 
         movie.draw(canvas, -100, 0); 
        canvas.restore(); 
        holder.unlockCanvasAndPost(canvas); 
        movie.setTime((int) (System.currentTimeMillis() % movie.duration())); 

        handler.removeCallbacks(drawGIF); 
        handler.postDelayed(drawGIF, frameDuration); 
       } 
      } 

      @Override 
      public void onVisibilityChanged(boolean visible) { 
       this.visible = visible; 
       if (visible) { 
        handler.post(drawGIF); 
       } else { 
        handler.removeCallbacks(drawGIF); 
       } 
      } 

      @Override 
      public void onDestroy() { 
       super.onDestroy(); 
       handler.removeCallbacks(drawGIF); 
      } 
     } 
    } 
+0

任何人都可以帮助我吗? –

+0

在继续讨论这个问题之后,我认为问题在于发生更改时不会调用onSharedPreferenceChange()。我试图找出原因。 –

+0

好吧,我解决了'onSharedPreferenceChange()'没有被调用的问题。它现在从'WallpaperService'内被调用,但我无法弄清楚在实现中应该放什么。当'Service'第一次启动时,一切都正常工作...并且设置背景图像的变量根据用户在菜单中选择的内容得到更新,但由于'Service'已经运行,更新后的变量没有任何影响。请帮忙!!! –

回答

-1

我不知道,如果你找到你的答案,但我看到这个在android裁判:

WallpaperService.Engine onCreateEngine()

必须执行才能返回壁纸引擎的新实例。请注意,多个实例可能同时处于活动状态,例如当壁纸当前设置为活动壁纸并且用户在壁纸选取器中时,也会查看其预览。

chris

1

我已经很晚了,但希望有人会觉得这个有用。

您需要先指定并注册SharedPrefs。将此添加到您的onCreate()方法中。

SharedPreferences preferences = getSharedPreferences("PREFERENCES NAME", Context.MODE_PRIVATE); 
     preferences.registerOnSharedPreferenceChangeListener(this);