默認鎖屏壁紙無效問題

Android O默認鎖屏壁紙無效

我們設置android默認壁紙的時候,會替換對應的資源文件,但是android O之後只能配置系統壁紙,鎖屏壁紙設置爲透明或設置與系統壁紙一樣,如果我們要像之前一樣單獨配置鎖屏壁紙需要修改WallpaperManager.關於Android O後面爲什麼不能設置鎖屏壁紙,源碼有下面的解釋:

frameowrks/base/core/java/android/app/WallpaperManager.java

 public static InputStream openDefaultWallpaper(Context context, @SetWallpaperFlags int which) {
        final String whichProp;
        final int defaultResId;
        if (which == FLAG_LOCK) {
            /* Factory-default lock wallpapers are not yet supported
            whichProp = PROP_LOCK_WALLPAPER;
            defaultResId = com.android.internal.R.drawable.default_lock_wallpaper;
            */
            return null;
        } else {
            whichProp = PROP_WALLPAPER;
            defaultResId = com.android.internal.R.drawable.default_wallpaper;
        }
      ........
        return null;
    }

openDefaultWallpaper方法有一個參數which,它只會有兩種類型FLAG_LOCK,FLAG_SYSTEM,分別代表這鎖屏壁紙和桌面壁紙(桌面壁紙在SysemUI應用裏面).但是源碼這裏有一個註解"Factory-default lock wallpapers are not yet supported",說明官方不支持設置默認鎖屏壁紙,經過發現,默認鎖屏就是默認桌面的壁紙,default_lock_wallpaper;是無效.

如果要實現單獨配置鎖屏和桌面壁紙,需要修改相關代碼,在修改之前需要了解加載流程.

默認壁紙加載相關的類

以展訊8.1爲例:
展訊8.1直接把默認壁紙透明話,只顯示桌面壁紙.從而省略了加載鎖屏壁紙的流程,提高了流暢度.所以我們需要先把這個開關打開.
frameowrks/base/package/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = SystemProperties.getBoolean("ro.lockwallpaper.enable", true);

加載鎖屏和默認壁紙有相關的4個類


	modified:   base/core/java/android/app/WallpaperManager.java
	modified:   base/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
	modified:   base/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
	modified:   base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java

功能 類,名 所屬
桌面壁紙(系統壁紙加載類) ImageWallpaper SystemUI
鎖屏壁紙加載類 LockscreenWallpaper SystemUI
壁紙加載服務類應用進程端 ImageWallpaper frameworks
壁紙加載服務類系統進程端 WallpaperManagerService frameworks

加載默認壁紙是在"壁紙加載服務類應用進程端"

默認壁紙加載流程

在這裏插入圖片描述加載默認壁紙是不會調用WallpaperManagerService,只在

在LockscreenWallpaperhe 和ImageWallpaper最終調用getBitmapAsUser如下所示

    public Bitmap getBitmap() {
        return getBitmapAsUser(mContext.getUserId());
    }

    /**
     * Like {@link #getDrawable()} but returns a Bitmap for the provided user.
     *
     * @hide
     */
    public Bitmap getBitmapAsUser(int userId) {
        return sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, userId);
    }

在getBitmapAsUser只會傳入FLAG_SYSTEM,見:peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, userId);所以要在加載鎖屏壁紙這個邏輯要修改(後面修改)

然後進入peekWallpaperBitmap,代碼如下

        public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
                @SetWallpaperFlags int which, int userId) {

            ....
            if (returnDefault) {
                Bitmap defaultWallpaper = mDefaultWallpaper;
                if (defaultWallpaper == null) {
;
                    defaultWallpaper = getDefaultWallpaper(context, which);
                    synchronized (this) {
                       mDefaultLockWallpaper = defaultWallpaper;
                    }
                }
                return defaultWallpaper;
            }
            return null;
        }

這個只有一個mDefaultLockWallpaper,所以在保存的時候只會保存一個,因爲要想鎖屏壁紙和系統壁紙都有效,必須分別加載,這裏也要修改.(後面修改)

最後到openDefaultWallpaper方法

    public static InputStream openDefaultWallpaper(Context context, @SetWallpaperFlags int which) {

       ....
        if (which == FLAG_LOCK) {
            /* Factory-default lock wallpapers are not yet supported*/
            whichProp = PROP_LOCK_WALLPAPER;
            defaultResId = com.android.internal.R.drawable.default_lock_wallpaper;
            return null;
            */
        } else {
            whichProp = PROP_WALLPAPER;
            defaultResId = com.android.internal.R.drawable.default_wallpaper;
        }
        final String path = SystemProperties.get(whichProp);
        if (!TextUtils.isEmpty(path)) {
            final File file = new File(path);
            if (file.exists()) {
                try {
                    return new FileInputStream(file);
                } catch (IOException e) {
                    // Ignored, fall back to platform default below
                }
            }
        }
        try {
            return context.getResources().openRawResource(defaultResId);
        } catch (NotFoundException e) {
            // no default defined for this device; this is not a failure
        }
        return null;
    }

which == FLAG_LOCK已經被註解了,需要去掉註解,去掉retrun null;(後面修改)

增加配置默認鎖屏壁紙功能

step 1 :打開鎖屏壁紙加載開關

SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
打開加載鎖屏壁紙開關

-    private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = SystemProperties.getBoolean("ro.lockwallpaper.enable", true);
+    private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
step 2 :修改加載鎖屏壁紙方式,使得加載與系統壁紙區分

SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
修改LockscreenWallpaper加載方式
在這裏插入圖片描述

  1. 需要註釋掉加載系統壁紙的代碼,因爲這裏是加載鎖屏壁紙
  2. 注意selectedUser有時候會null,我們只需要mCurrentUserId,selectedUser.getIdentifier()返回本身就是mCurrentUserId
  3. getLockBitmapAsUser方法是後面添加WallpaperManager中的.
step 3 : wallpaperManager加載鎖屏壁紙

base/core/java/android/app/WallpaperManager.java

在這裏插入圖片描述
上面方法是原來的加載的方法,現在只做系統壁紙加載,後面添加的方法做鎖屏壁紙加載

修改:WallpaperManager內部類Globals的方法peekWallpaperBitmap

在這裏插入圖片描述
在這裏插入圖片描述這樣就能保存鎖屏和系統兩種不同的默認壁紙了

修改:WallpaperManager內部類Globals的方法openDefaultWallpaper

在這裏插入圖片描述

按照如上修改,系統就能分別配置鎖屏和默認壁紙了

修改的patch

其他平臺和android版本修改應該大同小異

下面是3個文件的修改patch

diff --git a/base/core/java/android/app/WallpaperManager.java b/base/core/java/android/app/WallpaperManager.java
index 8a375cd44..2cb77e88d 100644
--- a/base/core/java/android/app/WallpaperManager.java
+++ b/base/core/java/android/app/WallpaperManager.java
@@ -284,6 +284,7 @@ public class WallpaperManager {
         private Bitmap mCachedWallpaper;
         private int mCachedWallpaperUserId;
         private Bitmap mDefaultWallpaper;
+        private Bitmap mDefaultLockWallpaper;
         private Handler mMainLooperHandler;
 
         Globals(Looper looper) {
@@ -393,6 +394,7 @@ public class WallpaperManager {
 
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
                 @SetWallpaperFlags int which, int userId) {
+
             if (mService != null) {
                 try {
                     if (!mService.isWallpaperSupported(context.getOpPackageName())) {
@@ -427,11 +429,15 @@ public class WallpaperManager {
                 }
             }
             if (returnDefault) {
-                Bitmap defaultWallpaper = mDefaultWallpaper;
+                Bitmap defaultWallpaper = (which == FLAG_LOCK) ? mDefaultLockWallpaper : mDefaultWallpaper;
                 if (defaultWallpaper == null) {
                     defaultWallpaper = getDefaultWallpaper(context, which);
                     synchronized (this) {
-                        mDefaultWallpaper = defaultWallpaper;
+                        if(which == FLAG_LOCK) {
+                            mDefaultLockWallpaper = defaultWallpaper;
+                        } else {
+                            mDefaultWallpaper = defaultWallpaper;
+                        }
                     }
                 }
                 return defaultWallpaper;
@@ -831,6 +837,17 @@ public class WallpaperManager {
         return sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM, userId);
     }
 
+    /**
+     * Like {@link #getDrawable()} but returns a Bitmap for the provided user.
+     *
+     * @hide
+     */
+    public Bitmap getLockBitmapAsUser(int userId) {
+        Log.i("wangcan","wallpapseManager-getLockBitmapAsUser FLAG_LOCK");
+        return sGlobals.peekWallpaperBitmap(mContext, true, FLAG_LOCK, userId);
+    }
+
+
     /**
      * Get an open, readable file descriptor to the given wallpaper image file.
      * The caller is responsible for closing the file descriptor when done ingesting the file.
@@ -1829,11 +1846,10 @@ public class WallpaperManager {
         final String whichProp;
         final int defaultResId;
         if (which == FLAG_LOCK) {
-            /* Factory-default lock wallpapers are not yet supported
+            /* Factory-default lock wallpapers are not yet supported*/
             whichProp = PROP_LOCK_WALLPAPER;
             defaultResId = com.android.internal.R.drawable.default_lock_wallpaper;
-            */
-            return null;
+            //return null;
         } else {
             whichProp = PROP_WALLPAPER;
             defaultResId = com.android.internal.R.drawable.default_wallpaper;
diff --git a/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index e44a47220..25993c55b 100644
--- a/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -109,10 +109,10 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen
                 selectedUser != null ? selectedUser.getIdentifier() : currentUserId;
         ParcelFileDescriptor fd = mWallpaperManager.getWallpaperFile(
                 WallpaperManager.FLAG_LOCK, lockWallpaperUserId);
-        if (fd == null && mBar.getPowerSaveModeInternal() == PowerManagerEx.MODE_ULTRASAVING) {
-            fd = mWallpaperManager.getWallpaperFile(
-                WallpaperManager.FLAG_SYSTEM, lockWallpaperUserId);
-        }
+        //if (fd == null && mBar.getPowerSaveModeInternal() == PowerManagerEx.MODE_ULTRASAVING) {
+        //    fd = mWallpaperManager.getWallpaperFile(
+        //        WallpaperManager.FLAG_SYSTEM, lockWallpaperUserId);
+        //}
         if (fd != null) {
             try {
                 BitmapFactory.Options options = new BitmapFactory.Options();
@@ -128,11 +128,13 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen
             if (selectedUser != null) {
                 // Show the selected user's static wallpaper.
                 return LoaderResult.success(
-                        mWallpaperManager.getBitmapAsUser(selectedUser.getIdentifier()));
+                        mWallpaperManager.getLockBitmapAsUser(selectedUser.getIdentifier()));
 
             } else {
                 // When there is no selected user, show the system wallpaper
-                return LoaderResult.success(null);
+                //return LoaderResult.success(null);
+                return LoaderResult.success(
+                        mWallpaperManager.getLockBitmapAsUser(mCurrentUserId));
             }
         }
     }
diff --git a/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 22d0bed37..b9ee91f84 100644
--- a/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -381,7 +381,7 @@ public class StatusBar extends SystemUI implements DemoMode,
     private static final boolean ONLY_CORE_APPS;
 
     /** If true, the lockscreen will show a distinct wallpaper */
-    private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = SystemProperties.getBoolean("ro.lockwallpaper.enable", true);
+    private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
 
     /* If true, the device supports freeform window management.
      * This affects the status bar UI. */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章