使用反射设置壁纸,
// wallpaperManager.setWallpaperComponent(new ComponentName(context.getPackageName(), name));
如果需要设置壁纸跟随移动需要设置
// wallpaperManager.setWallpaperOffsetSteps(0.5f, 0.0f);
// wallpaperManager.setWallpaperOffsets(windowToken, 0.5f, 0.0f);
/**
* 通过反射设置动态壁纸
*
* @param context
* @param name
*/
private void setLiveWallpaper(Context context, String name) {
try {
Class<?> aClass = Class.forName(WallpaperManager.class.getName());
Method setWallpaperComponent = aClass.getMethod("setWallpaperComponent", new Class[]{ComponentName.class});
boolean susccess = (boolean) setWallpaperComponent.invoke(WallpaperManager.getInstance(context), new ComponentName(context.getPackageName(), name));
Log.d(TAG, "setLiveWallpaper: " + susccess);
} catch (ClassNotFoundException e) {
Log.d(TAG, "ClassNotFoundException: " + e.toString());
e.printStackTrace();
} catch (NoSuchMethodException e) {
Log.d(TAG, "NoSuchMethodException: " + e.toString());
e.printStackTrace();
} catch (IllegalAccessException e) {
Log.d(TAG, "IllegalAccessException: " + e.toString());
e.printStackTrace();
} catch (InvocationTargetException e) {
Log.d(TAG, "InvocationTargetException: " + e.toString());
e.printStackTrace();
}
// wallpaperManager.setWallpaperComponent(new ComponentName(context.getPackageName(), name));
// wallpaperManager.setWallpaperOffsetSteps(0.5f, 0.0f);
// wallpaperManager.setWallpaperOffsets(windowToken, 0.5f, 0.0f);
}
使用方法:
changePaper(context, GifWallpaperService.class.getCanonicalName());
GIF和video壁纸加载器参考下面:
package com.xbh.viewsonic.display.wallpaper.helper;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.xbh.viewsonic.util.LogUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by Tyhj on 2017/5/23.
*/
public class GifWallpaperService extends WallpaperService {
private static final String TAG = "GifWallpaperService";
public static String GIT_WALLPAPER = "git_wallpaper";
private final Handler mHandler = new Handler();
private Movie movie;
private float scaleWidth, scaleHeight;
public static ServiceConnection connection;
@Override
public void onCreate() {
super.onCreate();
LogUtil.i(TAG, "onCreate");
}
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
Log.d(TAG, "bindService: ");
connection = conn;
return super.bindService(service, conn, flags);
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
Log.d(TAG, "onRebind: ");
}
private void initGif() {
InputStream stream = null;
try {
String string = SPUtils.getInstance().getString(GIT_WALLPAPER, "wallpaper_001.gif");
/*是否是外部资源文件
* 1、assets文件
* 2、从外部拷贝到cache目录文件*/
if (string.contains(File.separator)) {
stream = new FileInputStream(string);
} else {
stream = getAssets().open(string);
}
} catch (IOException e) {
e.printStackTrace();
LogUtil.e(TAG, "initGif error:" + e.toString());
}
movie = Movie.decodeStream(stream);
//获取gif的宽高
int width = movie.width();
int height = movie.height();
// 设置想要的大小
int newWidth = ScreenUtils.getScreenWidth();
int newHeight = ScreenUtils.getScreenHeight();
LogUtil.i("宽度:", newWidth + "");
LogUtil.i("长度:", newHeight + "");
// 计算缩放比例
scaleWidth = ((float) newWidth) / width;
scaleHeight = ((float) newHeight) / height;
scaleWidth = (scaleWidth > scaleHeight) ? scaleWidth : scaleHeight;
}
@Override
public Engine onCreateEngine() {
Log.d(TAG, "onCreateEngine: ");
return new Mngine();
}
//Engine是WallpaperService中的一个内部类,实现了壁纸窗口的创建以及Surface的维护工作
class Mngine extends Engine {
//线程
private Runnable runnable = new Runnable() {
@Override
public void run() {
drawFrame();
}
};
private void drawFrame() {
if (movie == null) {
initGif();
}
Canvas canvas = null;
canvas = getSurfaceHolder().lockCanvas();
canvas.scale(scaleWidth, scaleWidth);
canvas.save();
//绘制此gif的某一帧,并刷新本身
movie.draw(canvas, 0, 0);
movie.setTime((int) (System.currentTimeMillis() % movie.duration()));
canvas.restore();
//结束锁定画图,并提交改变,画画完成(解锁)
getSurfaceHolder().unlockCanvasAndPost(canvas);
mHandler.postDelayed(runnable, 50); //50ms表示每50ms绘制一帧
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(true);
initGif();
LogUtil.i(TAG, "Engine onCreate");
}
public Mngine() {
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
drawFrame();
LogUtil.i(TAG, "onSurfaceCreated");
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(runnable);
movie = null;
LogUtil.i(TAG, "onDestroy");
}
@Override
public void onVisibilityChanged(boolean visible) {
LogUtil.i(TAG, "onVisibilityChanged:" + visible);
/*下面这个判断好玩,就是说,如果屏幕壁纸状态转为显式时重新绘制壁纸,否则黑屏幕,隐藏就可以*/
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(runnable);
}
}
@Override
public void onTouchEvent(MotionEvent event) {
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
LogUtil.i(TAG, "onSurfaceChanged");
drawFrame();
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
LogUtil.i(TAG, "onSurfaceDestroyed");
super.onSurfaceDestroyed(holder);
mHandler.removeCallbacks(runnable);
}
}
}
package com.xbh.viewsonic.display.wallpaper.helper;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.service.wallpaper.WallpaperService;
import android.view.SurfaceHolder;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.Utils;
import com.xbh.viewsonic.util.LogUtil;
import java.io.File;
import java.io.IOException;
public class VideoWallpaper extends WallpaperService {
private static final String TAG = "VideoWallpaper";
public static final String CLOSE_VOLUME = "close_volume";
public static String VIDEO_WALLPAPER = "video_wallpaper";
@Override
public void onCreate() {
super.onCreate();
LogUtil.d(TAG, "VideoWallpaper onCreate");
}
@Override
public Engine onCreateEngine() {
LogUtil.d(TAG, "VideoWallpaper onCreateEngine");
return new VideoEngine();
}
@Override
public void onDestroy() {
super.onDestroy();
LogUtil.d(TAG, "VideoWallpaper onDestroy");
}
class VideoEngine extends Engine {
private MediaPlayer mp;
private int progress = 0;
private String path;
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
LogUtil.d(TAG, "VideoEngine onCreate");
setTouchEventsEnabled(true);
path = SPUtils.getInstance().getString(VIDEO_WALLPAPER, "wallpaper_004.mov");
if (path.contains(File.separator)) {
setFileDataAndPlay(path);
} else {
setAssetsDataAndPlay(path);
}
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
mp.setSurface(holder.getSurface());
LogUtil.d(TAG, "VideoEngine onSurfaceCreated");
//mp.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
}
@Override
public void onVisibilityChanged(boolean visible) {
LogUtil.d(TAG, "VideoEngine onVisibilityChanged");
if (mp != null) {
if (visible) {
if (!mp.isPlaying()) {
mp.reset();
mp.release();
if (path.contains(File.separator)) {
setFileDataAndPlay(path);
} else {
setAssetsDataAndPlay(path);
}
mp.setSurface(getSurfaceHolder().getSurface());
mp.start();
return;
}
setCloseVolume();
mp.seekTo(progress);
mp.start();
} else {
progress = mp.getCurrentPosition();
mp.pause();
}
}
}
@Override
public void onDestroy() {
LogUtil.d(TAG, "VideoEngine onDestroy");
destroy();
super.onDestroy();
}
public void destroy() {
if (mp != null) {
mp.stop();
mp.reset();
mp.release();
}
}
/**
* aapt不压缩assets文件类型,如果还有需要不压缩的,在build中添加
* ".jpg", ".jpeg", ".png", ".gif",
* ".wav", ".mp2", ".mp3", ".ogg", ".aac",
* ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
* ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
* ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2"
* ".amr", ".awb", ".wma", ".wmv"
* @param path
*/
private void setAssetsDataAndPlay(String path) {
AssetManager assetManager = Utils.getApp().getAssets();
try {
AssetFileDescriptor fileDescriptor = assetManager
.openFd(path);
mp = new MediaPlayer();
mp.setDataSource(fileDescriptor.getFileDescriptor(),
fileDescriptor.getStartOffset(),
fileDescriptor.getLength());
mp.prepare();
} catch (IOException e) {
LogUtil.d(TAG, "Create player error: " + e.toString());
e.printStackTrace();
}
mp.setLooping(true);
setCloseVolume();
}
private void setFileDataAndPlay(String path) {
try {
mp = new MediaPlayer();
mp.setDataSource(path);
mp.prepare();
} catch (IOException e) {
LogUtil.d(TAG, "Create player error: " + e.toString());
e.printStackTrace();
}
mp.setLooping(true);
setCloseVolume();
}
/**
* 是否播放声音
*/
private void setCloseVolume() {
if (SPUtils.getInstance().getBoolean(CLOSE_VOLUME, false)) {
mp.setVolume(0.0f, 0.0f);
} else {
mp.setVolume(0.7f, 0.7f);
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
package com.xbh.viewsonic.display.wallpaper.helper;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.xbh.viewsonic.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created by Tyhj on 2017/5/23.
*/
public class MallpaperService extends WallpaperService {
public static String STILL_PAPER_KEY = "still _paper_key";
private final Handler mHandler = new Handler();
Bitmap newbm;
@Override
public void onCreate() {
int resourceID = SPUtils.getInstance().getInt(STILL_PAPER_KEY, R.mipmap.wallpaper_01);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resourceID);
// 获得图片的宽高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// 设置想要的大小
int newWidth = ScreenUtils.getScreenWidth();
int newHeight = ScreenUtils.getScreenHeight();
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
newbm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
super.onCreate();
}
@Override
public Engine onCreateEngine() {
return new Mngine();
}
//Engine是WallpaperService中的一个内部类,实现了壁纸窗口的创建以及Surface的维护工作
class Mngine extends Engine {
float touchX = 0;
float touchY = 0;
boolean isTouch;
Paint paint;
int width;
int height;
List<Mycircle> mycircleList;
int distance = 100;
float speed = 1.7f;
int count = 55;
float radius = 3.5f;
int gap = 1;
int length = 8;
private boolean mVisible;
private final Runnable mDrawCube = new Runnable() {
public void run() {
drawFrame();
}
};
private void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = null;
canvas = holder.lockCanvas();
canvas.save();
/*paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));*/
canvas.drawBitmap(newbm, 0, 0, paint);
for (int i = 0; i < mycircleList.size(); i++) {
if (mycircleList.get(i).startX > width || mycircleList.get(i).startX < 0) {
mycircleList.get(i).speedX = -mycircleList.get(i).speedX;
}
if (mycircleList.get(i).startY > height || mycircleList.get(i).startY < 0) {
mycircleList.get(i).speedY = -mycircleList.get(i).speedY;
}
mycircleList.get(i).startX = mycircleList.get(i).startX + mycircleList.get(i).speedX;
mycircleList.get(i).startY = mycircleList.get(i).startY + mycircleList.get(i).speedY;
//画圆
canvas.drawCircle(mycircleList.get(i).startX, mycircleList.get(i).startY, mycircleList.get(i).radius, mycircleList.get(i).paint);
}
//画连接线
for (int i = 0; i < mycircleList.size() - 1; i++) {
for (int j = i + 1; j < mycircleList.size(); j++) {
float x = mycircleList.get(i).startX - mycircleList.get(j).startX;
float y = mycircleList.get(i).startY - mycircleList.get(j).startY;
if (x * x + y * y < mycircleList.get(i).distance * distance * distance) {
canvas.drawLine(mycircleList.get(i).startX, mycircleList.get(i).startY,
mycircleList.get(j).startX, mycircleList.get(j).startY, mycircleList.get(i).paint);
}
}
}
//点击时候处理
if (isTouch) {
List<Mycircle> connect = new ArrayList<Mycircle>();
canvas.drawCircle(touchX, touchY, 5, paint);
for (int i = 0; i < mycircleList.size(); i++) {
float x = mycircleList.get(i).startX - touchX;
float y = mycircleList.get(i).startY - touchY;
if (x * x + y * y < 8 * distance * distance) {
canvas.drawLine(mycircleList.get(i).startX, mycircleList.get(i).startY,
touchX, touchY, mycircleList.get(i).paint);
connect.add(mycircleList.get(i));
}
}
for (int i = 0; i < connect.size(); i++) {
for (int k = connect.size() - 1; k > i; k--) {
float x = connect.get(i).startX - connect.get(k).startX;
float y = connect.get(i).startY - connect.get(k).startY;
if (x*x+y*y<10*distance*distance) {
canvas.drawLine(connect.get(i).startX, connect.get(i).startY,
connect.get(k).startX, connect.get(k).startY, connect.get(i).paint);
}
}
}
}
int x = width / 4;
int y = height / 4;
canvas.restore();
holder.unlockCanvasAndPost(canvas);
mHandler.removeCallbacks(mDrawCube);
if (mVisible) {
mHandler.postDelayed(mDrawCube, 10);
}
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(true);
}
public Mngine() {
paint = new Paint();
paint.setAntiAlias(true);
//设置颜色
paint.setColor(Color.WHITE);
//设置背景
//canvas.drawColor(Color.WHITE);
mycircleList = new ArrayList<Mycircle>();
Random random = new Random(System.currentTimeMillis());
for (int i = 0; i < count; i++) {
int distance = 1;
int alpha = random.nextInt(60) + 40;
float radius = this.radius * random.nextFloat() + 1.5f;
float startX = random.nextInt(1080);
float startY = random.nextInt(1920);
float speedX = speed - 2 * speed * random.nextFloat();
float speedY = speed - 2 * speed * random.nextFloat();
if (speedX == 0)
speedX = 0.5f;
if (speedY == 0)
speedY = -0.5f;
if (i % 50 == 0)
distance = 2;
else if (i % 30 == 0)
distance = 2;
else if (i % 20 == 0)
distance = 2;
if (radius < 0.7f)
distance = 0;
Mycircle mycircle = new Mycircle(radius, startX, startY, speedX, speedY, alpha, distance);
mycircleList.add(mycircle);
}
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mDrawCube);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
/*下面这个判断好玩,就是说,如果屏幕壁纸状态转为显式时重新绘制壁纸,否则黑屏幕,隐藏就可以*/
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(mDrawCube);
}
}
@Override
public void onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isTouch = true;
touchX = event.getX();
touchY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
isTouch = true;
touchX = event.getX();
touchY = event.getY();
break;
case MotionEvent.ACTION_UP:
isTouch = false;
touchX = -1;
touchY = -1;
break;
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
this.width = width;
this.height = height;
drawFrame();
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mDrawCube);
}
}
class Mycircle {
int distance;
Paint paint;
float radius;
float startX;
float startY;
float speedX;
float speedY;
int alpha;
public Mycircle(float radius, float startX, float startY, float speedX, float speedY, int alpha, int distance) {
this.radius = radius;
this.startX = startX;
this.startY = startY;
this.speedX = speedX;
this.speedY = speedY;
this.alpha = alpha;
paint = new Paint();
paint.setAntiAlias(true);
//设置颜色
paint.setColor(Color.WHITE);
paint.setAlpha(alpha);
this.distance = distance;
}
}
}
AndroidManifest中配置
<!--GIF动态壁纸-->
<service
android:enabled="true"
android:exported="true"
android:name=".display.wallpaper.helper.GifWallpaperService"
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/livewallpaper" />
</service>
<!--视频动态壁纸-->
<service
android:enabled="true"
android:exported="true"
android:name=".display.wallpaper.helper.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/livewallpaper" />
</service>
<!--静态壁纸,用来做中间跳板使用-->
<service
android:enabled="true"
android:exported="true"
android:name=".display.wallpaper.helper.MallpaperService"
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/livewallpaper" />
</service>
livewallpaper.xml
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity=".display.wallpaper.LiveWallPreference"
android:thumbnail="@mipmap/ic_launcher"
android:description="@string/display_wallpaper_desc" />
添加权限:
<uses-permission android:name="android.permission.BIND_WALLPAPER"/>
<uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT"/>
参考项目链接:
链接:https://pan.baidu.com/s/1_ukpxLJia_GQ-72xCj_TqA
提取码:c58f