必威体育Betway必威体育官网
当前位置:首页 > IT技术

动态壁纸开发指南(一)概述介绍

时间:2019-06-12 15:41:04来源:IT技术作者:seo实验室小编阅读:69次「手机版」
 

动态壁纸

一、概述

1.1 简介

在Android中,壁纸分为静态与动态两种。静态壁纸是一张图片,而动态壁纸则以动画为表现形式,或者可以对用户的操作作出反应。动态壁纸实际上和其他应用是类似的,自Android 2.1开始支持。Android壁纸运行在一个Android服务之中,这个服务的名字叫做WallpaperService。当用户选择了一个壁纸之后,此壁纸所对应的WallpaperService便会启动并开始进行壁纸的绘制工作。Engine是WallpaperService中的一个内部类,实现了壁纸窗口的创建以及Surface的维护工作。

1.2 示例

简单来说,动态壁纸就是一个服务,动态壁纸需要实现动态壁纸的服务WallpaperService和描绘动态壁纸的引擎WallpaperService.Engine。

组件类 说明
WallpaperService 实现动态壁纸的服务程序
WallpaperService.Engine 描绘动态壁纸的引擎

下面以视频动态壁纸为例,讲述一下具体实现流程。

(1) 首先定义一个类VideoWallpaper来继承WallpaperService类并实现onCreateEngine()方法,在该方法中需要返回一个Engine实例。

public class VideoWallpaper extends WallpaperService {
    @Override
    public Engine onCreateEngine() {
        return null;
    }
}

(2) 然后定义一个VideoEngine类来继承Engine类并实现onSurfaceCreated() 、onSurfaceDestroyed()和onVisibilityChanged()方法。在onSurfaceCreated()方法中初始对象资源;在onSurfaceDestroyed()中去释放和销毁资源;在onVisibilityChanged()方法中去控制视图是显示和隐藏逻辑。以视频壁纸为例:

private class VideoEngine extends Engine {
    private MediaPlayer mPlayer;

    @Override
    public void onVisibilityChanged(boolean visible) {
        if (visible) {
            mPlayer.start();
        } else {
            mPlayer.pause();
        }
    }

    @Override
    public void onSurfaceCreated(SurfaceHolder holder) {
        super.onSurfaceCreated(holder);
        mPlayer = new MediaPlayer();
        //不能使用setDisplay()方法
        mPlayer.setSurface(holder.getSurface());
        mPlayer.setDataSource(videoPath);
        mPlayer.prepare();
        mPlayer.start();
    }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
        super.onSurfaceDestroyed(holder);
        if (mPlayer.isPlaying()) {
            mPlayer.stop();
        }
        mPlayer.release();
        mPlayer = null;
    }
}

(3) 对VideoWallPaper服务进行注册,这里在注册时写法和普通的Service相同。需要注意的是,WallPaperService需要一个"android.permission.BIND_WALLPAPER"的权限,添加一个action为"android.service.wallpaper.WallpaperService",还需要一个名为"android.service.wallpaper"的meta-data。如下:

 <service  
         android:label="@string/app_name"  
         android:permission="android.permission.BIND_WALLPAPER"   
         android:name=".VideoWallpaper">  
         <intent-filter>  
             <action android:name="android.service.wallpaper.WallpaperService" />  
         </intent-filter>  
         <meta-data android:name="android.service.wallpaper"   
               android:resource="@xml/livewallpaper" />              
</service>  

(4) 上面的代码中meta-data中需要一个xml文件源,所以还需要在res的xml文件夹(没有就创建)下,创建一个名为wallpaper的xml文件。xml文件的根标签为wallpaper,有一下三个属性:

  • description :动态壁纸的文字描述
  • thumbnail:动态壁纸的图片描述
  • settingsActivity:动态壁纸的设置界面

动态壁纸的资源来源“/res/xml/liveWallpaper.xml”

<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/wallpaper_description"
    android:settingsActivity="com.example.videowallpaper.SettingsActivity"
    android:thumbnail="@mipmap/ic_launcher">
</wallpaper>

SettingsActivity代码示例如下:

public class SettingsActivity extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.setting_layout);
    }
}

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="video_param"
    android:title="设置">
    <CheckBoxPreference
        android:defaultValue="true"
        android:key="loop"
        android:title="是否循环播放" />
    <CheckBoxPreference
        android:checked="false"
        android:key="volume"
        android:title="是否开启声音" />
</PreferenceScreen>

(5) 接下来就是启动壁纸服务了,这里不能通过context的startService()方法来启动壁纸服务,需要通过启动系统的预览界面来间接启动服务。

Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER); intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, new ComponentName(context, VideoWallPaperService.class)); context.startActivity(intent);

除了启动还需要关闭壁纸服务,可以通过WallpaperManager的clear()方法来关闭,也可以通过WallpaperService的clearWallpaper()(已经被标记过时)方法来关闭壁纸。

try {
      WallpaperManager.getInstance(context).clear();
} catch(IOException e) {
       e.printStackTrace();
}

其他需要注意的地方,比如可以通过WallpaperManager的getWallpaperInfo()方法来判断当前壁纸的服务是否已经在运行,从而可以通过广播或者其他通知来直接修改壁纸播放的视频,避免每次更换一个视频都需要走一次系统的预览界面。也就是在设置里面动态设置壁纸参数。

在这里插入图片描述

上面只是简单的示例代码,如果对视频动态壁纸感兴趣,可以参考此项目VideoWallpaper

总结

以上就是实现一个基本动态壁纸的流程,其实视频动态壁纸实现起来比较简单,不需要开发者自己画出复杂的界面,也没有手势交互逻辑。但是市面上的动态壁纸大多比较复杂,而且基本上是使用绘图API画出来的,包括OpenGL等,在之后的文章里会详细介绍。

相关阅读

实时系统动态内存算法分析dsa(二)——TLSF代码分析

上一篇我们看了dsa的分类和简单的内存管理算法实现,这篇文档我们来看TLSF的实现,一种更加高级的内存管理算法;一、实现原理 基本的Se

【C++】动态内存分配详解(new/new[]和delete/delete[])

一、为什么需要动态内存分配? 在C++程序中,所有内存需求都是在程序执行之前通过定义所需的变量来确定的。 但是可能存在程序的内存

easyui动态修改required

经常使用easyui,对于基本的使用还算了解,经常有这样的需要,需要动态的修改required,也就是在某些情况下required是true,有些情况下req

C语言中动态分配数组

很多人在编写C语言代码的时候很少使用动态数组,不管什么情况下通通使用静态数组的方法来解决,在当初学习C语言的时候我就是一个典型

动态链接库(DLL)初始化例程失败 解决方法

重装了系统,在安装VIVADO的时候报错:LoadLibrary failed with error 1114: 动态链接库(DLL)初始化例程失败,不知道怎么回事,在知乎上看

分享到:

栏目导航

推荐阅读

热门阅读