Android 静态 / 动态壁纸(Live wallpaper)开发 - WallpaperService

5,698 阅读2分钟

开发背景

最近,接到壁纸开发的需求;之前未接触过,感觉系统应该有相应的接口;产品当时给我的竞品案例,壁纸上居然可以有控件,当时我就有点懵逼,人家是Open GL做的;通过自己简单百度+Google之后,发现很多都是静态壁纸,最后才知道动态壁纸是通过Canvas不断的绘制实现,这也是动态壁纸耗电的原因;今天,先介绍简单的静态壁纸的实现,然后介绍动态壁纸的实现,最后把你们可能会遇到的问题简单罗列一下,没有涉及到的请谅解,可直接左边QQ私聊;不扯淡了,回到今天的主题。

先上效果图:
此处输入图片的描述

静态壁纸

设置静态壁纸,壁纸的切换都是渐变动画切换,不会有任何的界面跳转和弹窗出现,或许你干点回事,都不知道谁干的,哈哈,开个玩笑…看具体栗子吧,不爽就@我

1.使用Bitmap做为壁纸

举栗子:

    WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
    try {
        Bitmap wallpaperBitmap = BitmapFactory.decodeResource(getResources(), R.raw.girl);
        wallpaperManager.setBitmap(wallpaperBitmap);
    } catch (IOException e) {
        e.printStackTrace();
    }

上面的栗子是目前推荐的静态壁纸的设置方式。WallpaperManager是系统提供,非个人封装,O(∩_∩)O哈哈~。
其它方式:
在集成ContextWrapper的类中直接使用,例如:Activity中设置壁纸

setWallpaper(wallpaperBitmap);
或
setWallpaper(getResources().openRawResource(R.raw.girl));

不过,此方法已过时。
还有一些Api 24设置壁纸的api,使用需做版本的判断。

2.使用资源文件做为壁纸

举栗子:

    WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
    try {
        wallpaperManager.setResource(R.raw.wallpaper);
    } catch (IOException e) {
        e.printStackTrace();
    }

壁纸分系统壁纸和锁屏壁纸,Api接口是有,但是是API 24才能使用,不过还是的给个例子,主要是第二个参数which:

    WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //WallpaperManager.FLAG_LOCK  WallpaperManager.FLAG_SYSTEM
            wallpaperManager.setResource(R.raw.wallpaper, WallpaperManager.FLAG_SYSTEM);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

3.清除壁纸

举栗子:

    WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
    try {
        wallpaperManager.clear();
    } catch (IOException e) {
        e.printStackTrace();
    }

其它方式:
在集成ContextWrapper的类中直接使用,例如:Activity中设置壁纸

clearWallpaper();

不过,此方法已过时。

设置壁纸需添加壁纸的权限:

<uses-permission android:name="android.permission.SET_WALLPAPER" />

清除壁纸需添加设置权限:

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

总是要什么权限给什么权限……

动态壁纸

1.首先创建一个壁纸Service(LiveWallpaperService),继承WallpaperService
2.在LiveWallpaperService中创建一个引擎(LiveWallpaperEngine),继承LiveWallpaperService.Engine
3.在LiveWallpaperService的onCreateEngine方法中,返回LiveWallpaperEngine的实例
4.在AndroidManifest添加Service

<service
        android:name=".service.LiveWallpaperService"
        android:enabled="true"
        android:label="@string/wallpaper_name"
        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/my_wallpaper" />
    </service>

动态壁纸的具体实现,请看代码。

如果你的图片资源在SDCard上,记得添加读写权限。

源码:https://github.com/coolspan/LiveWallpaper

欢迎Star,O(∩_∩)O哈哈~

可能会遇到的问题:

1.

Caused by: java.lang.SecurityException: Access denied to process: 30404, must have permission android.permission.SET_WALLPAPER

解决方法:这个问题很简单,添加对应的权限即可。

2.

Caused by: java.lang.SecurityException: Permission denial: writing to settings requires android.permission.WRITE_SETTINGS

解决方法:同上。