阅读原文:https://www.jianshu.com/p/5a5f95f6cd59
最近搞了一下Android的动态壁纸,像实现“萤火视频桌面”那样,本来以为很难的,但是了解了一下感觉还是很容易的。
Android壁纸
WallpaperService与Engine
壁纸运行在一个Android服务之中,这个服务的名字叫做WallpaperService。当用户选择了一个壁纸之后,此壁纸所对应的WallpaperService便会启动并开始进行壁纸的绘制工作。Engine是WallpaperService中的一个内部类,实现了壁纸窗口的创建以及Surface的维护工作。这一层次的内容主要体现了壁纸的实现原理。
WallpaperManagerService
这个系统服务用于管理壁纸的运行与切换,并通过WallpaperManager类向外界提供操作壁纸的接口。这一层次主要体现了Android对壁纸的管理方式。
WindowManagerService
用于计算壁纸窗口的Z序、可见性以及为壁纸应用窗口动画。这一层次主要体现了Android对壁纸窗口的管理方式。
实现
首先静态壁纸是很简单的,大概就是如下几种方法,我也没有试过,
- 使用WallpaperManager的setResource(int ResourceID)方法
- 使用WallpaperManager的setBitmap(Bitmap bitmap)方法
- 使用WallpaperManager的setStream(InputStream data)方法
1 2 3 4 5 6 7 8 9
|
<uses-permission android:name = "android.permission.SET_WALLPAPER"/> WallpaperManager wallpaperManager = WallpaperManager.getInstance(this); try { wallpaperManager.setResource(R.drawable.picture); } catch (IOException e) { e.printStackTrace(); }
|
动态壁纸
刚才讲了,动态壁纸就是一个服务,我们先创建一个服务并继承WallpaperService。这个服务里面有个内部类Engine,实现了壁纸窗口的创建以及Surface的维护工作。就是说我们可以获取到一个SurfaceHolder,拿到这个东西就好办了,我们可以在上面画自己想要的东西或者把视频输出到上面去。
视频壁纸的实现
代码还是比较简单的,就是壁纸起来的时候播放一下视频,在壁纸不可见时候暂停,再次恢复的时候继续播放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class VideoWallpaper extends WallpaperService { private MediaPlayer mp; @Override public Engine onCreateEngine() { return new VideoEngine(); } class VideoEngine extends Engine { @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); } @Override public void onSurfaceCreated(SurfaceHolder holder) { } @Override public void onVisibilityChanged(boolean visible) { if visible() { } else { } } @Override public void onDestroy() { super.onDestroy(); } } }
|
这里只是展示了部分代码,具体的实现还是要自己在不同的生命周期对视频进行处理,逻辑也是比较简单,和正常的视频播放没什么区别
注册服务
是Service那肯定要注册的
1 2 3 4 5 6 7 8 9 10 11 12
| <service android:name="ui.service.VideoWallpaper" 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/livewallpapervideo" /> </service>
|
然后关于”livewallpapervideo.xml”,就是一个正常的布局文件
1 2 3 4 5 6
| <?xml version="1.0" encoding="utf-8"?> <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:thumbnail="@mipmap/ic_video" android:description="@string/wallpaper_description4" />
|
设置壁纸
调用系统的接口将壁纸服务设置为系统的壁纸服务即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public static void changePaper(Class clazz, Context context) { Intent chooseIntent; chooseIntent = new Intent(); chooseIntent.setFlags(FLAG_ACTIVITY_NEW_TASK); chooseIntent.setAction(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); chooseIntent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(context.getPackageName(), clazz.getCanonicalName())); context.startActivity(chooseIntent); }
|
其他玩法
除了将视频作为壁纸以为还可以将GIF作为壁纸,将摄像头获取到的图象作为壁纸,甚至直接自己在SurfaceHolder自己画东西都可以,道理都是一样的
服务器挂了,可以看看本地壁纸
项目地址:https://github.com/tyhjh/liveWallpaper