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 final
FileObserver 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;
}
}
分享到:
相关推荐
考虑到Android设备的多样性和版本差异,SetWallPaper可能包含了针对不同API级别的兼容性代码,以确保在多个Android版本上都能正常运行。 10. **版本控制和构建工具** 开发过程中,源码可能使用Git进行版本控制,...
"Gallery与setWallpaper"涉及到了从图库应用(Gallery)选择图片并将其设置为壁纸的过程。在这个过程中,开发者通常需要利用Android提供的API来实现这一功能。下面我们将深入探讨这个主题。 首先,Android的Gallery...
在Android开发中,设置壁纸是一项常见的功能,但考虑到国内各种定制化的ROM(如MIUI、EMUI、...此外,SetWallpaper-master 这个项目可能包含了一个示例工程,可以作为参考,研究其源码以了解更多细节和具体实现。
用户可以选择应用内的图片,并通过调用`setWallpaper(Bitmap)`或`setStream(InputStream)`方法将图片设置为壁纸。为了提供这一功能,开发者可能还会实现一个选择器界面,允许用户选择要设为壁纸的图片。 图片下载...
Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1...
Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1...
Google Android SDK开发范例大全(完整版)共4个分卷 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1...
这个界面通常是一个`Activity`,用户在其中点击按钮触发`WallpaperManager`的`setWallpaper()`或`setLiveWallpaper()`方法,将你的动态壁纸应用到手机上。 8. **性能优化**:由于动态壁纸会在后台持续运行,所以...
8.10 远程下载桌面背景图案——URLConnection与setWallpaper()搭配 8.11 将手机文件上传至网站服务器——模拟HTTPFORM的POSTACTION 8.12 移动博客发布器——以XML-RPC达成远程过程调用 8.13 移动RSS阅读器——利用...
2.2 建立第一个Android项目(HelloAndroid!) 2.3 Android应用程序架构——从此开始 2.4 可视化的界面开发工具 2.5 部署应用程序到Android手机 第3章 用户人机界面 3.1 更改与显示文字标签——TextView标签的使用 ...
在应用内部,你可以提供一个设置入口,调用`WallpaperManager`的`setWallpaper()`或`setLiveWallpaper()`方法来设置屏保。 7. **文件名列表`PhotoTable`**:这个文件名可能指的是存储照片数据的数据库表,用于记录...
Google Android SDK开发范例大全(完整版) 包含部分书中源码 目录 第1章 了解.深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 ...
通过调用其 setWallpaper() 或 setBitmap() 方法,应用能够将指定的图片设置为设备的锁屏或主屏幕壁纸。如果"sw"应用还支持动态壁纸,那么它可能利用了LiveWallpaper服务,这是一种特殊的壁纸类型,能够在屏幕上显示...
Android 设置手机屏幕壁纸,不能就是大家熟悉的桌面背景,点击按钮,即可更换手机背景图片,整个功能的实现,封装在一个按钮事件中,以下是相关的代码片段: Button bbjt;//设置背景图按钮 EditText etwz;//网站...
用户选择壁纸后,可以调用 WallpaperManager 类的 setWallpaper() 或 setLiveWallpaper() 方法来设置壁纸。前者用于静态壁纸,后者用于动态壁纸。如果需要支持更换锁屏壁纸,同样需要调用 WallpaperManager 的相应...
3. **设置壁纸**:Android提供了`setWallpaper()`方法,通过`Context`对象调用,将`Bitmap`对象设置为壁纸。有三个不同类型的壁纸可以设置:主屏幕壁纸、锁屏壁纸和联系人壁纸,分别对应` WallpaperManager`的`...
6. **设置和配置**:在`setWallpaper()`或`setLiveWallpaper()`方法中,用户可以将你的动态壁纸设置为当前壁纸。同时,你还可以提供一个设置界面让用户自定义壁纸的参数。 7. **优化性能**:由于动态壁纸一直在后台...
在Android开发中,设置桌面背景图片是常见的需求之一,它涉及到对用户界面的自定义以及权限管理。下面将详细介绍如何实现这一功能。 首先,我们来看标题和描述中提到的实现方法。Android系统允许应用程序设置壁纸,...