anndroid6.0锁屏壁纸

 

锁屏壁纸 的保存位置在/data/system/users/0 

root@**:/data/system/users/0 # ls -la
-rw-rw---- system system 73728 1970-01-14 09:26 accounts.db
-rw------- system system 8720 1970-01-14 09:26 accounts.db-journal
-rw------- system system 406 2017-03-03 18:52 appwidgets.xml
drwx------ system system 1970-01-14 09:26 fpdata
-rwx------ system system 1525422 2017-03-06 11:57 lock_wallpaper
-rw------- system system 149 2017-03-06 11:57 lock_wallpaper_info.xml
-rw------- system system 1550 2017-03-05 16:56 notificationSubscript.xml

-rw-rw---- system system 4153 2017-03-06 15:09 package-restrictions.xml
drwxrwx--x system system 1970-01-14 09:26 registered_services
-rw------- system system 16990 2017-03-06 14:06 runtime-permissions.xml
-rw------- system system 7032 2017-03-06 09:07 settings_global.xml
-rw------- system system 5090 2017-03-06 09:07 settings_secure.xml
-rw------- system system 6148 2017-03-06 15:11 settings_system.xml
-rwx------ system system 1525422 2017-03-06 11:57 wallpaper
-rw------- system system 99 2017-03-06 11:57 wallpaper_info.xml
root@**:/data/system/users/0 # pwd
/data/system/users/0

 

详http://blog.csdn.net/sssheiye/article/details/52052544

 

gallery入口选择图片设置为锁屏壁纸

方案:

1:在data/system/users/0/这个目录建立一个存放锁屏图片资源的文件lockwallpaper

2:将gallery选择的图片保存当锁屏时调用该保存的图片资源

3:将图片资源作为SystemUI中NotificationPanelView的背景

 

 

第一,二步:放在一块讲

我们知道桌面壁纸是把图片存在/data/system/users/0/wallpaper 里面,所以我们要想办法在这个目录建立一个lockwallpaper。

实现相关代码路径:

frameworks/base/core/Java/Android/app/WallpaperManager.java

frameworks/base/core/java/android/app/IWallpaperManagerCallback.aidl

frameworks/base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. frameworks/base/core/java/android/app/WallpaperManager.java  
  2.   
  3. public class WallpaperManager {  
  4.     private static String TAG = "WallpaperManager";  
  5.     ... ...  
  6.   //{hss add for lockscreen wallpaper start  
  7.     private static final String WALLPAPERDIR = "/data/system/users/0";  
  8.     static final String LOCKWALLPAPERNAME = "lockwallpaper";  
  9.   
  10.     private final Context mContext;  
  11.   
  12.     <... ... ...>  
  13.     /** 
  14.      * Retrieve the current system wallpaper; if 
  15.      * no wallpaper is set, the system built-in static wallpaper is returned. 
  16.      * This is returned as an 
  17.      * abstract Drawable that you can install in a View to display whatever 
  18.      * wallpaper the user has currently set.  
  19.      * 
  20.      * @return Returns a Drawable object that will draw the wallpaper. 
  21.      */  
  22.       public Drawable getDrawable() {//获取wallpaper资源  
  23.         Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true);  
  24.         if (bm != null) {  
  25.             Drawable dr = new BitmapDrawable(mContext.getResources(), bm);  
  26.             dr.setDither(false);  
  27.             return dr;  
  28.         }  
  29.         return null;  
  30.     }    
  31.   
  32.     //hss add for lockscreen wallpaper start 模仿桌面壁纸获取Drrawable资源  
  33.     public Drawable getLockScreenDrawable() {  
  34.         Bitmap bm = sGlobals.getCurrentLockScreenWallpaperLocked(mContext);  
  35.         if (bm != null) {  
  36.             Drawable dr = new BitmapDrawable(mContext.getResources(), bm);  
  37.             dr.setDither(false);  
  38.             return dr;  
  39.         }  
  40.         return null;  
  41.     }  
  42.     <... ... ...>  
  43. static class Globals extends IWallpaperManagerCallback.Stub {//内部类  
  44.         private IWallpaperManager mService;  
  45.         private Bitmap mWallpaper;  
  46.         private Bitmap mDefaultWallpaper;  
  47.           
  48.         private static final int MSG_CLEAR_WALLPAPER = 1;  
  49. <pre name="code" class="java"><... ... ...>  
  50.          private Bitmap getCurrentWallpaperLocked(Context context) {//hss find 获取当前的wallpaper  
  51.             if (mService == null) {  
  52.                 Log.w(TAG, "WallpaperService not running");  
  53.                 return null;  
  54.             }  
  55.   
  56.             try {  
  57.                 Bundle params = new Bundle();  
  58.                 ParcelFileDescriptor fd = mService.getWallpaper(this, params);  
  59.                 if (fd != null) {  
  60.                     try {  
  61.                         BitmapFactory.Options options = new BitmapFactory.Options();  
  62.                         //M: Enable PQ support for all static wallpaper bitmap decoding  
  63.                         options.inPostProc = true;  
  64.                          options.inPostProcFlag = 1;  
  65.                         return BitmapFactory.decodeFileDescriptor(  
  66.                                 fd.getFileDescriptor(), null, options);  
  67.                     } catch (OutOfMemoryError e) {  
  68.                         Log.w(TAG, "Can't decode file", e);  
  69.                     } finally {  
  70.                         try {  
  71.                             fd.close();  
  72.                         } catch (IOException e) {  
  73.                             // Ignore  
  74.                         }  
  75.                     }  
  76.                 }  
  77.             } catch (RemoteException e) {  
  78.                 // Ignore  
  79.             }  
  80.             return null;  
  81.         }  
  82.         //hss add for lockscreen wallpaper start  模范获取桌面壁纸协议恶搞获取当前的lockscreen wallpaper      
  83.           public Bitmap getCurrentLockScreenWallpaperLocked(Context context) {// 获取当前的lockscreen wallpaper  
  84.             if (mService == null) {  
  85.                 Log.w(TAG, "WallpaperService not running");  
  86.                 return null;  
  87.             }  
  88.             try {  
  89.                 Bundle params = new Bundle();  
  90.                 ParcelFileDescriptor fd = mService.getLockScreenWallpaper(this, params);//该方法定义在WallpaperManagerService.java  
  91.                 if (fd != null) {  
  92.                     try {  
  93.                         BitmapFactory.Options options = new BitmapFactory.Options();  
  94.                         //M: Enable PQ support for all static wallpaper bitmap decoding  
  95.                         options.inPostProc = true;  
  96.                         options.inPostProcFlag = 1;  
  97.                           return BitmapFactory.decodeFileDescriptor(  
  98.                                 fd.getFileDescriptor(), null, options);  
  99.                     } catch (OutOfMemoryError e) {  
  100.                         Log.w(TAG, "Can't decode file", e);  
  101.                     } finally {  
  102.                         try {  
  103.                             fd.close();  
  104.                         } catch (IOException e) {  
  105.                             // Ignore  
  106.                         }  
  107.                     }  
  108.                 }  
  109.             } catch (RemoteException e) {  
  110.                 // Ignore  
  111.             }  
  112.             return null;  
  113.         }  
  114.         //hss add for lockscreen wallpaper end  
  115.       }  
  116.      //这个是存设置桌面壁纸的方法,我们仿照它写一个锁屏壁纸的数据写入setLockScreenStream   
  117. public void setStream(InputStream data) throws IOException {  
  118.  if (sGlobals.mService == null) {  
  119.  Log.w(TAG, "WallpaperService not running");   
  120. return;   
  121. }   
  122. try {   
  123. ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null, mContext.getOpPackageName());  
  124. if (fd == null) {   
  125. return;   
  126. }  
  127.  FileOutputStream fos = null;  
  128.  try {  
  129.  fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);   
  130. setWallpaper(data, fos);  
  131.  } finally {   
  132. if (fos != null) {   
  133. fos.close();   
  134. }   
  135. }   
  136. catch (RemoteException e) { // Ignore } } //将选好的图片流写到指定路径   
  137. private void setWallpaper(InputStream data, FileOutputStream fos) throws IOException {  
  138. byte[] buffer = new byte[32768];   
  139. int amt;   
  140. while ((amt=data.read(buffer)) > 0) {   
  141. fos.write(buffer, 0, amt);   
  142. }   
  143. }   
  144.   
  145. //模仿写一个设置锁屏壁纸,将图片存入到指定路径下   
  146. public void setLockScreenStream(InputStream data) throws IOException {  
  147.         if (sGlobals.mService == null) {  
  148.             return;  
  149.         }  
  150.         if(data==null)  
  151.         {   Log.w(TAG, "hss data==null");  
  152.             //模仿桌面壁纸如果图片不存在,就以默认壁纸作为锁屏壁纸来设置  
  153.             data=sGlobals.openDefaultWallpaperRes(mContext);  
  154.         }  
  155.         try {  
  156.             ParcelFileDescriptor fd = sGlobals.mService.setLockScreenWallpaper(null,  
  157.                     mContext.getOpPackageName());//该方法定义在WallpaperManagerService.java  
  158.             if (fd == null) {  
  159.                 Log.w(TAG, "hss fd==null");  
  160.                 return;  
  161.             }  
  162.             FileOutputStream fos = null;  
  163.             try {  
  164.                 fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);  
  165.                 setWallpaper(data, fos);  
  166.             } finally {  
  167.                 if (fos != null) {  
  168.                     fos.close();  
  169.                 }  
  170.  }  
  171.         } catch (Exception e) {  
  172.             e.printStackTrace();  
  173.         }  
  174.         Log.w(TAG, "hss wallpaperpath="+WALLPAPERDIR+"/"+LOCKWALLPAPERNAME);  
  175.     }  
  176. }  

 


在WallpaperManager类中,我们按照桌面壁纸方法,添加了三个方法:

得到锁屏壁纸drawable    getLockScreenDrawable存壁纸资源  setLockScreenStream真正获取锁屏壁纸资源的方法   getCurrentLockScreenWallpaperLocked   。同时实际的锁屏资源的存取都是通过远程调用WallpaperManagerService.java这个service的两个方法(getLockScreenWallpaper,setLockScreenWallpaper)来实现的。所以我们需要通过aidl来实现。如下在IWallpaperManagerCallback添加两个方法,实现在WallpaperManagerService中添加:

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. frameworks/base/core/java/android/app/IWallpaperManagerCallback.aidl  
  2.   
  3.   
  4. ** @hide */  
  5. interface IWallpaperManager {  
  6.     /** 
  7.      * Set the wallpaper. 
  8.      */  
  9.     ParcelFileDescriptor setWallpaper(String name, in String callingPackage);  
  10.       
  11.       /** 
  12.      * Set the lockscreen wallpaper. 
  13.      */  
  14.     ParcelFileDescriptor setLockScreenWallpaper(String name, in String callingPackage);  
  15.  /** 
  16.      * Get the wallpaper. 
  17.      */  
  18.     ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,  
  19.             out Bundle outParams);  
  20.       
  21.    /** 
  22.      * Get the lockscreen wallpaper. 
  23.      */  
  24.    ParcelFileDescriptor getLockScreenWallpaper(IWallpaperManagerCallback cb,  
  25.             out Bundle outParams);  
  26.     
  27.     ... ... ...  
  28. }  



 

在WallpaperManagerService.java中实现

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. frameworks/base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java  
  2.   
  3. public class WallpaperManagerService extends IWallpaperManager.Stub {  
  4.     static final String TAG = "WallpaperManagerService";  
  5.     static final boolean DEBUG = true;  
  6.   
  7.     final Object mLock = new Object[0];  
  8.      
  9.     ... ...  
  10.     //这个是桌面壁纸获取  
  11.     public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,  
  12.             Bundle outParams) {  
  13.         synchronized (mLock) {  
  14.             // This returns the current user's wallpaper, if called by a system service. Else it  
  15.             // returns the wallpaper for the calling user.  
  16.             int callingUid = Binder.getCallingUid();  
  17.             int wallpaperUserId = 0;  
  18.             if (callingUid == android.os.Process.SYSTEM_UID) {  
  19.                 wallpaperUserId = mCurrentUserId;  
  20.             } else {  
  21.                 wallpaperUserId = UserHandle.getUserId(callingUid);  
  22.             }  
  23.             WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);  
  24.             if (wallpaper == null) {  
  25.                 return null;  
  26.             }  
  27.             try {  
  28.                 if (outParams != null) {  
  29.                     outParams.putInt("width", wallpaper.width);  
  30.                     outParams.putInt("height", wallpaper.height);  
  31.                 }  
  32.                 wallpaper.callbacks.register(cb);  
  33.                 File f = new File(getWallpaperDir(wallpaperUserId), mWallpaperFileName);  
  34.                 if (!f.exists()) {  
  35.                     return null;  
  36.                 }  
  37.                 return ParcelFileDescriptor.open(f, MODE_READ_ONLY);  
  38.             } catch (FileNotFoundException e) {  
  39.                 /* Shouldn't happen as we check to see if the file exists */  
  40.                 Slog.w(TAG, "Error getting wallpaper", e);  
  41.             }  
  42.                         return null;  
  43.         }  
  44.     }  
  45.     //add by hss for lockscreen wallpaper start 仿照桌面壁纸获取写一个获取锁屏壁纸资源  
  46.     public ParcelFileDescriptor getLockScreenWallpaper(IWallpaperManagerCallback cb,  
  47.             Bundle outParams) {  
  48.         synchronized (mLock) {  
  49.             // This returns the current user's wallpaper, if called by a system service. Else it  
  50.             // returns the wallpaper for the calling user.  
  51.             int callingUid = Binder.getCallingUid();  
  52.             int wallpaperUserId = 0;  
  53.             WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);  
  54.             if (wallpaper == null) {  
  55.                 return null;  
  56.             }  
  57.             try {  
  58.                 if (outParams != null) {  
  59.                     outParams.putInt("width", wallpaper.width);  
  60.                     outParams.putInt("height", wallpaper.height);  
  61.                 }  
  62.                 wallpaper.callbacks.register(cb);  
  63.                 File f = new File(getWallpaperDir(wallpaperUserId), LOCKWALLPAPER);  
  64.                 if (!f.exists()) {  
  65.                     return null;  
  66.                 }  
  67.              return ParcelFileDescriptor.open(f, MODE_READ_ONLY);  
  68.             } catch (FileNotFoundException e) {  
  69.                 /* Shouldn't happen as we check to see if the file exists */  
  70.                 Slog.w(TAG, "Error getting wallpaper", e);  
  71.             }  
  72.             return null;  
  73.         }  
  74.     }</span>  
  75.     //add by hss for lockscreen wallpaper end  
  76.   
  77.    ... ... ...  
  78.   //这个是设置壁纸资源  
  79.    public ParcelFileDescriptor setWallpaper(String name, String callingPackage) {//hss find here for set wallpaper  
  80.   
  81.         checkPermission(android.Manifest.permission.SET_WALLPAPER);  
  82.         if (!isWallpaperSupported(callingPackage)) {  
  83.             return null;  
  84.         }  
  85.         synchronized (mLock) {  
  86.             if (DEBUG) Slog.v(TAG, "setWallpaper");  
  87.             // /M: To support Smart Book @ {  
  88.             if (isSmartBookSupport()) {  
  89.                 mHaveUsedSmartBook = false;  
  90.             }  
  91.             // /@ }  
  92.             int userId = UserHandle.getCallingUserId();  
  93.             WallpaperData wallpaper = getWallpaperSafeLocked(userId);  
  94.             final long ident = Binder.clearCallingIdentity();  
  95.             try {  
  96.                 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);  
  97.                 if (pfd != null) {  
  98.                     wallpaper.imageWallpaperPending = true;  
  99.                 }  
  100.                 return pfd;  
  101.             } finally {  
  102.                 Binder.restoreCallingIdentity(ident);  
  103.             }  
  104.         }  
  105.     }  
  106.   
  107.     ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {  
  108.         if (name == null) name = "null";  
  109.         try {  
  110.             File dir = getWallpaperDir(wallpaper.userId);  
  111.             if (!dir.exists()) {  
  112.                 dir.mkdir();  
  113.                 FileUtils.setPermissions(  
  114.                         dir.getPath(),  
  115.                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,  
  116.                         -1, -1);  
  117.             }  
  118.             Slog.v(TAG, "hss dir.getPath()"+dir.getPath()+"/"+name);  
  119.             File file = new File(dir, mWallpaperFileName);  
  120.             ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,  
  121.                     MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE);  
  122.             if (!SELinux.restorecon(file)) {  
  123.                 return null;  
  124.             }  
  125.             wallpaper.name = name;  
  126.             return fd;  
  127.         } catch (FileNotFoundException e) {  
  128.             Slog.w(TAG, "Error setting wallpaper", e);  
  129.         }  
  130.         return null;  
  131.     }  
  132.   
  133. //hss add for lockscreenwallpaper start仿照桌面设置壁纸资源写一个设置锁屏壁纸  
  134.   public ParcelFileDescriptor setLockScreenWallpaper(String name, String callingPackage) {//hss find here for set wallpaper  
  135.   
  136.         checkPermission(android.Manifest.permission.SET_WALLPAPER);  
  137.         if (!isWallpaperSupported(callingPackage)) {  
  138.             return null;  
  139.         }  
  140.         synchronized (mLock) {  
  141.             if (DEBUG) Slog.v(TAG, "setLockScreenWallpaper");  
  142.             // /M: To support Smart Book @ {  
  143.             if (isSmartBookSupport()) {  
  144.                 mHaveUsedSmartBook = false;  
  145.             }  
  146.         WallpaperData wallpaper = getWallpaperSafeLocked(0);//userId  
  147.             final long ident = Binder.clearCallingIdentity();  
  148.             try {  
  149.                 ParcelFileDescriptor pfd = updateLockScreenWallpaperBitmapLocked(name, wallpaper);  
  150.                 if (pfd != null) {  
  151.                     wallpaper.imageWallpaperPending = true;  
  152.                 }  
  153.                 return pfd;  
  154.             } finally {  
  155.                 Binder.restoreCallingIdentity(ident);  
  156.             }  
  157.         }  
  158.     }   
  159.   
  160. ParcelFileDescriptor updateLockScreenWallpaperBitmapLocked(String name, WallpaperData wallpaper) {  
  161.         if (name == null) name = "";  
  162.         try {  
  163.             File dir = getWallpaperDir(0);//wallpaper.userId  
  164.             if (!dir.exists()) {  
  165.                 dir.mkdir();  
  166.                 FileUtils.setPermissions(  
  167.                         dir.getPath(),  
  168.                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,  
  169.                         -1, -1);  
  170.             }  
  171.             File file = new File(dir, LOCKWALLPAPER);  
  172.             Slog.v(TAG, "hss file.getPath()"+file.getPath());  
  173.             ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,  
  174.             MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE);  
  175.             if (!SELinux.restorecon(file)) {  
  176.                 Slog.v(TAG, "hss return null");  
  177.                 return null;  
  178.             }  
  179.             wallpaper.name = name;  
  180.             return fd;  
  181.         } catch (FileNotFoundException e) {  
  182.             Slog.w(TAG, "Error setting lockscreenwallpaper", e);  
  183.         }  
  184.         return null;  
  185.     }</span>  
  186.     //hss add for lockscreenwallpaper end  
  187.    ... ... ...  
  188. }  

 

到此已经可以实现锁屏壁纸的存取了。不过由于android6.0对权限的限制,我们需要在/data/system/users/0/目录创建的lockwallpaper里面写入图片资源还要加下Linux权限

/device/mediatek/common/sepolicy/file_contexts.te

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /data/system/users/[0-9]+/lockwallpaper u:object_r:wallpaper_file:s0  


带三步:最后一步就是在systemui中去设置这个壁纸了,也就是NotificationPanelView的背景

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
    1. public class NotificationPanelView extends PanelView implements  
    2.         ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,  
    3.         View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,  
    4.         KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,  
    5.         HeadsUpManager.OnHeadsUpChangedListener {  
    6.          
    7.         ... ... ...  
    8.   
    9.          public void setBarState(int statusBarState, boolean keyguardFadingAway,  
    10.             boolean goingToFullShade) {  
    11.         int oldState = mStatusBarState;  
    12.         boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD;  
    13.         setKeyguardStatusViewVisibility(statusBarState, keyguardFadingAway, goingToFullShade);  
    14.         setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);  
    15.   
    16.         mStatusBarState = statusBarState;  
    17.         mKeyguardShowing = keyguardShowing;  
    18.       <span style="color:#009900;">  //hss add for lockscreen wallpaper start  
    19.             Bitmap bm = getCurrentWallpaperLocked();  
    20.              
    21.             
    22.             //hss add for lockscreen wallpaper end  
    23.   
    24.                 if (bm!=null&&(mStatusBarState == StatusBarState.SHADE_LOCKED || mStatusBarState == StatusBarState.KEYGUARD)) {  
    25.                               Log.w(TAG, "hss add for getCurrentWallpaperLocked not null...");  
    26.                    Drawable dr = new BitmapDrawable(mContext.getResources(), generateBitmap(bm, 480, 1280));  
    27.                    dr.setDither(false);  
    28.                    setBackground(dr);  
    29.                //setBackgroundResource(R.drawable.lockwallpaper);  
    30.         } else {  
    31.                         Log.w(TAG, "hss add for getCurrentWallpaperLocked null...");  
    32.             setBackgroundResource(0);  
    33.         }  
    34.         ///@}  
    35.         </span>if (goingToFullShade || (oldState == StatusBarState.KEYGUARD  
    36.                 && statusBarState == StatusBarState.SHADE_LOCKED)) {  
    37.             animateKeyguardStatusBarOut();  
    38.             animateHeaderSlidingIn();  
    39.         } else if (oldState == StatusBarState.SHADE_LOCKED  
    40.        ... ... ...  
    41.   
    42.      }  
    43. ... ... ...  
    44. }  
    45.          
posted @ 2017-03-06 15:35  夏叶星空  阅读(663)  评论(0编辑  收藏  举报