android6.0 壁纸设置流程讲解

来源:互联网 发布:淘宝如何办理退货 编辑:程序博客网 时间:2024/06/06 09:28

主要以在launcher界面长按点击wallpaper按钮来设置壁纸的流程。

当我们点击wallpaper按钮后进入WallpaperPickerActivity.java界面,分三块上为设置按钮,中为将要设置的wallpaper图片,下为所有壁纸的缩略图。

选择好壁纸后点击设置按钮

 /packages/apps/Launcher3/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java        // Action bar        // Show the custom action bar view        final ActionBar actionBar = getActionBar();        actionBar.setCustomView(R.layout.actionbar_set_wallpaper);        actionBar.getCustomView().setOnClickListener(                new View.OnClickListener() {                    @Override                    public void onClick(View v) {                    // Ensure that a tile is slelected and loaded.                        if (mSelectedTile != null && mCropView.getTileSource() != null) {                            // Prevent user from selecting any new tile.                            mWallpaperStrip.setVisibility(View.GONE);                            actionBar.hide();                            WallpaperTileInfo info = (WallpaperTileInfo) mSelectedTile.getTag();                            info.onSave(WallpaperPickerActivity.this);//接着这个方法                        } else {                            // no tile was selected, so we just finish the activity and go back                            setResult(Activity.RESULT_OK);                            finish();                             }                    }                });        mSetWallpaperButton = findViewById(R.id.set_wallpaper_button);

上面这个方法调用FileWallpaperInfo中的onSave方法

<pre name="code" class="java"> /packages/apps/Launcher3/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java@FileWallpaperInfo
@Override
public void onSave(WallpaperPickerActivity a)
{ a.setWallpaper(Uri.fromFile(mFile), true);//该setWallpaper在WallpaperCropActivity.java中实现

由上转入WallpaperCropActivity.java的setWallpaper()方法。

/packages/apps/Launcher3/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java

protected void setWallpaper(Uri uri, final boolean finishActivityWhenDone) {int rotation = BitmapUtils.getRotationFromExif(getContext(), uri);BitmapCropTask cropTask = new BitmapCropTask( getContext(), uri, null, rotation, 0, 0, true, false, null);//该task是图片处理与切割关键final Point bounds = cropTask.getImageBounds();Runnable onEndCrop = new Runnable() {    public void run() {      updateWallpaperDimensions(bounds.x, bounds.y);     if (finishActivityWhenDone) {        setResult(Activity.RESULT_OK);        finish();      } } };      cropTask.setCropSize(bounds.x, bounds.y);        cropTask.setOnEndRunnable(onEndCrop);        cropTask.setNoCrop(true);        cropTask.execute();     } 


由上转入BitmapCropTask.java,具体代码就不全贴出,关键看cropBitmap()里的wallpaperManager.setStream(is);调用

/packages/apps/Launcher3/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.javapublic boolean cropBitmap() {        boolean failure = false;        ... ... ...        wallpaperManager.setStream(is);        ... ... ...} 

我们看到最后通过流数据写入,将图片资源写入到wallpaper文件里面。具体实现我们转到wallpaperManager.java这个类

/frameworks/base/core/java/android/app/wallpaperManager.javapublic void setStream(InputStream data) throws IOException {        if (sGlobals.mService == null) {            Log.w(TAG, "WallpaperService not running");            return;        }        try {            ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,                    mContext.getOpPackageName());//这个service调用是关键,获取wallpaper文件载体            if (fd == null) {                return;            }            FileOutputStream fos = null;            try {                fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);                setWallpaper(data, fos);//获取到wallpaper文件载体后往里面写如数据                } finally {                if (fos != null) {                    fos.close();                }            }        } catch (RemoteException e) {            // Ignore        }    }        private void setWallpaper(InputStream data, FileOutputStream fos)//往wallpaper文件载体里面写数据            throws IOException {        byte[] buffer = new byte[32768];        int amt;        while ((amt=data.read(buffer)) > 0) {            fos.write(buffer, 0, amt);        }    }    

我们看到上面有一个ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,mContext.getOpPackageName());,该setWallpaper实现在WallpaperManagerService.java中实现,由于是远程service调用所以这里用到aidl.具体接口声明在

frameworks/base/core/java/android/app/IWallpaperManagerCallback.aidl,这里不列出。


public ParcelFileDescriptor setWallpaper(String name, String callingPackage) {        checkPermission(android.Manifest.permission.SET_WALLPAPER);        if (!isWallpaperSupported(callingPackage)) {            return null;        }        synchronized (mLock) {            if (DEBUG) Slog.v(TAG, "setWallpaper");            // /M: To support Smart Book @ {            if (isSmartBookSupport()) {                mHaveUsedSmartBook = false;            }            // /@ }            int userId = UserHandle.getCallingUserId();            WallpaperData wallpaper = getWallpaperSafeLocked(userId);            final long ident = Binder.clearCallingIdentity();            try {                ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);                if (pfd != null) {                    wallpaper.imageWallpaperPending = true;                }               return pfd;            } finally {                Binder.restoreCallingIdentity(ident);            }        }    }    ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {        if (name == null) name = "";        try {            File dir = getWallpaperDir(wallpaper.userId);            if (!dir.exists()) {                dir.mkdir();                FileUtils.setPermissions(                        dir.getPath(),                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,                        -1, -1);            }            File file = new File(dir, mWallpaperFileName);            ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,                    MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE);            if (!SELinux.restorecon(file)) {                return null;            }            wallpaper.name = name;            return fd;        } catch (FileNotFoundException e) {            Slog.w(TAG, "Error setting wallpaper", e);        }        return null;    }private static File getWallpaperDir(int userId) {        return Environment.getUserSystemDirectory(userId);    }






1 0
原创粉丝点击