天天看点

Android客制化------7.0设置壁纸存在的一些问题

最近在开7.0的坑,遇到了一些小问题,记录一下。很大可能这个问题只是我这个芯片的代码上才存在的,不过殊途同归啦。

第一个问题就是,我们增加内置可选壁纸,选择这些壁纸后进行设置,会发现拉伸很明显。通过增加打印log发现

diff --git a/src/com/android/wallpaperpicker/WallpaperCropActivity.java b/src/com/android/wallpaperpicker/WallpaperCropActivity.java
old mode 
new mode 
index bdb601b.d1551
--- a/src/com/android/wallpaperpicker/WallpaperCropActivity.java
+++ b/src/com/android/wallpaperpicker/WallpaperCropActivity.java
@@ -, +, @@ public class WallpaperCropActivity extends Activity implements Handler.Callback
         Point inSize = mCropView.getSourceDimensions();
         Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(),
                 getWindowManager());
+               android.util.Log.d(LOGTAG,"inSize.x = " + inSize.x + " inSize.y = " + inSize.y
+                       + " outSize.x = " + outSize.x + " outSize.y = " + outSize.y);
         RectF crop = Utils.getMaxCropRect(
                 inSize.x, inSize.y, outSize.x, outSize.y, false);
         // Passing 0, 0 will cause launcher to revert to using the
         // default wallpaper size
         CropAndFinishHandler onEndCrop = new CropAndFinishHandler(new Point(, ),
                 shouldFadeOutOnFinish);
         CropAndSetWallpaperTask cropTask = new CropAndSetWallpaperTask(
                 streamProvider, this, crop, streamProvider.getRotationFromExif(this),
                 outSize.x, outSize.y, onEndCrop);
         DialogUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener());
     }
           

我们的壁纸尺寸是1024*600,log打印的inSize都是正确的,但是outSize却变成了1200*1024了,由此产生了壁纸设置后有拉伸的情况。

Android客制化------7.0设置壁纸存在的一些问题
Android客制化------7.0设置壁纸存在的一些问题

因此问题就是出在这个Size的变化上,我们继续跟踪源码,会发现

diff --git a/src/com/android/wallpaperpicker/WallpaperUtils.java b/src/com/android/wallpaperpicker/WallpaperUtils.java
old mode 
new mode 
index .a4d88d7
--- a/src/com/android/wallpaperpicker/WallpaperUtils.java
+++ b/src/com/android/wallpaperpicker/WallpaperUtils.java
@@ -, +, @@ public final class WallpaperUtils {

             // We need to ensure that there is enough extra space in the wallpaper
             // for the intended parallax effects
-            final int defaultWidth, defaultHeight;
+            int defaultWidth, defaultHeight;
             if (res.getConfiguration().smallestScreenWidthDp >= ) {
                 defaultWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
                 defaultHeight = maxDim;
@@ -, +, @@ public final class WallpaperUtils {
                 defaultWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
                 defaultHeight = maxDim;
             }
+                       android.util.Log.d("WallpaperCropActivity"," res.getConfiguration().smallestScreenWidthDp = "
+                       + res.getConfiguration().smallestScreenWidthDp + " defaultWidth = " + defaultWidth
+                               + " minDim =" + minDim + " maxDim =" + maxDim);
+            defaultWidth = maxDim;
+            defaultHeight = minDim;
             sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight);
         }
         return sDefaultWallpaperSize;
           

问题的根源就是这个defaultWidth和defaultHeight啦。继续打印log发现maxDim和minDim就是我们正确的壁纸尺寸,这两个变量都是final的更改下修饰符,同时将最终设置的尺寸更改为正确的,辣么设置的壁纸的拉伸问题就暂时解决了。

第二个问题,就是设置sd卡中的图片作为壁纸,这个东西源码分析的过程比较复杂。可以通过dumpsys wallpaper以及dumpsys SurfaceFlinger来查看图片的设置尺寸。更改的地方涉及三处。分别是launcher3、framework/base/core以及SystemUI。

packages/apps/Launcher3
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index ..ecd3ad6 
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -, +, @@ public class InvariantDeviceProfile {
                     (int) (largeSide * wallpaperTravelToScreenWidthRatio(largeSide, smallSide)),
                     largeSide);
         } else {
-            defaultWallpaperSize = new Point(Math.max(smallSide * , largeSide), largeSide);
+            defaultWallpaperSize = new Point(largeSide, largeSide);
         }
     }

frameworks/base
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -, +, @@ import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.WindowManager;
 import android.view.WindowManagerGlobal;

 import libcore.io.IoUtils;
@@ -, +, @@ public class WallpaperManager {
                 mCachedWallpaper = null;
                 mCachedWallpaperUserId = ;
                 try {
-                    mCachedWallpaper = getCurrentWallpaperLocked(userId);
+                    mCachedWallpaper = getCurrentWallpaperLocked(context,userId);
                     mCachedWallpaperUserId = userId;
                 } catch (OutOfMemoryError e) {
                     Log.w(TAG, "No memory load current wallpaper", e);
@@ -, +, @@ public class WallpaperManager {
           }
         }

-        private Bitmap getCurrentWallpaperLocked(int userId) {
+        private Bitmap getCurrentWallpaperLocked(Context context,int userId) {
             if (mService == null) {
                 Log.w(TAG, "WallpaperService not running");
                 return null;
@@ -, +, @@ public class WallpaperManager {
                         params, userId);
                 if (fd != null) {
                     try {
+                       WindowManager mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+                       int wW = mWindowManager.getDefaultDisplay().getWidth();
+                       int wH = mWindowManager.getDefaultDisplay().getHeight();
                         BitmapFactory.Options options = new BitmapFactory.Options();
+                       options.inJustDecodeBounds = true;
+                       BitmapFactory.decodeFileDescriptor(
+                               fd.getFileDescriptor(), null, options);
+                       options.inSampleSize = calculateInSampleSize(options, wW,wH);
+                       options.inJustDecodeBounds = false;
                         return BitmapFactory.decodeFileDescriptor(
                                 fd.getFileDescriptor(), null, options);
                     } catch (OutOfMemoryError e) {
@@ -, +, @@ public class WallpaperManager {
             return null;
         }

+        private int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight){
+                  int width = options.outWidth;
+                  int height = options.outHeight;
+                  int inSampleSize = ;
+                  if (width > reqWidth && height > reqHeight){
+                int widthRatio = Math.round((float) width / (float) reqWidth);
+                int heightRatio = Math.round((float) width / (float) reqWidth);
+                inSampleSize = Math.max(widthRatio, heightRatio);
+                  }
+                  return inSampleSize;
+        }
+
         private Bitmap getDefaultWallpaper(Context context, @SetWallpaperFlags int which) {
+            WindowManager mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+            int wW = mWindowManager.getDefaultDisplay().getWidth();
+            int wH = mWindowManager.getDefaultDisplay().getHeight();
             InputStream is = openDefaultWallpaper(context, which);
             if (is != null) {
                 try {
                     BitmapFactory.Options options = new BitmapFactory.Options();
+                    options.inJustDecodeBounds = true;
+                    BitmapFactory.decodeStream(is, null, options);
+                    options.inSampleSize = calculateInSampleSize(options, wW,wH);
+                    options.inJustDecodeBounds = false;
                     return BitmapFactory.decodeStream(is, null, options);
                 } catch (OutOfMemoryError e) {
                     Log.w(TAG, "Can't decode stream", e);



diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index c88931d..fecc47e 
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -, +, @@ public class ImageWallpaper extends WallpaperService {
                 surfaceHeight = Math.max(displayInfo.logicalHeight, mBackgroundHeight);
             }

-            if (FIXED_SIZED_SURFACE) {
+           //Log.d(TAG,"----surfaceWidth = "+surfaceWidth+" surfaceHeight= "+surfaceHeight);
+            /*if (FIXED_SIZED_SURFACE) {
                 // Used a fixed size surface, because we are special.  We can do
                 // this because we know the current design of window animations doesn't
                 // cause this to break.
                 surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight);
                 mLastRequestedWidth = surfaceWidth;
                 mLastRequestedHeight = surfaceHeight;
-            } else {
+            } else*/ {
                 surfaceHolder.setSizeFromLayout();
             }
             return hasWallpaper;