这几天对前段事件比较火的视频壁纸产生了兴趣,也已经有了很多的实现,这里自己做下记录,也尝试着实现了一下相机壁纸,好玩是好玩就是有点费电。
为了兼容6.0之后的权限请求,可以看下之前写的Android6.0之后权限请求工具类
视频壁纸
先上效果图,gif的录制确实是个大坑
实现方法也挺简单的,都是继承了WallpaperService,只需要实现里面的一个onCreateEngine()方法即可。
实现一个继承了Engine的视频壁纸引擎,在surface创建后把MediaPlayer初始化好,之后只需要控制视频的播放和显示就好了。
1.
/**
2.
* 视频壁纸的引擎
3.
*/
4.
class VideoEngine extends Engine{
5.
MediaPlayer mediaPlayer;
6.
7.
@Override
8.
public void onSurfaceCreated(SurfaceHolder holder){
9.
super.onSurfaceCreated(holder);
10.
initMediaPlayer(holder);
11.
}
12.
13.
/**
14.
* 初始化MediaPlayer
15.
@param
16.
*/
17.
private void initMediaPlayer(SurfaceHolder surfaceHolder){
18.
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.video);
19.
mediaPlayer.setSurface(surfaceHolder.getSurface());
20.
true);
21.
}
22.
23.
@Override
24.
public void onVisibilityChanged(boolean{
25.
super.onVisibilityChanged(visible);
26.
if(visible){
27.
//可见时播放
28.
mediaPlayer.start();
29.
else{
30.
//不可见时暂停
31.
mediaPlayer.pause();
32.
}
33.
}
34.
35.
@Override
36.
public void onDestroy(){
37.
super.onDestroy();
38.
//停止释放MediaPlayer
39.
if(mediaPlayer.isPlaying()){
40.
mediaPlayer.stop();
41.
}
42.
mediaPlayer.release();
43.
null;
44.
}
45.
}
配置文件中需要配置service,配置的label会在我们选择壁纸的时候显示
1.
<service
2.
android:name=
".service.VideoWallpaperService"
3.
android:label=
"@string/video_wallpaper"
4.
android:permission=
"android.permission.BIND_WALLPAPER">
5.
<intent-filter>
6.
<action android:name="android.service.wallpaper.WallpaperService"
7.
</intent-filter>
8.
9.
<meta-data
10.
android:name=
"android.service.wallpaper"
11.
android:resource=
"@xml/video_wallpaper"
12.
</service>
xml文件,里面可以设置thumbnail,description和settingsActivity等,thumbnail设置的图片会在我们选择壁纸的时候显示,便于识别
1.
<?xml version="1.0" encoding="utf-8"?>
2.
<!--选择壁纸时显示的缩略图-->
3.
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
4.
android:thumbnail=
"@mipmap/ic_launcher"
5.
android:description=
"@string/video_description"
6.
/>
权限
<uses-permission android:name="android.permission.SET_WALLPAPER" />
相机桌面
同上也放一个很渣的gif图
实现和上面的视频差不多,同样是用了SurfaceHolder显示,只是用了Camera。
有意思的是我们可以接受处理桌面上的触摸事件,比如在接受到接受到点击事件的时候拍照保存之类的,还是蛮有意思的。
1.
/**
2.
* 相机壁纸的引擎
3.
*/
4.
class CameraEngine extends Engine{
5.
Camera camera;
6.
7.
@Override
8.
public void onCreate(SurfaceHolder surfaceHolder){
9.
super.onCreate(surfaceHolder);
10.
//接受触摸事件
11.
true);
12.
}
13.
14.
@Override
15.
public void onTouchEvent(MotionEvent event){
16.
super.onTouchEvent(event);
17.
//可以在这里处理添加触摸事件,如点击拍照
18.
}
19.
20.
@Override
21.
public void onVisibilityChanged(boolean{
22.
super.onVisibilityChanged(visible);
23.
if(visible){
24.
startPreview();
25.
else{
26.
stopPreview();
27.
}
28.
}
29.
30.
@Override
31.
public void onDestroy(){
32.
stopPreview();
33.
super.onDestroy();
34.
}
35.
36.
/**
37.
* 开始预览
38.
*/
39.
private void startPreview(){
40.
camera = Camera.open();
41.
//需要旋转90度
42.
90);
43.
try
44.
camera.setPreviewDisplay(getSurfaceHolder());
45.
camera.startPreview();
46.
catch
47.
e.printStackTrace();
48.
}
49.
}
50.
51.
/**
52.
* 关闭预览
53.
*/
54.
private void stopPreview(){
55.
if (camera != null) {
56.
camera.stopPreview();
57.
camera.release();
58.
null;
59.
}
60.
}
61.
}
几乎相同的配置
1.
<service
2.
android:name= ".service.CameraWallpaperService"
3.
android:label= "@string/camera_wallpaper"
4.
android:permission= "android.permission.BIND_WALLPAPER">
5.
<intent-filter>
6.
<action android:name="android.service.wallpaper.WallpaperService"
7.
</intent-filter>
8.
9.
<meta-data
10.
android:name= "android.service.wallpaper"
11.
android:resource= "@xml/camera_wallpaper"
12.
</service>
几乎相同的xml
1.
<?xml version="1.0" encoding="utf-8"?>
2.
<!--选择壁纸时显示的缩略图-->
3.
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
4.
android:thumbnail= "@mipmap/ic_launcher"
5.
android:description= "@string/camera_description"
6.
/>
权限
因为需要使用相机,所以需要获取提供相机权限
1.
<uses-permission android:name="android.permission.CAMERA"
2.
<uses-permission android:name="android.permission.SET_WALLPAPER"
3.
4.
<uses-feature android:name="android.hardware.camera"
5.
<uses-feature android:name="android.hardware.camera.autofocus"
调用
直接使用指定壁纸,传入Service组件
1.
new
2.
new
3.
startActivity(intent);
项目源码