android动态壁纸LiveWallpaper用法

原文地址:http://blog.csdn.net/oldmtn/article/details/9177123


学习到的知识总结:

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

[html] view plain copy
 print?
  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.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="8"  
  9.         android:targetSdkVersion="16" />  
  10.   
  11.     <application  
  12.         android:allowBackup="true"  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.         <service  
  17.             android:name="com.example.testlivewallpaper.Wallpaper"  
  18.             android:label="@string/service_name"  
  19.             android:permission="android.permission.BIND_WALLPAPER" >  
  20.             <intent-filter>  
  21.                 <action android:name="android.service.wallpaper.WallpaperService" />  
  22.             </intent-filter>  
  23.   
  24.             <meta-data  
  25.                 android:name="android.service.wallpaper"  
  26.                 android:resource="@xml/wallpaper" />  
  27.         </service>  
  28.     </application>  
  29.   
  30. </manifest>  

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

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

我这里为:

[html] view plain copy
 print?
  1. <meta-data  
  2.     android:name="android.service.wallpaper"  
  3.     android:resource="@xml/wallpaper" />  
其中wallpaper内容为:

[html] view plain copy
 print?
  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是用来设置当前动态壁纸可见时显示动画。当其不可见时,壁纸会停止运行,不显示动画,代码如下:

[java] view plaincopy
  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是我写的一个简单的根据随机数画线的函数,代码如下:

[java] view plaincopy
  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回调里,代码如下:

[java] view plaincopy
  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.         };  


完整的代码如下“:

[java] view plaincopy
  1. package com.androidbook.simplelivewallpaper;  
  2.   
  3. import java.util.Random;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.graphics.Path;  
  8. import android.graphics.Paint.Style;  
  9. import android.os.Handler;  
  10. import android.service.wallpaper.WallpaperService;  
  11. import android.view.MotionEvent;  
  12. import android.view.SurfaceHolder;  
  13.   
  14. public class SimpleDroidWallpaper extends WallpaperService {  
  15.     // private static final String DEBUG_TAG = "SimpleDroidWallpaper";  
  16.     private final Handler handler = new Handler();  
  17.   
  18.     @Override  
  19.     public Engine onCreateEngine() {  
  20.         return new SimpleWallpaperEngine();  
  21.     }  
  22.   
  23.     class SimpleWallpaperEngine extends WallpaperService.Engine {  
  24.   
  25.         boolean canDraw = true;  
  26.         private int virtualHeight;  
  27.         private int virtualWidth;  
  28.         Paint paint = new Paint();  
  29.         Path m_path = new Path();  
  30.         volatile int ox = 0, oy = 0, nx = 100, ny = 200;  
  31.         final Random rand = new Random();  
  32.   
  33.         private final Runnable drawRequest = new Runnable() {  
  34.             @Override  
  35.             public void run() {  
  36.                 try {  
  37.                     Thread.sleep(1000);  
  38.                     drawDroid();  
  39.                 } catch (InterruptedException e) {  
  40.                     // TODO Auto-generated catch block  
  41.                     e.printStackTrace();  
  42.                 }  
  43.             }  
  44.         };  
  45.   
  46.         public SimpleWallpaperEngine() {  
  47.             m_path.lineTo(ox, oy);  
  48.         }  
  49.   
  50.         @Override  
  51.         public void onCreate(SurfaceHolder surfaceHolder) {  
  52.             super.onCreate(surfaceHolder);  
  53.             // When touch is enable, all MotionEvents are passed, even those  
  54.             // handled by other widgets  
  55.             setTouchEventsEnabled(true);  
  56.             virtualHeight = getDesiredMinimumHeight();  
  57.             virtualWidth = getDesiredMinimumWidth();  
  58.         }  
  59.   
  60.         @Override  
  61.         public void onDestroy() {  
  62.             super.onDestroy();  
  63.             handler.removeCallbacks(drawRequest);  
  64.         }  
  65.   
  66.         @Override  
  67.         public void onVisibilityChanged(boolean visible) {  
  68.             canDraw = visible;  
  69.             if (visible) {  
  70.                 drawDroid(); // 自己的绘屏函数  
  71.             } else {  
  72.                 handler.removeCallbacks(drawRequest); // 不可见时,移除回调  
  73.             }  
  74.         }  
  75.   
  76.         @Override  
  77.         public void onOffsetsChanged(float xOffset, float yOffset,  
  78.                 float xOffsetStep, float yOffsetStep, int xPixelOffset,  
  79.                 int yPixelOffset) {  
  80.             super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,  
  81.                     xPixelOffset, yPixelOffset);  
  82.         }  
  83.   
  84.         @Override  
  85.         public void onSurfaceCreated(SurfaceHolder holder) {  
  86.             super.onSurfaceCreated(holder);  
  87.         }  
  88.   
  89.         @Override  
  90.         public void onSurfaceChanged(SurfaceHolder holder, int format,  
  91.                 int width, int height) {  
  92.             super.onSurfaceChanged(holder, format, width, height);  
  93.   
  94.             drawDroid();  
  95.         }  
  96.   
  97.         @Override  
  98.         public void onSurfaceDestroyed(SurfaceHolder holder) {  
  99.             super.onSurfaceDestroyed(holder);  
  100.             canDraw = false;  
  101.             handler.removeCallbacks(drawRequest);  
  102.         }  
  103.   
  104.         private void drawDroid() {  
  105.             final SurfaceHolder holder = getSurfaceHolder();  
  106.             Canvas canvas = null;  
  107.             try {  
  108.                 canvas = holder.lockCanvas();  
  109.                 if (canvas != null) {  
  110.                     paint.setColor(Color.BLUE);  
  111.                     paint.setStrokeWidth(10);  
  112.                     paint.setStyle(Style.STROKE);  
  113.                     nx = (int) (rand.nextFloat() * virtualWidth);  
  114.                     ny = (int) (rand.nextFloat() * virtualHeight);  
  115.                     m_path.lineTo(nx, ny);  
  116.                     canvas.drawPath(m_path, paint);  
  117.                 }  
  118.             } finally {  
  119.                 if (canvas != null) {  
  120.                     holder.unlockCanvasAndPost(canvas);  
  121.                 }  
  122.             }  
  123.             handler.removeCallbacks(drawRequest);  
  124.             if (canDraw) {  
  125.                 handler.postDelayed(drawRequest, 33);  
  126.             }  
  127.         }  
  128.   
  129.         @Override  
  130.         public void onTouchEvent(MotionEvent event) {  
  131.             /* 添加触屏效果 */  
  132.             super.onTouchEvent(event);  
  133.         }  
  134.     }  
  135. }  

完整的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,内容为如下:

[html] view plaincopy
  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,以在作用户操作后保存设置内容!

你可能感兴趣的:(livewallpaper)