• Android动态壁纸的制作教程


    动态壁纸是在Android 2.1新增的一个功能。动态壁纸可以添加到Android的桌面,具有交互式的动画背景效果。在本教程中,我们将教会你如何去制作一个交互式的动态壁纸。

    动态壁纸是一个Android应用程序,包括一个服务(WallpaperService)。该服务必须包括一个引擎(WallpaperService.Engine)。该引擎是连接用户、桌面、系统之间的桥梁。它也可以绘制桌面壁纸。

    首先,必须由内在的Engine类创建一个WallpaperService类。该服务必须在AndroidManifest.xml中声明为"android.service.wallpaper.WallpaperService",这样它才会作为动态壁纸被手机识别。而且还要在服务配置中附加"android.permission.BIND_WALLPAPER"的权限许可:

    <service
        android:name="LiveWallpaperService"
        android:enabled="true"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:permission="android.permission.BIND_WALLPAPER">

        <intent-filter android:priority="1" >
            <action android:name="android.service.wallpaper.WallpaperService" />
        </intent-filter>
        <meta-data
          android:name="android.service.wallpaper"
          android:resource="@xml/wallpaper" />

    </service>

    创建一个XML文件,放置在应用程序目录下的/res/xml/中。它用来描述你的动态壁纸。

    <?xml version="1.0" encoding="UTF-8"?>

    <wallpaper
        xmlns:android="http://schemas.android.com/apk/res/android
        android:thumbnail="@drawable/thumbnail"
        android:description="@string/description"
        android:settingsActivity="PreferenceActivity"/>

    再创建一个xml的属性文件 attrs.xml ,代码如下:

    <declare-styleable name="Wallpaper">
        <!-- Component name of an activity that allows the user to modify
             the current settings for this wallpaper. -->
        <attr name="settingsActivity" />
     
        <!-- Reference to a the wallpaper's thumbnail bitmap. -->

        <attr name="thumbnail" format="reference" />
     
        <!-- Name of the author of this component, e.g. Google. -->
        <attr name="author" format="reference" />

     
        <!-- Short description of the component's purpose or behavior. -->
        <attr name="description" />
    </declare-styleable>

    动态壁纸的服务代码如下

    package net.androgames.blog.sample.livewallpaper;
     
    import android.content.SharedPreferences;
    import android.service.wallpaper.WallpaperService;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
     
    /**
     * Android Live Wallpaper Archetype
     * 
    @author antoine vianey
     * under GPL v3 : 
    http://www.gnu.org/licenses/gpl-3.0.html
     
    */
    public class LiveWallpaperService extends WallpaperService {
     
        @Override
        public Engine onCreateEngine() {
            return new SampleEngine();
        }
     
        @Override
        public void onCreate() {
            super.onCreate();
        }
     
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
     
        public class SampleEngine extends Engine {
     
            private LiveWallpaperPainting painting;
     
            SampleEngine() {
                SurfaceHolder holder = getSurfaceHolder();
                painting = new LiveWallpaperPainting(holder, 
                    getApplicationContext());
            }
     
            @Override
            public void onCreate(SurfaceHolder surfaceHolder) {
                super.onCreate(surfaceHolder);
                // register listeners and callbacks here
                setTouchEventsEnabled(true);
            }
     
            @Override
            public void onDestroy() {
                super.onDestroy();
                // remove listeners and callbacks here
                painting.stopPainting();
            }
     
            @Override
            public void onVisibilityChanged(boolean visible) {
                if (visible) {
                    // register listeners and callbacks here
                    painting.resumePainting();
                } else {
                    // remove listeners and callbacks here
                    painting.pausePainting();
                }
            }
     
            @Override
            public void onSurfaceChanged(SurfaceHolder holder, int format, 
                    int width, int height) {
                super.onSurfaceChanged(holder, format, width, height);
                painting.setSurfaceSize(width, height);
            }
     
            @Override
            public void onSurfaceCreated(SurfaceHolder holder) {
                super.onSurfaceCreated(holder);
                // start painting
                painting.start();
            }
     
            @Override
            public void onSurfaceDestroyed(SurfaceHolder holder) {
                super.onSurfaceDestroyed(holder);
                boolean retry = true;
                painting.stopPainting();
                while (retry) {
                    try {
                        painting.join();
                        retry = false;
                    } catch (InterruptedException e) {}
                }
            }
     
            @Override
            public void onOffsetsChanged(float xOffset, float yOffset, 
                    float xStep, float yStep, int xPixels, int yPixels) {
            }
     
            @Override
            public void onTouchEvent(MotionEvent event) {
                super.onTouchEvent(event);
                painting.doTouchEvent(event);
            }
     
        }
     
    }

    当壁纸的显示、状态或大小变化是,会调用Engine的onCreate, onDestroy, onVisibilityChanged, onSurfaceChanged, onSurfaceCreatedonSurfaceDestroyed方法。有了这些方法,动态壁纸才能展现出动画效果。而通过设置setTouchEventsEnabled(true),并且调用onTouchEvent(MotionEvent event)方法,来激活触摸事件。

    我们在绘画墙纸的时候,也会使用一个单独的绘画线程

    package net.androgames.blog.sample.livewallpaper;
     
    import android.content.Context;
    import android.graphics.Canvas;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
     
    /**
     * Android Live Wallpaper painting thread Archetype
     * 
    @author antoine vianey
     * GPL v3 : 
    http://www.gnu.org/licenses/gpl-3.0.html
     
    */
    public class LiveWallpaperPainting extends Thread {
     
        /** Reference to the View and the context */
        private SurfaceHolder surfaceHolder;
        private Context context;
     
        /** State */
        private boolean wait;
        private boolean run;
     
        /** Dimensions */
        private int width;
        private int height;
     
        /** Time tracking */
        private long previousTime;
        private long currentTime;
     
        public LiveWallpaperPainting(SurfaceHolder surfaceHolder, 
                Context context) {
            // keep a reference of the context and the surface
            
    // the context is needed if you want to inflate
            
    // some resources from your livewallpaper .apk
            this.surfaceHolder = surfaceHolder;
            this.context = context;
            // don't animate until surface is created and displayed
            this.wait = true;
        }
     
        /**
         * Pauses the live wallpaper animation
         
    */
        public void pausePainting() {
            this.wait = true;
            synchronized(this) {
                this.notify();
            }
        }
     
        /**
         * Resume the live wallpaper animation
         
    */
        public void resumePainting() {
            this.wait = false;
            synchronized(this) {
                this.notify();
            }
        }
     
        /**
         * Stop the live wallpaper animation
         
    */
        public void stopPainting() {
            this.run = false;
            synchronized(this) {
                this.notify();
            }
        }
     
        @Override
        public void run() {
            this.run = true;
            Canvas c = null;
            while (run) {
                try {
                    c = this.surfaceHolder.lockCanvas(null);
                    synchronized (this.surfaceHolder) {
                        currentTime = System.currentTimeMillis();
                        updatePhysics();
                        doDraw(c);
                        previousTime = currentTime;
                    }
                } finally {
                    if (c != null) {
                        this.surfaceHolder.unlockCanvasAndPost(c);
                    }
                }
                // pause if no need to animate
                synchronized (this) {
                    if (wait) {
                        try {
                            wait();
                        } catch (Exception e) {}
                    }
                }
            }
        }
     
        /**
         * Invoke when the surface dimension change
         
    */
        public void setSurfaceSize(int width, int height) {
            this.width = width;
            this.height = height;
            synchronized(this) {
                this.notify();
            }
        }
     
        /**
         * Invoke while the screen is touched
         
    */
        public void doTouchEvent(MotionEvent event) {
            // handle the event here
            
    // if there is something to animate
            
    // then wake up
            this.wait = false;
            synchronized(this) {
                notify();
            }
        }
     
        /**
         * Do the actual drawing stuff
         
    */
        private void doDraw(Canvas canvas) {}
     
        /**
         * Update the animation, sprites or whatever.
         * If there is nothing to animate set the wait
         * attribute of the thread to true
         
    */
        private void updatePhysics() {
            // if nothing was updated :
            
    // this.wait = true;
        }
     
    }

    如果桌面壁纸是可见状态下,系统服务通知有新的东西,这个类会优先把它绘制在画布上。如果没有动画了,updatePhysics会通知线程去等待。通常SurfaceView在有两个画布交替绘制的时候,会在画布上绘制上一次......

    如果要让你的动态墙纸有配置功能,只要创建一个PreferenceActivity,并将它在wallpaper.xml文件中声明。同时让SharedPreference对象可以找到你的配置选项。

    教程就写到这里,如果还有什么不懂,你可以通过Eclipse来浏览完整的源代码:SampleLiveWallpaper

  • 相关阅读:
    根据snort规则写openvas nasl 攻击 脚本
    snort规则中tcp/udp端口的具体作用
    snort规则头解析
    正则匹配中的特殊案例
    snort 规则 byte_test 不同运算符命中条件
    Linux中tar命令的一些用法
    Thymeleaf传递url参数
    PO BO VO DTO POJO DAO DO 令人迷惑的Java概念
    linux中多个命令连接符— ; && || ()
    遇见了count(1)这种写法,什么意思?
  • 原文地址:https://www.cnblogs.com/zziss/p/2380704.html
Copyright © 2020-2023  润新知