Android SetWallpaper

[size=medium]Android setWallpaper涉及到以及几个文件:[/size]
[b]Laucher.java[/b]
注册Wallpaper change Receiver
[b]Workspace.java[/b]
加载壁纸
[b]WallpaperChoose.java[/b]
发起Setwallpaper
[b]Context.java
[/b]SetWallper的原始接口
[b]ContextWrapper.java[/b]
继承Context
[b]ApplicationContext.java[/b]
继承Context实现SetWallper
[b]WallpaperService.java[/b]
Wallpaper 的一个serivce发出壁纸改变通知Launcher
[b]IWallpaperService.aidl-->WallpaperService.java[/b]
IWallpaperServiceCallback.aidle-->ApplicationContext.java


[color=red]Activity:-- Launcher.WallpaperChoose.java[/color]

InputStream stream = getResources().openRawResource(mImages.get(position));
setWallpaper(stream);

Context.java

public abstract void setWallpaper(InputStream data) throws IOException;

[color=red]ContextWrapper.java[/color]
[color=red]public class ContextWrapper extends Context[/color]

@Override
public void setWallpaper(InputStream data) throws IOException {
mBase.setWallpaper(data);
}


ApplicationContext.java
class ApplicationContext extends Context
@Override
public void setWallpaper(InputStream data) throws IOException {
try {
ParcelFileDescriptor fd = [color=blue]getWallpaperService().setWallpaper();[/color]
if (fd == null) {
return;
}
FileOutputStream fos = null;
try {
fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
setWallpaper(data, fos);
} finally {
if (fos != null) {
fos.close();
}
}
} catch (RemoteException e) {
}
}

private void setWallpaper(InputStream data, FileOutputStream fos)
throws IOException {
byte[] buffer = new byte[32768];
int amt;
while ((amt=data.read(buffer)) > 0) {
fos.write(buffer, 0, amt);
}
}


[color=red]WallpaperService.java[/color]
class WallpaperService extends IWallpaperService.Stub

public ParcelFileDescriptor setWallpaper() {
checkPermission(android.Manifest.permission.SET_WALLPAPER);
try {
ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE,
MODE_CREATE|MODE_READ_WRITE);

// changing the wallpaper means we'll need to back up the new one
long origId = Binder.clearCallingIdentity();
BackupManager bm = new BackupManager(mContext);
bm.dataChanged();
Binder.restoreCallingIdentity(origId);

return fd;
} catch (FileNotFoundException e) {
if (Config.LOGD) Log.d(TAG, "Error setting wallpaper", e);
}
return null;
}


private final [color=blue]FileObserver[/color] mWallpaperObserver = new FileObserver(
WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE) {
@Override
public void onEvent(int event, String path) {
if (path == null) {
return;
}

File changedFile = new File(WALLPAPER_DIR, path);
if (WALLPAPER_FILE.equals(changedFile)) {
[color=blue]notifyCallbacks()[/color];
}
}
};


private void notifyCallbacks() {
final int n = mCallbacks.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
[color=blue]mCallbacks.getBroadcastItem(i).onWallpaperChanged();[/color]
} catch (RemoteException e) {

// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
mCallbacks.finishBroadcast();
[color=blue]final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
mContext.sendBroadcast(intent);[/color]
}


[color=red]Launcher.java[/color]

private static class WallpaperIntentReceiver extends BroadcastReceiver {
private final Application mApplication;
private WeakReference<Launcher> mLauncher;

WallpaperIntentReceiver(Application application, Launcher launcher) {
mApplication = application;
setLauncher(launcher);
}

void setLauncher(Launcher launcher) {
mLauncher = new WeakReference<Launcher>(launcher);
}

@Override
public void onReceive(Context context, Intent intent) {
// Load the wallpaper from the ApplicationContext and store it locally
// until the Launcher Activity is ready to use it
final Drawable drawable = mApplication.getWallpaper();
if (drawable instanceof BitmapDrawable) {
sWallpaper = ((BitmapDrawable) drawable).getBitmap();
} else {
throw new IllegalStateException("The wallpaper must be a BitmapDrawable.");
}

// If Launcher is alive, notify we have a new wallpaper
if (mLauncher != null) {
final Launcher launcher = mLauncher.get();
if (launcher != null) {
[color=red]launcher.loadWallpaper();[/color]
}
}
}
}


private void loadWallpaper() {
// The first time the application is started, we load the wallpaper from
// the ApplicationContext
if (sWallpaper == null) {
final Drawable drawable = getWallpaper();
if (drawable instanceof BitmapDrawable) {
sWallpaper = ((BitmapDrawable) drawable).getBitmap();
} else {
throw new IllegalStateException("The wallpaper must be a BitmapDrawable.");
}
}
[color=blue] mWorkspace.loadWallpaper(sWallpaper);[/color]
}


[color=red]Workspace.java[/color]
void loadWallpaper(Bitmap bitmap) {
mWallpaper = bitmap;
mWallpaperLoaded = true;
requestLayout();
invalidate();
}


@Override
protected void dispatchDraw(Canvas canvas) {
boolean restore = false;

// If the all apps drawer is open and the drawing region for the workspace
// is contained within the drawer's bounds, we skip the drawing. This requires
// the drawer to be fully opaque.
if (mLauncher.isDrawerUp()) {
final Rect clipBounds = mClipBounds;
canvas.getClipBounds(clipBounds);
clipBounds.offset(-mScrollX, -mScrollY);
if (mDrawerBounds.contains(clipBounds)) {
return;
}
} else if (mLauncher.isDrawerMoving()) {
restore = true;
canvas.save(Canvas.CLIP_SAVE_FLAG);

final View view = mLauncher.getDrawerHandle();
final int top = view.getTop() + view.getHeight();

canvas.clipRect(mScrollX, top, mScrollX + mDrawerContentWidth,
top + mDrawerContentHeight, Region.Op.DIFFERENCE);
}

float x = mScrollX * mWallpaperOffset;
if (x + mWallpaperWidth < mRight - mLeft) {
x = mRight - mLeft - mWallpaperWidth;
}

canvas.drawBitmap(mWallpaper, x, (mBottom - mTop - mWallpaperHeight) / 2, mPaint);

// ViewGroup.dispatchDraw() supports many features we don't need:
// clip to padding, layout animation, animation listener, disappearing
// children, etc. The following implementation attempts to fast-track
// the drawing dispatch by drawing only what we know needs to be drawn.

boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;
// If we are not scrolling or flinging, draw only the current screen
if (fastDraw) {
drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());
} else {
final long drawingTime = getDrawingTime();
// If we are flinging, draw only the current screen and the target screen
if (mNextScreen >= 0 && mNextScreen < getChildCount() &&
Math.abs(mCurrentScreen - mNextScreen) == 1) {
drawChild(canvas, getChildAt(mCurrentScreen), drawingTime);
drawChild(canvas, getChildAt(mNextScreen), drawingTime);
} else {
// If we are scrolling, draw all of our children
final int count = getChildCount();
for (int i = 0; i < count; i++) {
drawChild(canvas, getChildAt(i), drawingTime);
}
}
}

if (restore) {
canvas.restore();
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

final int width = MeasureSpec.getSize(widthMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
}

final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
}

// The children are given the same width and height as the workspace
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}

if (mWallpaperLoaded) {
mWallpaperLoaded = false;
mWallpaper = Utilities.centerToFit(mWallpaper, width,
MeasureSpec.getSize(heightMeasureSpec), getContext());
mWallpaperWidth = mWallpaper.getWidth();
mWallpaperHeight = mWallpaper.getHeight();
}

final int wallpaperWidth = mWallpaperWidth;
mWallpaperOffset = wallpaperWidth > width ? (count * width - wallpaperWidth) /
((count - 1) * (float) width) : 1.0f;

if (mFirstLayout) {
scrollTo(mCurrentScreen * width, 0);
mFirstLayout = false;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值