Android 仿火萤视频桌面 神奇的LiveWallPaper

逆水行舟用力撑,一篙松劲退千寻。这篇文章主要讲述Android 仿火萤视频桌面 神奇的LiveWallPaper相关的知识,希望能为你提供帮助。

本文已在我的公众号hongyangandroid原创首发。
转载请标明出处:
http://blog.csdn.net/lmj623565791/article/details/72170299
本文出自张鸿洋的博客
一、概述 上周我的微信公众号推送了一篇Android 实现”透明屏幕, 当时我看到之后就觉得特别感兴趣, 也立即联系作者要了授权~~
欢迎大家扫描左侧二维码关注我的公众号, 每天7点半推送优秀技术博文。
感兴趣的原因是, 我是内涵段子的资深用户, 前段时间基本被一款叫火萤视频桌面的软件( 就是将视频作为桌面) 给刷屏了, 所以看了下作者的代码, 看到了SurfaceHolder, 立刻想到了, 肯定可以用来播放视频实现视频桌面的效果, 于是周末尝试了下, 果然很简单。
所以本篇文章无限感谢Android 实现”透明屏幕一文, 代码也部分参考自其提供的透明相机。
https://github.com/songixan/Wallpaper
效果图是这样的:
Android 仿火萤视频桌面 神奇的LiveWallPaper

文章图片

注: 本文的测试机为小米5s , 可能不同手机会有一些兼容性问题, 尝试解决下, 欢迎留言。
二、实现 (1) 配置相关
首先编写一个xml文件, 用于描述wallpaper的thumbnaildescriptionsettingsActivity等, 这里为了简单, 仅设置了thumbnail。
< ?xml version= " 1.0" encoding= " utf-8" ?> < wallpaper xmlns:android= " http://schemas.android.com/apk/res/android" android:thumbnail= " @ mipmap/ic_launcher" />

( 2) 编写代码
Wallpaper需要在屏幕上一直显示, 其背后其实是一个Service, 所以实现一个Wallpaper需要继承自WallpaperService, 实现其抽象方法onCreateEngine,如下:
public class VideoLiveWallpaper extends WallpaperService { public Engine onCreateEngine() { return new VideoEngine(); } //... }

可以看到返回值是一个Engine,Engine为WallpaperService的内部类, 其内部包含onSurfaceCreatedonSurfaceChangedonSurfaceDestroyedonTouchEvent等方法, 看到这些方法, 立刻想到了SurfaceView, 关于SurfaceView相关知识可以参考:
  • Android SurfaceView实战 打造抽奖转盘
此外, 大家还记得在Android播放视频吗?
常规的做法有通过VideoView, 除此以外还有通过MediaPlayer配合SurfaceView配合来实现, 今天这个例子类似后者。
我们只需要通过MediaPlayer将解码的数据不断的输送到传入的Surface中即可。
class VideoEngine extends Engine {private MediaPlayer mMediaPlayer; @ Override public void onSurfaceCreated(SurfaceHolder holder) { L.d(" VideoEngine#onSurfaceCreated " ); super.onSurfaceCreated(holder); mMediaPlayer = new MediaPlayer(); mMediaPlayer.setSurface(holder.getSurface()); try { AssetManager assetMg = getApplicationContext().getAssets(); AssetFileDescriptor fileDescriptor = assetMg.openFd(" test1.mp4" ); mMediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength()); mMediaPlayer.setLooping(true); mMediaPlayer.setVolume(0, 0); mMediaPlayer.prepare(); mMediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); }}@ Override public void onVisibilityChanged(boolean visible) { L.d(" VideoEngine#onVisibilityChanged visible = " + visible); if (visible) { mMediaPlayer.start(); } else { mMediaPlayer.pause(); } }@ Override public void onSurfaceDestroyed(SurfaceHolder holder) { L.d(" VideoEngine#onSurfaceDestroyed " ); super.onSurfaceDestroyed(holder); mMediaPlayer.release(); mMediaPlayer = null; }

代码非常简单, 在onSurfaceCreated中去初始化mMediaPlayer, 核心代码即为设置setSurface方法, 这里我默认设置了静音。
onVisibilityChanged, 即当桌面不可见时, 我们要暂停播放, 等回到桌面继续。
当onSurfaceDestroyed时释放资源~~
这样我们的VideoLiveWallpaper就写好了, 别忘了他是个Service, 需要我们去注册。
< service android:name= " .VideoLiveWallpaper" android:label= " @ string/app_name" android:permission= " android.permission.BIND_WALLPAPER" android:process= " :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/livewallpaper" /> < /service>

( 3) 设置为壁纸
【Android 仿火萤视频桌面 神奇的LiveWallPaper】注册完成后, 我们在MainActivity中添加一个按钮点击设置为桌面背景, 调用代码如下
public static void setToWallPaper(Context context) { final Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(context, VideoLiveWallpaper.class)); context.startActivity(intent); }

这样就完成了代码的初步编写啦~~
( 4) 增加一些参数的支持
刚才我们设置了默认是静音, 可能有时候我们会希望能够动态去控制视频桌面的参数, 正常应该尝试去使用settingsActivity, 不过我觉得其实广播也挺合适的, 无非就是Service( 可能在独立的进程) 和Activity等通信嘛~~
这里我们增加一个复选框, 支持设置开启声音or关闭声音。
public static final String VIDEO_PARAMS_CONTROL_ACTION = " com.zhy.livewallpaper" ; public static final String KEY_ACTION = " action" ; public static final int ACTION_VOICE_SILENCE = 110; public static final int ACTION_VOICE_NORMAL = 111; class VideoEngine extends Engine { // 省略其他代码 private BroadcastReceiver mVideoParamsControlReceiver; @ Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); IntentFilter intentFilter = new IntentFilter(VIDEO_PARAMS_CONTROL_ACTION); registerReceiver(mVideoParamsControlReceiver = new BroadcastReceiver() { @ Override public void onReceive(Context context, Intent intent) { L.d(" onReceive" ); int action = intent.getIntExtra(KEY_ACTION, -1); switch (action) { case ACTION_VOICE_NORMAL: mMediaPlayer.setVolume(1.0f, 1.0f); break; case ACTION_VOICE_SILENCE: mMediaPlayer.setVolume(0, 0); break; } } }, intentFilter); } @ Override public void onDestroy() { unregisterReceiver(mVideoParamsControlReceiver); super.onDestroy(); } }

Engine还有onCreate和onDestroy声明周期方法, 可以在onCreate中注册动态广播, 当接受到发送的action为ACTION_VOICE_NORMAL则开启声音; 接收到发送的ACTION_VOICE_SILENCE则为静音状态。
最后直接在VideoLiveWallpaper中添加两个静态方法用于发送广播即可:
public static void voiceSilence(Context context) { Intent intent = new Intent(VideoLiveWallpaper.VIDEO_PARAMS_CONTROL_ACTION); intent.putExtra(VideoLiveWallpaper.KEY_ACTION, VideoLiveWallpaper.ACTION_VOICE_SILENCE); context.sendBroadcast(intent); }public static void voiceNormal(Context context) { Intent intent = new Intent(VideoLiveWallpaper.VIDEO_PARAMS_CONTROL_ACTION); intent.putExtra(VideoLiveWallpaper.KEY_ACTION, VideoLiveWallpaper.ACTION_VOICE_NORMAL); context.sendBroadcast(intent); }

在Actiivty中:
public class MainActivity extends AppCompatActivity { private CheckBox mCbVoice; @ Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mCbVoice = (CheckBox) findViewById(R.id.id_cb_voice); mCbVoice.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @ Override public void onCheckedChanged( CompoundButton buttonView, boolean isChecked) { if (isChecked) { // 静音 VideoLiveWallpaper.voiceSilence(getApplicationContext()); } else { VideoLiveWallpaper.voiceNormal(getApplicationContext()); } } }); } }

监听一下CheckBox状态, 发送广播即可。
ok, 这样一个简单的视频桌面就完成啦~~
源码地址:
  • https://github.com/WanAndroid/LiveWallPaper/tree/master/hongyang/MagicWallPaper
直接将这个目录以项目形式导入。
支持我的话可以关注下我的公众号, 每天都会推送新知识~
欢迎关注我的微信公众号: hongyangAndroid
( 可以给我留言你想学习的文章, 支持投稿)
Android 仿火萤视频桌面 神奇的LiveWallPaper

文章图片

参考
  • http://www.vogella.com/tutorials/AndroidLiveWallpaper/article.html
  • http://www.jianshu.com/u/befb61deec9c

    推荐阅读