• 周三. 4 月 22nd, 2026

物嫩软件资讯网

软件资讯来物嫩

android动态壁纸LiveWallpaper用法

admin@wunen

6 月 3, 2025


原文地址:

http://blog.csdn.net/oldmtn/article/details/9177123




学习到的知识总结:


先贴上我的AndroidManifest.xml的内容。




  1. <?


    xml




    version


    =


    “1.0”




    encoding


    =


    “utf-8”


    ?>







  2. <


    manifest




    xmlns:android


    =


    “http://schemas.android.com/apk/res/android”







  3. package


    =


    “com.example.testlivewallpaper”







  4. android:versionCode


    =


    “1”







  5. android:versionName


    =


    “1.0”




    >










  6. <


    uses-sdk







  7. android:minSdkVersion


    =


    “8”







  8. android:targetSdkVersion


    =


    “16”




    />










  9. <


    application







  10. android:allowBackup


    =


    “true”







  11. android:icon


    =


    “@drawable/ic_launcher”







  12. android:label


    =


    “@string/app_name”







  13. android:theme


    =


    “@style/AppTheme”




    >







  14. <


    service







  15. android:name


    =


    “com.example.testlivewallpaper.Wallpaper”







  16. android:label


    =


    “@string/service_name”







  17. android:permission


    =


    “android.permission.BIND_WALLPAPER”




    >







  18. <


    intent-filter


    >







  19. <


    action




    android:name


    =


    “android.service.wallpaper.WallpaperService”




    />







  20. </


    intent-filter


    >










  21. <


    meta-data







  22. android:name


    =


    “android.service.wallpaper”







  23. android:resource


    =


    “@xml/wallpaper”




    />







  24. </


    service


    >







  25. </


    application


    >










  26. </


    manifest


    >









1. 自己编写的动态壁纸相关的类必须从WallpaperService类派生




2. 需要自己提供一个xml描述的wallpaper,该wallpaper作为你选择动态壁纸时候的预览图片。


我这里为:




  1. <


    meta-data







  2. android:name


    =


    “android.service.wallpaper”







  3. android:resource


    =


    “@xml/wallpaper”




    />






其中wallpaper内容为:




  1. <?


    xml




    version


    =


    “1.0”




    encoding


    =


    “utf-8”


    ?>







  2. <


    wallpaper




    xmlns:android


    =


    “http://schemas.android.com/apk/res/android”







  3. android:author


    =


    “@+string/author”







  4. android:description


    =


    “@string/description”







  5. android:thumbnail


    =


    “@drawable/cold”




    />








3.因为动态壁纸是一种服务,是给系统的壁纸管理程序调用的,所以可以不需要Activity。


当然你也可以添加一个Activity,然后给出列表,提供多个LiveWallpaper供用户选择。
















///


参考链接1:


地址:http://blog.csdn.net/blogercn/article/details/7407647


安卓从2.1开始支持动态墙纸编程,英文名字叫live wallpaper 。自己编写的动态壁纸必须从WallpaperService类派生,并且在重载其方法onCreateEngine里实现自己的动态效果。其代码如下,SimpleWallpaperEngine是我们基于Engine类派生的类:


public Engine onCreateEngine() {


return new SimpleWallpaperEngine();


}


上面retun返回的代码就是我们用Engine类的派生类创建的对象,其实现过程使用surfaceview更新。所以要学习动态墙纸编程,最好是已经熟练的掌握了surfaceview使用技巧。在Engine类里,有很多方法,我们需要重载以下三个方法,


1.创建壁纸


public void onCreate(SurfaceHoldersurfaceHolder){…}


2.释放壁纸


public void onDestroy(){…}


3.VisibilityChanged是用来设置当前动态壁纸可见时显示动画。当其不可见时,壁纸会停止运行,不显示动画,代码如下:




  1. @Override







  2. public




    void


    onVisibilityChanged(


    boolean


    visible) {




  3. canDraw = visible;




  4. if


    (visible) {




  5. drawDroid();

    // 自己的绘屏函数






  6. }

    else


    {




  7. handler.removeCallbacks(drawRequest);

    // 不可见时,移除回调






  8. }



  9. }






drawDroid


是我写的一个简单的根据随机数画线的函数,代码如下:




  1. private




    void


    drawDroid() {





  2. final


    SurfaceHolder holder = getSurfaceHolder();




  3. Canvas canvas =

    null


    ;





  4. try


    {




  5. canvas = holder.lockCanvas();




  6. if


    (canvas !=


    null


    ) {




  7. paint.setColor(Color.BLUE);



  8. paint.setStrokeWidth(

    10


    );




  9. paint.setStyle(Style.STROKE);



  10. nx = (

    int


    ) (rand.nextFloat() * virtualWidth);




  11. ny = (

    int


    ) (rand.nextFloat() * virtualHeight);




  12. m_path.lineTo(nx, ny);



  13. canvas.drawPath(m_path, paint);



  14. }



  15. }

    finally


    {





  16. if


    (canvas !=


    null


    ) {




  17. holder.unlockCanvasAndPost(canvas);



  18. }



  19. }



  20. handler.removeCallbacks(drawRequest);




  21. if


    (canDraw) {




  22. handler.postDelayed(drawRequest,

    33


    );




  23. }



  24. }





由于动画是使用surfacewive实现的,所以我们也要重载surfacewive的方法:


1.  建立


onSurfaceCreated


2.  释放


onSurfaceDestroyed


3.  大小变化,横竖屏操作,与用户交互时修改


onSurfaceChanged


如果需要添加用户交互,需要重载



public voidonTouchEvent(MotionEvent event)




surfacewive使用线程更新屏幕,我们可以使用Runnable接口创建一个线程,把我们的绘画函数放进去,并把他添加到窗口handler回调里,代码如下:




  1. private




    final


    Runnable drawRequest =


    new


    Runnable() {





  2. @Override







  3. public




    void


    run() {





  4. try


    {




  5. Thread.sleep(

    1000


    );




  6. drawDroid();



  7. }

    catch


    (InterruptedException e) {





  8. // TODO Auto-generated catch block






  9. e.printStackTrace();



  10. }



  11. }



  12. };











完整的代码如下“:




  1. package


    com.androidbook.simplelivewallpaper;








  2. import


    java.util.Random;





  3. import


    android.graphics.Canvas;





  4. import


    android.graphics.Color;





  5. import


    android.graphics.Paint;





  6. import


    android.graphics.Path;





  7. import


    android.graphics.Paint.Style;





  8. import


    android.os.Handler;





  9. import


    android.service.wallpaper.WallpaperService;





  10. import


    android.view.MotionEvent;





  11. import


    android.view.SurfaceHolder;








  12. public




    class


    SimpleDroidWallpaper


    extends


    WallpaperService {





  13. // private static final String DEBUG_TAG = “SimpleDroidWallpaper”;







  14. private




    final


    Handler handler =


    new


    Handler();








  15. @Override







  16. public


    Engine onCreateEngine() {





  17. return




    new


    SimpleWallpaperEngine();




  18. }







  19. class


    SimpleWallpaperEngine


    extends


    WallpaperService.Engine {








  20. boolean


    canDraw =


    true


    ;





  21. private




    int


    virtualHeight;





  22. private




    int


    virtualWidth;




  23. Paint paint =

    new


    Paint();




  24. Path m_path =

    new


    Path();





  25. volatile




    int


    ox =


    0


    , oy =


    0


    , nx =


    100


    , ny =


    200


    ;





  26. final


    Random rand =


    new


    Random();








  27. private




    final


    Runnable drawRequest =


    new


    Runnable() {





  28. @Override







  29. public




    void


    run() {





  30. try


    {




  31. Thread.sleep(

    1000


    );




  32. drawDroid();



  33. }

    catch


    (InterruptedException e) {





  34. // TODO Auto-generated catch block






  35. e.printStackTrace();



  36. }



  37. }



  38. };







  39. public


    SimpleWallpaperEngine() {




  40. m_path.lineTo(ox, oy);



  41. }







  42. @Override







  43. public




    void


    onCreate(SurfaceHolder surfaceHolder) {





  44. super


    .onCreate(surfaceHolder);





  45. // When touch is enable, all MotionEvents are passed, even those







  46. // handled by other widgets






  47. setTouchEventsEnabled(

    true


    );




  48. virtualHeight = getDesiredMinimumHeight();



  49. virtualWidth = getDesiredMinimumWidth();



  50. }







  51. @Override







  52. public




    void


    onDestroy() {





  53. super


    .onDestroy();




  54. handler.removeCallbacks(drawRequest);



  55. }







  56. @Override







  57. public




    void


    onVisibilityChanged(


    boolean


    visible) {




  58. canDraw = visible;




  59. if


    (visible) {




  60. drawDroid();

    // 自己的绘屏函数






  61. }

    else


    {




  62. handler.removeCallbacks(drawRequest);

    // 不可见时,移除回调






  63. }



  64. }







  65. @Override







  66. public




    void


    onOffsetsChanged(


    float


    xOffset,


    float


    yOffset,





  67. float


    xOffsetStep,


    float


    yOffsetStep,


    int


    xPixelOffset,





  68. int


    yPixelOffset) {





  69. super


    .onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,




  70. xPixelOffset, yPixelOffset);



  71. }







  72. @Override







  73. public




    void


    onSurfaceCreated(SurfaceHolder holder) {





  74. super


    .onSurfaceCreated(holder);




  75. }







  76. @Override







  77. public




    void


    onSurfaceChanged(SurfaceHolder holder,


    int


    format,





  78. int


    width,


    int


    height) {





  79. super


    .onSurfaceChanged(holder, format, width, height);







  80. drawDroid();



  81. }







  82. @Override







  83. public




    void


    onSurfaceDestroyed(SurfaceHolder holder) {





  84. super


    .onSurfaceDestroyed(holder);




  85. canDraw =

    false


    ;




  86. handler.removeCallbacks(drawRequest);



  87. }







  88. private




    void


    drawDroid() {





  89. final


    SurfaceHolder holder = getSurfaceHolder();




  90. Canvas canvas =

    null


    ;





  91. try


    {




  92. canvas = holder.lockCanvas();




  93. if


    (canvas !=


    null


    ) {




  94. paint.setColor(Color.BLUE);



  95. paint.setStrokeWidth(

    10


    );




  96. paint.setStyle(Style.STROKE);



  97. nx = (

    int


    ) (rand.nextFloat() * virtualWidth);




  98. ny = (

    int


    ) (rand.nextFloat() * virtualHeight);




  99. m_path.lineTo(nx, ny);



  100. canvas.drawPath(m_path, paint);



  101. }



  102. }

    finally


    {





  103. if


    (canvas !=


    null


    ) {




  104. holder.unlockCanvasAndPost(canvas);



  105. }



  106. }



  107. handler.removeCallbacks(drawRequest);




  108. if


    (canDraw) {




  109. handler.postDelayed(drawRequest,

    33


    );




  110. }



  111. }







  112. @Override







  113. public




    void


    onTouchEvent(MotionEvent event) {





  114. /* 添加触屏效果 */







  115. super


    .onTouchEvent(event);




  116. }



  117. }



  118. }





完整的XML文件如下:


<?xml version=”1.0″ encoding=”utf-8″?>

<manifest

xmlns:

Android

=”http://schemas.android.com/apk/res/android”

package=”com.androidbook.simplelivewallpaper”

android:versionCode=”1″

android:versionName=”1.0″>

<application

android:icon=”@drawable/icon”

android:label=”@string/app_name”

android:debuggable=”true”>

<activity

android:name=”.SimpleLiveWallpaperMenuActivity”

android:label=”@string/app_name”>

<intent-filter>

<action

android:name=”android.intent.action.MAIN” />

<category

android:name=”android.intent.category.LAUNCHER” />

</intent-filter>

</activity>

<service

android:label=”@string/wallpaper_name”

android:name=”SimpleDroidWallpaper”

android:permission=”android.permission.BIND_WALLPAPER”>

<intent-filter>

<action

android:name=”android.service.wallpaper.WallpaperService” />

</intent-filter>

<meta-data

android:name=”android.service.wallpaper”

android:resource=”@xml/droid_wallpaper” />

</service>

</application>

<uses-sdk

android:minSdkVersion=”7″

android:targetSdkVersion=”8″ />

<uses-feature

android:name=”android.software.live_wallpaper” />

</manifest>


其实我们这里创建的墙纸不需要Activity类,只是一种服务,是被墙纸管理程序调用的,所以对于eclipse生成的工程,你可以去掉XML中有关Activity窗口的声明,同时资源文件里你也可以去掉layout\main.xml文件和源代码文件夹里的Activit文件。当然,我们的墙纸如果支持自定义设置,那你也是需要Activit,那时你需要定义一个Activit供墙纸设置程序调用,以修改自定义墙纸默认设置。需要注意的是,设置文件需要在我们在/res/文件夹中新建一个名为xml的文件夹,名为livewallpaper.xml,内容为如下:




  1. <?


    xml




    version


    =


    “1.0”




    encoding


    =


    “utf-8”


    ?>







  2. <


    wallpaper




    xmlns:android


    =


    “http://schemas.android.com/apk/res/android”







  3. android:settingsActivity


    =


    “ca.jvsh.livewallpaper.LiveWallpaperSettings”







  4. android:thumbnail


    =


    “@drawable/icon”


    />








然后把设置的值引入到你自己的墙纸类中调用。墙纸设置类一般会派生于PreferenceActivity,以在作用户操作后保存设置内容!


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注