Android动态壁纸详解

news/2025/1/12 1:42:13/

动态壁纸

Livewallpaper(动态壁纸): 首先动态壁纸并不是GIF图片,而是一个独立的应用程序,本质是一个Service,甚至可以没有桌面图标。


直接看AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.qwq.clocklivewallpaper"><applicationandroid:allowBackup="true"android:icon="@drawable/clock"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme"><!-- 主界面Activity.可以去掉。动态壁纸应用是可以允许没有Activity的 --><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><!-- 动态壁纸设置界面,可有可无,一般壁纸应用会有,作用是让用户自定义动态壁纸 --><activityandroid:name=".SettingsActivity"android:exported="true"android:label="@string/app_name"></activity><!-- 动态壁纸本质就是Service,所以此类为动态壁纸核心--><serviceandroid:name=".ClockWallpaperService"android:enabled="true"android:label="@string/wallpaper_name" //下面第一张图片中labelandroid:permission="android.permission.BIND_WALLPAPER">//动态壁纸必须加此权限<intent-filter>//系统就是通过APK的这个action把其当做一个动态墙纸。<action android:name="android.service.wallpaper.WallpaperService"></action></intent-filter><!-- android:resource 指定的xml很重要!!!后面会单独介绍 --><meta-dataandroid:name="android.service.wallpaper"android:resource="@xml/clock_wallpaper"></meta-data></service></application></manifest>

clock_wallpaper.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.qwq.clocklivewallpaper.SettingsActivity"android:thumbnail="@drawable/ic_preview" />

android:thumbnail 动态壁纸列表中的图标,
android:description 动态壁纸的简单介绍文字,有的手机可能不显示
动态壁纸列表图片

android:settingsActivity 指定一个Activity。系统会检测动态壁纸应用有没有此属性。如果有则和下方的图片显示效果一样(两个Button),点击下图中设定Button可跳转至指定的Activity(设置界面)。如果没有此属性,就只有一个设置壁纸Button。可以去掉此属性看一下效果。
动态壁纸设置界面图片


WallpaperService(核心)

实现动态壁纸必须继承WallpaperService,且重载onCreateEngine方法。onCreateEngine()方法只需返回一个Engine的子类对象就可以了,所以动态壁纸应用的主要工作就是实现Engine的子类。其原理是使用surfaceview不断更新,实现动态壁纸效果。不多说了,直接贴代码,重要的方法都会有所说明。

package com.qwq.clocklivewallpaper;import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;import java.util.Date;public class ClockWallpaperService extends WallpaperService {static final String TAG = ClockWallpaperService.class.getSimpleName();static final int POINTER_WIDTH = 9;//  onCreateEngine()方法需返回一个Engine的子类对象就可以了,//  所以动态壁纸应用的主要工作就是实现Engine的子类@Overridepublic Engine onCreateEngine() {Log.d(TAG, "onCreateEngine");return new ClockWallpaperEngine();}//实现Engine的子类,本文的重中之重,动态壁纸就是在此具体实现的private class ClockWallpaperEngine extends Engine implements OnSharedPreferenceChangeListener {private final Handler handler = new Handler();// surfacewive使用线程更新UI,所以我们可使用Runnable接口创建一个线程,把具体绘制方法放进去,// 下文会使用handler调用private final Runnable drawRunner = new Runnable() {@Overridepublic void run() {draw();}};private Paint paint;private int width;private int height;private boolean isVisible = true;private boolean isShowSecond;private ClockView clockView;private SharedPreferences sp;//构造函数,初始化动态壁纸public ClockWallpaperEngine() {Log.d(TAG, "ClockWallpaperEngine");initSp();initPaint();startDrawClock();}public void initSp() {sp = PreferenceManager.getDefaultSharedPreferences(ClockWallpaperService.this);sp.registerOnSharedPreferenceChangeListener(this);isShowSecond = sp.getBoolean(SettingsActivity.IS_SHOW_SECOND, true);}public void initPaint() {paint = new Paint();paint.setAntiAlias(true);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(POINTER_WIDTH);}public void startDrawClock() {clockView = new ClockView(getApplicationContext());handler.post(drawRunner);}@Overridepublic void onCreate(SurfaceHolder surfaceHolder) {super.onCreate(surfaceHolder);Log.d(TAG, "onCreate");}//监听是否可见变化,可见时开始更新UI,不可见时停止刷新@Overridepublic void onVisibilityChanged(boolean visible) {this.isVisible = visible;if (visible) {handler.post(drawRunner);} else {handler.removeCallbacks(drawRunner);}}@Overridepublic void onSurfaceDestroyed(SurfaceHolder holder) {super.onSurfaceDestroyed(holder);isVisible = false;handler.removeCallbacks(drawRunner);sp.unregisterOnSharedPreferenceChangeListener(this);}@Overridepublic void onSurfaceChanged(SurfaceHolder holder,int format,int width,int height){    this.width = width;this.height = height;super.onSurfaceChanged(holder, format, width, height);}//绘制,每个200毫秒刷新界面private void draw() {SurfaceHolder holder = getSurfaceHolder();Canvas canvas = null;try {canvas = holder.lockCanvas();if (canvas != null) {drawClock(canvas);}} finally {if (canvas != null) {holder.unlockCanvasAndPost(canvas);}}handler.removeCallbacks(drawRunner);if (isVisible) {handler.postDelayed(drawRunner, 200);}}//具体绘制钟表private void drawClock(Canvas canvas) {canvas.drawColor(Color.WHITE);   //绘制整个动态壁纸的背景颜色clockView.config(width / 2, height / 2, (int) (width * 0.8f), new Date(), paint, isShowSecond);clockView.draw(canvas);}@Overridepublic void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){ //监听SharedPreference变化,改变动态壁纸样式if (SettingsActivity.IS_SHOW_SECOND.equals(key)) {isShowSecond = sharedPreferences.getBoolean(SettingsActivity.IS_SHOW_SECOND,  true);}}@Overridepublic void onTouchEvent(MotionEvent event) {super.onTouchEvent(event);// 可以在这里做一些与用户交互的操作,例如动态星星壁纸,用户触摸屏幕时增加星星数量。Log.d(TAG, "onTouchEvent");}}}

ClockView(钟表的具体绘制)

package com.qwq.clocklivewallpaper;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;import java.util.Calendar;
import java.util.Date;public class ClockView extends View {static final String TAG = ClockView.class.getSimpleName();private float x;private float y;private int radius;private Calendar cal;private Paint paint;private Bitmap clockDial = BitmapFactory.decodeResource(getResources(),R.drawable.clock_bg);private int sizeScaled = -1;private Bitmap clockDialScaled;private boolean isShowSecond;public ClockView(Context context) {super(context);cal = Calendar.getInstance();}//设置钟表宽高等属性
public void config(float x, float y, int size, Date date, Paint paint, boolean isShowSecond) {this.x = x;this.y = y;this.paint = paint;this.isShowSecond = isShowSecond;cal.setTime(date);if (size != sizeScaled) {clockDialScaled = Bitmap.createScaledBitmap(clockDial, size, size, false);radius = size / 2;}}//具体绘制钟表的指针
protected void onDraw(Canvas canvas) {Log.d(TAG,"onDraw:"+canvas);super.onDraw(canvas);if (paint != null) {canvas.drawBitmap(clockDialScaled, x - radius, y - radius, null);float sec = cal.get(Calendar.SECOND);float min = cal.get(Calendar.MINUTE);float hour = cal.get(Calendar.HOUR_OF_DAY);paint.setColor(Color.RED);canvas.drawLine(x, y,(float)(x + (radius * 0.5f)*Math.cos(Math.toRadians((hour / 12.0f * 360.0f) - 90f))),(float)(y + (radius * 0.5f)*Math.sin(Math.toRadians((hour / 12.0f * 360.0f) -90f))),   paint);canvas.save();paint.setColor(Color.BLUE);canvas.drawLine(x, y, (float)(x + (radius * 0.6f)*Math.cos(Math.toRadians((min / 60.0f * 360.0f) - 90f))),(float)(y + (radius * 0.6f)*Math.sin(Math.toRadians((min / 60.0f * 360.0f) - 90f))),  paint);canvas.save();if (isShowSecond) {paint.setColor(Color.GREEN);canvas.drawLine(x, y,(float)(x + (radius * 0.7f)*Math.cos(Math.toRadians((sec/60.0f * 360.0f) - 90f))),(float)(y + (radius * 0.7f)*Math.sin(Math.toRadians((sec/60.0f * 360.0f) - 90f))),   paint);}}}}


http://www.ppmy.cn/news/120972.html

相关文章

动态修改安卓桌面icon

动态修改安卓桌面icon 继承启动activity 网上很多说使用activity-alias的&#xff0c;后面看到知乎一个文章&#xff1a;Android动态变更图标和应用名&#xff0c;觉得也是写成一个activity合理一些。 这里直接继承原来的启动activity&#xff0c;内容为空就行&#xff1a; …

Android动态壁纸开发

新建一个Android项目&#xff1a; 完成下面步骤后&#xff0c;安装到手机&#xff0c;并设置动态壁纸才能看到效果。 res/xml/cube1.xml <?xml version"1.0" encoding"utf-8"?><!-- The attributes in this XML file provide configuration inf…

Android静态壁纸和动态壁纸的使用和理解

这两天在公众号上偶然看到一篇关于设置动态壁纸的文章&#xff0c;觉得蛮有意思的&#xff0c;学习了一下&#xff0c;以此文章记录一下怎样给手机设置静态壁纸和动态壁纸&#xff0c;设置壁纸的使用方法。 静态壁纸 Android中WallpaperManager系统服务用于管理壁纸的运行与切…

Android动态壁纸的制作教程

动态壁纸是在Android 2.1新增的一个功能。动态壁纸可以添加到Android的桌面&#xff0c;具有交互式的动画背景效果。在本教程中&#xff0c;我们将教会你如何去制作一个交互式的动态壁纸。 动态壁纸是一个Android应用程序&#xff0c;包括一个服务(WallpaperService)。该服务必…

Android 动态壁纸 Livepaper

动态壁纸原理 及 例子 最近做动态壁纸的项目&#xff0c;原来觉得动态壁纸是个很小的项目&#xff0c;但是看到Android Market上有个专门的动态壁纸分类(现在升级为Google Play了), 而且自己做的这个项目可连接上服务器&#xff0c;供用户购买下载图片&#xff0c;终于有了自信…

android动态壁纸---线条

android SDK2.1中有关于动态壁纸的2个演示DEMO&#xff0c;本人在网上查了相关资料。找到了一个演示DEMO的源代码&#xff0c;希望和大家分享。 同时谢谢提供代码的LZ.并且再此基础上本人做了一个简单的线条动态壁纸,后续还有动态壁纸---球的感应动作实例和大家一起分享学习。…

安卓动态壁纸开发

一般的壁纸设定&#xff0c;只需要在获取壁纸权限后&#xff0c;只需要getWallPagerManager对象来设定壁纸&#xff08;静态&#xff09; 与安卓应用的开发不同&#xff0c;动态壁纸的开发不需要传统的布局文件&#xff0c;也不要活动&#xff08;activity&#xff09;来管理&a…

Android-动态壁纸的实现

前言: 最近遇到了几个很恶心的问题&#xff0c;第一个是手机录制视频发现资源不够用&#xff0c;第二个是手机播放视频发现卡顿。找了半天两个问题的root cause都是手机动态壁纸。我们手机动态壁纸的实现是无论当前壁纸是否处于前台&#xff0c;video instance都是一直活跃的。…