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



Activity:-- Launcher.WallpaperChoose.java

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

Context.java

public abstract void setWallpaper(InputStream data) throws IOException;

ContextWrapper.java
public class ContextWrapper extends Context

@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 =getWallpaperService().setWallpaper();
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);
}
}




WallpaperService.java
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 finalFileObserver 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)) {
notifyCallbacks();
}
}
};




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

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

}



Launcher.java

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) {
launcher.loadWallpaper();
}
}
}
}


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.");
}
}
mWorkspace.loadWallpaper(sWallpaper);
}



Workspace.java
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;
}
}








更多相关文章

  1. ListView中使用线程实现无限加载
  2. 利用View.inflate加载xml
  3. Android JNI学习笔记——so文件动态加载
  4. Android类加载器源码分析
  5. Android实现ListView异步加载图片
  6. Android应用开发提高系列(5)——Android动态加载(下)——加载已安装A
  7. Android Eclipse JNI 调用 .so文件加载
  8. Android Activity四种加载方式

随机推荐

  1. Android(安卓)MimeType和MimeTypeMap的介
  2. Android(安卓)中文api (81)——InputMeth
  3. Android短信的发送和广播接收者实现短信
  4. android开发每日汇总【2011-11-02】
  5. Textview基本属性及功能
  6. 解决 Android(安卓)模拟器 无法上网问题
  7. Android带播放进度条的音乐播放器
  8. android 上调试动态库方法
  9. Android一些好的资源
  10. Android音频架构解析