一、获取桌面壁纸:
常用方法:
/**
* 获取桌面壁纸
*/
public Bitmap getWallpaperBitmap(Context context){
// 获取壁纸管理器
WallpaperManager wallpaperManager = WallpaperManager .getInstance(mContext);
// 获取当前壁纸
Drawable wallpaperDrawable = wallpaperManager.getDrawable();
// 将Drawable,转成Bitmap
Bitmap bm = ((BitmapDrawable) wallpaperDrawable).getBitmap();
return bm;
}
二、添加壁纸:
用系统自带的方法添加壁纸:
/**
* 列出所有Action含有Android.intent.action.SET_WALLPAPER的应用
*/
public void openWallparerApp(Context context){
//调用系统自带壁纸选择功能,ACTION_SET_WALLPAPER为选择的时候使用的过滤条件
Intent chooseIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
//启动系统选择应用
Intent intent = new Intent(Intent.ACTION_CHOOSER);
intent.putExtra(Intent.EXTRA_INTENT, chooseIntent);
intent.putExtra(Intent.EXTRA_TITLE, "选择壁纸");
startActivity(intent);
}
也可以用下面的方法:
public void openWallparerApp(Context context){
Intent chooseIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
startActivity(Intent.createChooser(chooseIntent, "选择壁纸"));
}
选择更换壁纸
/**
* 选择更换壁纸:使用Broadcast机制来通知壁纸已经更换。
* 当选择了一张壁纸后,系统会发出一个Broadcast,
* 同时选择的壁纸会被缓存在整个应用程序的上下文中,
* 不仅仅可以在桌面上更换,也可以在图片显示应用中更换。
* 在这里可以直接通过Application.getWallpaper();获取最新的壁纸
*/
class WallpaperIntentReceiver extends BroadcastReceiver{
private Application application;
//WeakReference使得WallpaperIntentReceiver不会因为Launcher的引用而被推迟注销掉
private WeakReference<UorderLauncher> rLauncher;
public WallpaperIntentReceiver(Application application, UorderLauncher launcher) {
this.application = application;
this.rLauncher = new WeakReference<UorderLauncher>(launcher);
}
public void setLauncher(UorderLauncher l){
this.rLauncher = new WeakReference<UorderLauncher>(l);
}
@Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "更换了壁纸");
/**
* 从ApplicationContext获取壁纸
*/
final Drawable lDrawable = application.getWallpaper();
if(lDrawable instanceof BitmapDrawable){
Log.v(TAG, "壁纸是BitmapDrawable类型的");
mWallpaper = ((BitmapDrawable)lDrawable).getBitmap();
}else{
throw new IllegalStateException("The wallpaper must be a BitmapDrawable object");
}
/**
* 如果此时Launcher是活动的,未被锁定,则加载新的Wallpaper
*/
if(rLauncher != null){
final UorderLauncher launcher = rLauncher.get();
if(launcher != null){
launcher.loadWallpaper();
}
}
}
}
注册:
private void registerIntentReceivers(){
if(mWallpaperReceiver == null){
mWallpaperReceiver = new WallpaperIntentReceiver(getApplication(), this);
/**
* 注册的时候,指定IntentFilter,这样改BroadcastReciver就是接收壁纸更换的Broadcast的了
*/
IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
getApplication().registerReceiver(mWallpaperReceiver, filter);
}else{
mWallpaperReceiver.setLauncher(this);
}
}
加载壁纸,需要重新绘制界面:
/**
* 这里加载壁纸,需要重新绘制界面
* @param wallpaper
*/
public void loadWallpaper(Bitmap wallpaper) {
wallpaperLoaded = true;
mWallpaper = wallpaper;
//要求重新绘制界面
requestLayout();
invalidate();
}
这个方法仅仅要求重新绘制布局,那么,我们就知道,在绘制的方法中,应该会对壁纸进行相关的绘制。在dispatchDraw中,有对壁纸的处理,
/**
* 壁纸本身可能并没有整个workspace那么宽
* 所以,屏幕滑动的时候,壁纸向右边滑动的距离需要根据mWallpaperOffset做相应的调整
*/
float x = getScrollX()*mWallpaperOffset;
//这里啥个意思,TODO:
Log.v(TAG, "getRight-getLeft="+getRight()+"-"+getLeft()+"="+(getRight()-getLeft()));
/**
* getRight()-getLeft()=手机屏幕的宽度
*/
if(x<getRight()-getLeft()-mWallpaperWidth){
//当壁纸宽度小于屏幕宽度的时候,才会出现小于的情况
//这种情况就固定
//但是在获得用户选择的壁纸的时候,我们对其作了大小调整,所以,这里基本不会出现这种情况
x = getRight()-getLeft()-mWallpaperWidth;
}
float y = (getBottom()-getTop()-mWallpaperHeight)/2;
Log.v(TAG, "开始画壁纸:x,y分别为:"+x+","+y);
//canvas.drawColor(Color.BLACK);
if(mWallpaper!=null){
Log.v(TAG, "开始画壁纸");
canvas.drawBitmap(mWallpaper, x, y, mPaint);
//invalidate();
}
通过canvas.drawBitmap(mWallpaper, x, y, mPaint);绘制了壁纸,这里关键的是x,y的计算,桌面可以横向滑动的,那么每次滑动后重新绘制的时候,这个x的值是在变化的,通过代码我们可以发现,其中有一个变量mWallpaperOffset,查找这个变量,在onMeasure中,对该变量进行了赋值:
//加载壁纸
if(wallpaperLoaded){
wallpaperLoaded = false;
mWallpaper = BitmapUtils.centerToFit(mWallpaper, width, height, getContext());
mWallpaperWidth = mWallpaper.getWidth();
mWallpaperHeight = mWallpaper.getHeight();
Log.v(TAG, "测量壁纸大小:"+mWallpaperWidth+","+mWallpaperHeight);
}
final int wallpaperWidth = mWallpaperWidth;
//计算Wallpaper每次随着屏幕滑动移动的距离
if(wallpaperWidth > width){
/**
* 计算壁纸滑动的速率
* 壁纸可以滑动的距离是count*width-wallpaperWidth
* 屏幕可以滑动的距离是(count-1)*width
* 这样,一除就是壁纸相对于屏幕滑动的速率了
*/
//mWallpaperOffset = wallpaperWidth/(count*(float)width);
mWallpaperOffset = (count*width-wallpaperWidth)/((count-1)*(float)width);
}else {
mWallpaperOffset = 1.0f;
}
Log.v(TAG, "wallpaper的offset:"+mWallpaperOffset);