注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

北漂的小羊

Java编程,开发者,程序员,软件开发,编程,代码。新浪微博号:IT国子监

 
 
 

日志

 
 
关于我

在这里是面向程序员的高品质IT技术学习社区,是程序员学习成长的地方。让我们更好地用技术改变世界。请关注新浪微博号: IT国子监(http://weibo.com/itguozijian)

网易考拉推荐

android setWallpaper 设置手机壁纸  

2013-02-26 17:47:26|  分类: Android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
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; 
        } 
    } 


设置手机背景很简单,只要重写系统的setWallpaper()方法,再调用它即可。
setWallPaper()方法有两种参数类型:
★setWallpaper(Bitmap bitmap)
★setWallpaper(InputStream data)
现在来一个一个举例:
1、setWallpaper(Bitmap bitmap):
eg: Bitmap bitmap = BitmapFactory.decodeFile(path);
    try
       {
           setWallpaper(bitmap);
       } catch (Exception e)
       {
          // TODO: handle exception
       }
    @Override
    public void setWallpaper(InputStream data) throws IOException {
        // TODO Auto-generated method stub
        super.setWallpaper(data);
    }
注:path为文件地址。
    生成Bitmap对象类型的方法有很多,只要setWallPaper()参数为Bitmap类型即可。
2、setWallpaper(InputStream data)
eg: Resources resources = getBaseContext().getResources();
     InputStream is = resources.openRawResource(R.drawable.icon);
     try
       {
          setWallpaper(is);         
        } catch (Exception e)
       {
          // TODO: handle exception
        }
    @Override
    public void setWallpaper(InputStream data) throws IOException {
        // TODO Auto-generated method stub
        super.setWallpaper(data);
    }
注:一定要记得在Android Manifest.xml中加入下面语句,声明拥有修改壁纸的权限,不然setWallPaper()方法不起作用
<uses-permission android:name="android.permission.SET_WALLPAPER" />

  评论这张
 
阅读(877)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016