设置动态壁纸不起作用

发布于 2024-11-17 18:22:48 字数 8110 浏览 4 评论 0原文

我已经问过这个问题,但它已迁移到 android.stackexchange.com 并在那里作为题外话关闭。 所以我们再次开始:

我制作了一个简单的动态壁纸。在预览中我可以看到它,但如果我尝试将其设置为我的动态壁纸,Android 会保留旧壁纸。

有什么想法吗?

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.localfotos"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

  <uses-feature android:name="android.software.live_wallpaper" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <service android:name=".MyWallpaperService"
            android:label="@string/app_name"
            android:icon="@drawable/icon">

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

        </service>

    </application>
</manifest>

livewallpaper.xml

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
/>

MyWallpaperService.java

package com.localfotos;

import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class MyWallpaperService extends WallpaperService {

    @Override
    public Engine onCreateEngine() {
        return new MyEngine();
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public class MyEngine extends Engine {

        private MyWallpaperPainting painting;

        MyEngine() {
            SurfaceHolder holder = getSurfaceHolder();
            painting = new MyWallpaperPainting(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);
        }

    }

}

MyWallpaperPainting.java

package com.localfotos;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class MyWallpaperPainting extends Thread {
    private static final String TAG = "MyWallpaperPainting";


    /** 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 MyWallpaperPainting(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) {}
                }
            }

        synchronized (this){    
            try{
                wait(1000);
            }catch (InterruptedException 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
         */

          Paint mPaint = new Paint();
          mPaint.setDither(true);
          mPaint.setColor(0xFFFFFF00);
          mPaint.setStyle(Paint.Style.STROKE);
          mPaint.setStrokeJoin(Paint.Join.ROUND);
          mPaint.setStrokeCap(Paint.Cap.ROUND);
          mPaint.setStrokeWidth(3);

          Path path = new Path();
          path.lineTo(10, 100);

          canvas.drawColor(0xFFFFFF00);

          Log.d(TAG, "doDraw");

    }

    private void updatePhysics() {
        // if nothing was updated :
        // this.wait = true;
    }

}

I already asked this, but it was migrated to android.stackexchange.com and closed there as offtopic.
So here we go again:

I made a simple live wallpaper. On the preview I can see it but if I try to set it as my live wallpaper Android keeps the old wallpaper there.

Any ideas?

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.localfotos"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

  <uses-feature android:name="android.software.live_wallpaper" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <service android:name=".MyWallpaperService"
            android:label="@string/app_name"
            android:icon="@drawable/icon">

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

        </service>

    </application>
</manifest>

livewallpaper.xml

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
/>

MyWallpaperService.java

package com.localfotos;

import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class MyWallpaperService extends WallpaperService {

    @Override
    public Engine onCreateEngine() {
        return new MyEngine();
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public class MyEngine extends Engine {

        private MyWallpaperPainting painting;

        MyEngine() {
            SurfaceHolder holder = getSurfaceHolder();
            painting = new MyWallpaperPainting(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);
        }

    }

}

MyWallpaperPainting.java

package com.localfotos;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class MyWallpaperPainting extends Thread {
    private static final String TAG = "MyWallpaperPainting";


    /** 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 MyWallpaperPainting(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) {}
                }
            }

        synchronized (this){    
            try{
                wait(1000);
            }catch (InterruptedException 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
         */

          Paint mPaint = new Paint();
          mPaint.setDither(true);
          mPaint.setColor(0xFFFFFF00);
          mPaint.setStyle(Paint.Style.STROKE);
          mPaint.setStrokeJoin(Paint.Join.ROUND);
          mPaint.setStrokeCap(Paint.Cap.ROUND);
          mPaint.setStrokeWidth(3);

          Path path = new Path();
          path.lineTo(10, 100);

          canvas.drawColor(0xFFFFFF00);

          Log.d(TAG, "doDraw");

    }

    private void updatePhysics() {
        // if nothing was updated :
        // this.wait = true;
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

执手闯天涯 2024-11-24 18:22:48

您的清单缺少 BIND_WALLPAPER 权限。请参阅 SDK 中的 Cube 示例。

android:permission="android.permission.BIND_WALLPAPER">

Your manifest is missing the BIND_WALLPAPER permission. See the Cube example in the SDK.

android:permission="android.permission.BIND_WALLPAPER">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文