Android动态壁纸实现

Android动态壁纸实现

阅读原文: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;

//这里就是返回我们自定义的Engine
@Override
public Engine onCreateEngine() {
return new VideoEngine();
}
//自定义Engine
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 -->
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<!-- 为动态壁纸配置meta-data -->
<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
/**
* 设置壁纸
*
* @param clazz 壁纸服务的类
* @param context
*/
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

作者

Tyhj

发布于

2020-11-18

更新于

2020-11-19

许可协议

CC BY-NC-SA 4.0

评论