• android 动态壁纸开发


    转:http://www.eoeandroid.com/thread-100389-1-1.html

    android 动态壁纸开发
    参考:http://www.ophonesdn.com/article/show/278
    推荐:http://www.oschina.net/code/snippet_203635_7426
    http://blog.csdn.net/homebei2/article/details/6079580
    resources/articles/live-wallpapers.html

    自己做了一个非常简单的 只是想了解过程 源码见附件 步骤如下:

    1、新建一个Android工程  然后进入工程的/res/文件夹,删除layout这个文件夹,当然里面的main.xml也会被删除的,对于Live Wallpaper来说传统的布局文件是不需要的。

    2、在res下面新建一个xml文件夹 然后新建一个mylivewallpaper.xml 内容如下:

    Java代码

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <wallpaper xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:thumbnail="@drawable/icon"  
    4. />  
    复制代码

    这里的android:thumbnail值得是你这个动态壁纸的小图标 会在你选着动态壁纸的时候出现 如下图:



    这个可以自己选一个好看一点的

    3、开始编写代码了  直接看吧

    Java代码

    1. package com.lp.wallpaper;  
    2.   
    3. import java.text.SimpleDateFormat;  
    4. import java.util.Date;  
    5.   
    6. import android.graphics.Canvas;  
    7. import android.graphics.Color;  
    8. import android.graphics.Paint;  
    9. import android.os.Bundle;  
    10. import android.os.Handler;  
    11. import android.service.wallpaper.WallpaperService;  
    12. import android.view.MotionEvent;  
    13. import android.view.SurfaceHolder;  
    14.   
    15. public class MyWallpaper extends WallpaperService{  
    16.     private Handler handler = new Handler();  
    17.       
    18.       
    19.       
    20.     @Override  
    21.     public void onCreate() {  
    22.         System.out.println("service onCreate");  
    23.         super.onCreate();  
    24.     }  
    25.   
    26.     @Override  
    27.     public void onDestroy() {  
    28.         System.out.println("service onDestory");  
    29.         super.onDestroy();  
    30.     }  
    31.   
    32.     @Override  
    33.     public Engine onCreateEngine() {  
    34.         System.out.println("service onCreateEngine");  
    35.         return new MyEngine();  
    36.     }  
    37.       
    38.     private class MyEngine extends Engine{  
    39.          
    40.         private float x = 200;  
    41.         private float y = 300;  
    42.         private Paint mPaint;  
    43.         private boolean mVisible = false;  
    44.          
    45.         private Runnable drawThread = new Runnable() {  
    46.             public void run() {  
    47.                 drawWallpaper();  
    48.             }  
    49.         };  
    50.          
    51.         public MyEngine(){  
    52.             System.out.println("MyEngine");  
    53.             mPaint = new Paint();  
    54.             mPaint.setColor(Color.RED);  
    55.             mPaint.setAntiAlias(true);  
    56.             mPaint.setStrokeWidth(4);  
    57.             mPaint.setStyle(Paint.Style.STROKE);  
    58.             mPaint.setTextSize(24);  
    59.         }  
    60.   
    61.         @Override  
    62.         public Bundle onCommand(String action, int x, int y, int z, Bundle extras, boolean resultRequested) {  
    63.             // TODO Auto-generated method stub  
    64.             System.out.println("onCommand");  
    65.             return super.onCommand(action, x, y, z, extras, resultRequested);  
    66.         }  
    67.   
    68.         @Override  
    69.         public void onCreate(SurfaceHolder surfaceHolder) {  
    70.             System.out.println("onCreate");  
    71.             super.onCreate(surfaceHolder);  
    72.             //作用是使壁纸能响应touch event,默认是false  
    73.             setTouchEventsEnabled(true);  
    74.         }  
    75.   
    76.         @Override  
    77.         public void onDestroy() {  
    78.             System.out.println("onDestroy");  
    79.             super.onDestroy();  
    80.             handler.removeCallbacks(drawThread);  
    81.         }  
    82.   
    83.         @Override  
    84.         public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {  
    85.             // TODO Auto-generated method stub  
    86.             System.out.println("onoffsetsChanged");  
    87.             super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);  
    88.         }  
    89.          
    90.         @Override  
    91.         public void onVisibilityChanged(boolean visible) {  
    92.             System.out.println("onVisibilityChanged");  
    93.             mVisible = visible;  
    94.             if (visible) {  
    95.                 //开始  
    96.                 handler.postDelayed(drawThread, 50);  
    97.             } else {  
    98.                 handler.removeCallbacks(drawThread);  
    99.             }  
    100.         }  
    101.   
    102.         @Override  
    103.         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
    104.             System.out.println("onSurfaceChanged");  
    105.             // TODO Auto-generated method stub  
    106.             super.onSurfaceChanged(holder, format, width, height);  
    107.         }  
    108.   
    109.         @Override  
    110.         public void onSurfaceCreated(SurfaceHolder holder) {  
    111.             System.out.println("onSurfaceCreated");  
    112.             super.onSurfaceCreated(holder);  
    113.         }  
    114.   
    115.         @Override  
    116.         public void onSurfaceDestroyed(SurfaceHolder holder) {  
    117.             System.out.println("onSurfaceDestoryed");  
    118.             // TODO Auto-generated method stub  
    119.             super.onSurfaceDestroyed(holder);  
    120.             handler.removeCallbacks(drawThread);  
    121.         }  
    122.   
    123.         @Override  
    124.         public void onTouchEvent(MotionEvent event) {  
    125.             System.out.println("onTouchEvent");  
    126.             // TODO Auto-generated method stub  
    127.             super.onTouchEvent(event);  
    128.         }  
    129.          
    130.          
    131.         private void drawWallpaper() {  
    132.               
    133.             SurfaceHolder holder = getSurfaceHolder();  
    134.             Canvas canvas = holder.lockCanvas();  
    135.             drawTime(canvas);  
    136.             holder.unlockCanvasAndPost(canvas);  
    137.               
    138.             //循环执行  
    139.             handler.postDelayed(drawThread, 50);  
    140.         }  
    141.   
    142.         private void drawTime(Canvas canvas) {  
    143.             Date date = new Date(System.currentTimeMillis());  
    144.             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");  
    145.             String dataStr = sdf.format(date);  
    146.             canvas.save();  
    147.             canvas.drawColor(0xff00ff00);  
    148.             canvas.drawText(dataStr, x, y, mPaint);  
    149.             canvas.restore();  
    150.         }  
    151.     }  
    152.   
    153. }  
    复制代码

    实现的效果是一个动态改变的时间 如下图:



    我们一一来解释:
    onCreateEngine() :

    启动一个WallpaperService.Engine 这个engine才是负责绘制壁纸以及响应与用户交互事件的核心部件 这个方法也是必须要重写的 并且是WallpaperService和service的主要区别

    onOffsetsChanged():

    这个一般在几个屏幕滑动的时候调用 而且 当你拖动A屏幕向B屏幕过度时 会随着B屏幕的显示面积的变大或者变小一直调用这个方法

    onVisibilityChanged()

    这个是屏幕显示或者不显示的时候调用的 必须完全覆盖屏幕才会调用

    onCommand()

    可以给壁纸发送一些命令 让其执行

    onTouchEvent()
    处理壁纸的点击时间的

    setTouchEventsEnabled(true)

    作用是使壁纸能响应touch event,默认是false

    其他的看名字应该就知道了 呵呵

    这里也说下Engine的惯用写法吧

    Java代码

    1. private class MyEngine extends Engine{  
    2.         //这里定义一个线程  
    3.         private Runnable drawThread = new Runnable() {  
    4.             public void run() {  
    5.                 drawWallpaper();  
    6.             }  
    7.         };  
    8.         //构造方法里面 一般初始化Paint对象  
    9.         public MyEngine(){  
    10.             System.out.println("MyEngine");  
    11.             mPaint = new Paint();  
    12.             mPaint.setColor(Color.RED);  
    13.             mPaint.setAntiAlias(true);  
    14.             mPaint.setStrokeWidth(4);  
    15.             mPaint.setStyle(Paint.Style.STROKE);  
    16.             mPaint.setTextSize(24);  
    17.         }  
    18.   
    19.                 //这里 调用setTouchEventsEnabled(true);即可  
    20.         @Override  
    21.         public void onCreate(SurfaceHolder surfaceHolder) {  
    22.             System.out.println("onCreate");  
    23.             super.onCreate(surfaceHolder);  
    24.             //作用是使壁纸能响应touch event,默认是false  
    25.             setTouchEventsEnabled(true);  
    26.         }  
    27.                 //取消callback  
    28.         @Override  
    29.         public void onDestroy() {  
    30.             System.out.println("onDestroy");  
    31.             super.onDestroy();  
    32.             handler.removeCallbacks(drawThread);  
    33.         }  
    34.                 //当显示的时候 绑定callback 不显示时  取消callback         
    35.         @Override  
    36.         public void onVisibilityChanged(boolean visible) {  
    37.             System.out.println("onVisibilityChanged");  
    38.             mVisible = visible;  
    39.             if (visible) {  
    40.                 //开始  
    41.                 handler.postDelayed(drawThread, 50);  
    42.             } else {  
    43.                 handler.removeCallbacks(drawThread);  
    44.             }  
    45.         }  
    46.   
    47.         @Override  
    48.         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
    49.             System.out.println("onSurfaceChanged");  
    50.             // TODO Auto-generated method stub  
    51.             super.onSurfaceChanged(holder, format, width, height);  
    52.         }  
    53.   
    54.         @Override  
    55.         public void onSurfaceCreated(SurfaceHolder holder) {  
    56.             System.out.println("onSurfaceCreated");  
    57.             super.onSurfaceCreated(holder);  
    58.         }  
    59.                  //取消callback  
    60.         @Override  
    61.         public void onSurfaceDestroyed(SurfaceHolder holder) {  
    62.             System.out.println("onSurfaceDestoryed");  
    63.             // TODO Auto-generated method stub  
    64.             super.onSurfaceDestroyed(holder);  
    65.             handler.removeCallbacks(drawThread);  
    66.         }  
    67.                 //处理点击事件 比如说 点击时 出现水波等  
    68.         @Override  
    69.         public void onTouchEvent(MotionEvent event) {  
    70.             System.out.println("onTouchEvent");  
    71.             // TODO Auto-generated method stub  
    72.             super.onTouchEvent(event);  
    73.         }  
    74.          
    75.         //得到surfaceholder和canvas 并调用核心处理方法  
    76.         private void drawWallpaper() {  
    77.               
    78.             SurfaceHolder holder = getSurfaceHolder();  
    79.             Canvas canvas = holder.lockCanvas();  
    80.             drawTime(canvas);  
    81.             holder.unlockCanvasAndPost(canvas);  
    82.               
    83.             //循环执行  
    84.             handler.postDelayed(drawThread, 50);  
    85.         }  
    86.                 //核心处理方法  
    87.         private void drawTime(Canvas canvas) {  
    88.               
    89.         }  
    90.     }  
    复制代码

    4、在AndroidManifes.xml里面注册service

    Java代码

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    3.       package="com.lp.wallpaper">  
    4.     <uses-sdk android:minSdkVersion="7" />  
    5.     <uses-feature android:name="android.software.live_wallpaper" />  
    6.   
    7.     <application   
    8.         android:icon="@drawable/icon"   
    9.         android:label="@string/app_name">  
    10.       
    11.         <service   
    12.             android:label="@string/app_name"  
    13.             android:name=".MyWallpaper"  
    14.             android:permission="android.permission.BIND_WALLPAPER">  
    15.             <intent-filter>  
    16.                 <action android:name="android.service.wallpaper.WallpaperService" />   
    17.             </intent-filter>  
    18.             <meta-data android:name="android.service.wallpaper" android:resource="@xml/mylivewallpaper" />      
    19.         </service>  
    20.   
    21.     </application>  
    22. </manifest>  
    复制代码

    除了

    1. android:resource="@xml/mylivewallpaper"  
    复制代码

    是可以自己修改 其他的都是必须得 特别强调几个:

    1. <uses-sdk android:minSdkVersion="7" />  
    2. <uses-feature android:name="android.software.live_wallpaper" />  
    3. android:permission="android.permission.BIND_WALLPAPER"  
    复制代码

    5、自己的一些关于方法执行顺序的测试信息:
    当进入改壁纸的设置页面 但是还没有设置时
    09-21 07:55:05.575: INFO/System.out(1337): service onCreate
    09-21 07:55:05.614: INFO/System.out(1337): service onCreateEngine
    09-21 07:55:05.634: INFO/System.out(1337): MyEngine
    09-21 07:55:05.663: INFO/System.out(1337): onCreate
    09-21 07:55:05.746: INFO/System.out(1337): onSurfaceCreated
    09-21 07:55:05.753: INFO/System.out(1337): onSurfaceChanged
    09-21 07:55:05.785: INFO/System.out(1337): onVisibilityChanged

    当点击设置壁纸按钮后
    09-21 07:55:19.434: INFO/System.out(1337): onTouchEvent
    09-21 07:55:19.574: INFO/System.out(1337): onTouchEvent
    09-21 07:55:20.283: INFO/System.out(1337): service onCreateEngine
    09-21 07:55:20.294: INFO/System.out(1337): MyEngine
    09-21 07:55:20.304: INFO/System.out(1337): onCreate
    09-21 07:55:20.414: INFO/System.out(1337): onSurfaceCreated
    09-21 07:55:20.424: INFO/System.out(1337): onSurfaceChanged
    09-21 07:55:20.443: INFO/System.out(1337): onVisibilityChanged
    09-21 07:55:20.443: INFO/System.out(1337): onoffsetsChanged
    09-21 07:55:20.863: INFO/System.out(1337): onVisibilityChanged
    09-21 07:55:21.305: INFO/System.out(1337): onSurfaceDestoryed
    09-21 07:55:21.333: INFO/System.out(1337): onDestroy

    在壁纸上面点击
    09-21 07:55:34.654: INFO/System.out(1337): onTouchEvent
    09-21 07:55:34.754: INFO/System.out(1337): onTouchEvent
    09-21 07:55:34.754: INFO/System.out(1337): onCommand

    启动其他程序 完全覆盖屏幕
    09-21 07:56:03.855: INFO/System.out(1337): onTouchEvent
    09-21 07:56:03.884: INFO/System.out(1337): onTouchEvent
    09-21 07:56:04.494: INFO/System.out(1337): onVisibilityChanged

    设置其他壁纸 代替自己的壁纸
    09-21 07:56:34.893: INFO/System.out(1337): onSurfaceDestoryed
    09-21 07:56:34.893: INFO/System.out(1337): onDestroy
    09-21 07:56:34.953: INFO/System.out(1337): service onDestory

  • 相关阅读:
    使用两个路由器扩展家庭无线网络
    RX(Reactive Extinsion)和IX(Interactive Extinsion)库改名了
    WPF绘制矢量图形模糊的问题
    WPF的二维绘图(二)——几何图形Geometry
    一个C#语法高亮插件
    WPF的二维绘图(一)——DrawingContext
    在.net桌面程序中自定义鼠标光标
    在WebAPI中自动创建Controller
    解决OneNote的无法同步的问题
    使用NuGet Package Project快速制作NuGet包
  • 原文地址:https://www.cnblogs.com/leihupqrst/p/3978085.html
Copyright © 2020-2023  润新知