Launcher是个特殊APK,但说到底还是个应用,想要在上面展示壁纸,自然是来自应用本身,要么就是Framework public资源。

首先,根据长按Launcher主界面空白处,弹出的wallpaper按钮的响应事件来看。

        View wallpaperButton = findViewById(R.id.wallpaper_button);wallpaperButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {if (!mWorkspace.isSwitchingState()) {onClickWallpaperPicker(arg0);}}});wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());

调用到的方法如下

    /*** Event handler for the wallpaper picker button that appears after a long press* on the home screen.*/protected void onClickWallpaperPicker(View v) {if (LOGD) Log.d(TAG, "onClickWallpaperPicker");startActivityForResult(new Intent(Intent.ACTION_SET_WALLPAPER).setPackage(getPackageName()),REQUEST_PICK_WALLPAPER);if (mLauncherCallbacks != null) {mLauncherCallbacks.onClickWallpaperPicker(v);}}

通过startActivity的方式启动Wallpaper选择界面,看看本应用中注册了SET_WALLPAPAER的Activity.

        <activity
            android:name="com.tct.launcher.wallpaperpicker.WallpaperPickerActivity"android:theme="@style/Theme.WallpaperPicker"android:label="@string/pick_wallpaper"android:icon="@mipmap/ic_launcher_wallpaper"android:finishOnCloseSystemDialogs="true"android:process=":wallpaper_chooser"><intent-filter><action android:name="android.intent.action.SET_WALLPAPER" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>

经过adb命令确认,正是该Activity被启动,下方可以看到默认的壁纸和许多的候选壁纸。

界面效果如下

接下来的问题是默认壁纸哪儿来以及后面的17张候选壁纸怎么来,或者怎么定制的。


根据SDK工具hierarchyviewer得的文件布局节点如下

发现这个master_wallpaper_list是个水平线性布局,来自WallpaperPickerActivity的onCreate()方法,布局代码如下:

        <HorizontalScrollView
            android:id="@+id/wallpaper_scroll_container"android:scrollbarSize="@dimen/horizontal_scrollbar_size"android:layout_width="match_parent"android:layout_height="wrap_content" ><LinearLayout
                android:id="@+id/master_wallpaper_list"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal" ><LinearLayout
                    android:id="@+id/wallpaper_list"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal" /><LinearLayout
                    android:id="@+id/live_wallpaper_list"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal" /><LinearLayout
                    android:id="@+id/third_party_wallpaper_list"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal" /></LinearLayout></HorizontalScrollView>

项目用到的是wallpaper_list这个线性布局,另外两个(live_wallpaper_list和third_party_wallpaper_list)为空。

        // Populate the built-in wallpapersArrayList<WallpaperTileInfo> wallpapers = findBundledWallpapers();mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list);SimpleWallpapersAdapter ia = new SimpleWallpapersAdapter(getContext(), wallpapers);populateWallpapersFromAdapter(mWallpapersView, ia, false);// Populate the saved wallpapersmSavedImages = new SavedWallpaperImages(getContext());mSavedImages.loadThumbnailsAndImageIdList();populateWallpapersFromAdapter(mWallpapersView, mSavedImages, true);// Populate the live wallpapers//......// Populate the third-party wallpaper pickers

就目前来说,初次调试,只有预编译进入APK和系统的(FRM) wallpaper资源了,经过几番调试,当前只有两张wallpaper,一张备选一张默认,塞进bundle的有两张。


下面看看findBundledWallpapers方法从哪里取得的图片

    @SuppressWarnings("deprecation")private ArrayList<WallpaperTileInfo> findBundledWallpapers() {final PackageManager pm = getContext().getPackageManager();final ArrayList<WallpaperTileInfo> bundled = new ArrayList<WallpaperTileInfo>(24);Partner partner = Partner.get(pm);if (partner != null) { // partner为空final Resources partnerRes = partner.getResources();final int resId = partnerRes.getIdentifier(Partner.RES_WALLPAPERS, "array",partner.getPackageName());if (resId != 0) {addWallpapers(bundled, partnerRes, partner.getPackageName(), resId);}// Add system wallpapersFile systemDir = partner.getWallpaperDirectory();if (systemDir != null && systemDir.isDirectory()) {for (File file : systemDir.listFiles()) {if (!file.isFile()) {continue;}String name = file.getName();int dotPos = name.lastIndexOf('.');String extension = "";if (dotPos >= -1) {extension = name.substring(dotPos);name = name.substring(0, dotPos);}if (name.endsWith("_small")) {// it is a thumbnailcontinue;}File thumbnail = new File(systemDir, name + "_small" + extension);Bitmap thumb = BitmapFactory.decodeFile(thumbnail.getAbsolutePath());if (thumb != null) {bundled.add(new FileWallpaperInfo(file, new BitmapDrawable(thumb)));}}}}Pair<ApplicationInfo, Integer> r = getWallpaperArrayResourceId();//来自应用内部R.array.extra_wallpapers;//从array中获取到了壁纸1if (r != null) {try {Resources wallpaperRes = getContext().getPackageManager().getResourcesForApplication(r.first);addWallpapers(bundled, wallpaperRes, r.first.packageName, r.second);} catch (PackageManager.NameNotFoundException e) {}}if ((partner == null || !partner.hideDefaultWallpaper()) && loadDefaultWallpaperForCustomization()) {// Add an entry for the default wallpaper (stored in system resources)WallpaperTileInfo defaultWallpaperInfo =(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)? getPreKKDefaultWallpaperInfo(): getDefaultWallpaper();// 来自getDefaultWallpaper方法, 壁纸2if (defaultWallpaperInfo != null) {bundled.add(0, defaultWallpaperInfo);}}return bundled; // 调试机器获取的壁纸有两张}

其中wallpaper1很容易理解,即预置在Launcher应用内部的R.array资源,本机调试只预置了一张图片,这也是后面要讲到的Launcher该如何定制自己的备选壁纸,即通过overlay的方式,增加图片和项。

<resources><string-array name="extra_wallpapers" translatable="false"><item>wallpaper1</item></string-array>
</resources>

接下来看默认的那张壁纸哪儿,看getDefaultWallpaper()方法。

经过断点调试,发现来自/data/user/0/com.tct.launcher/files目录,其中有张生成的jpg图片,被命名为:24_Y8KU2000CH00_default_thumb2.jpg。

这就时我们系统中第一张壁纸。经过再三验证,此图片即来自FRM。
/frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png
其将被编入framework-res.apk。

/system/framework/framework-res.apk=android

预置自己的备选壁纸
除了在上面提到的FRM中替换默认的那张壁纸外,还可以通过overlay的方式替换原本预编译在launcher中的array资源,R.array.extra_wallpapers,并加入对应的图片资源即可。

/vendor/overlay/SimpleLauncherRes-overlay.apk=com.simple.launcher.overlay

上面的WallpaperPickerActivity界面对应的备用wallpaper正是来自于覆盖的R.array.extra_wallpapers,反编译后得到的图片如下,从1至17,都在这儿了。

Launcher壁纸来源相关推荐

  1. android 5.1 壁纸路径,Android5.1 壁纸来源选项中有两个“壁纸”选项

    Android5.1 壁纸来源选项中有两个"壁纸"选项 [问题] 系统语言为中文,打开 设置->显示->壁纸->查看显示 可以看到设置菜单中有两个壁纸选项显示 系 ...

  2. Android launcher 壁纸 wallpaper

    壁纸分为动态和静态两种: 如果只需要修改默认静态壁纸,替换frameworks/base/core/res/res/drawable/default_wallpaper.jpg即可,或者在源码中修改对 ...

  3. 如何替换 Android 系统 Launcher 壁纸

    上次研究 adb 命令如何删除开机动画后,再研究了一下,壁纸其实我们也是可以替换.接下来直接上命令,各位看客可以尝试一下. adb remount adb shell cd system/media ...

  4. Android Launcher 设置壁纸

    版本:1.0  日期:2014.11.25 2014.11.26 版权:©kince 特别推荐:泡在网上的日子 一.概述 一般Launcher都带有壁纸设置的功能,Android提供了设置壁纸的API ...

  5. 动态添加select2input没样式_MIUI10壁纸升级:桌面动效壁纸与动态壁纸的前世今生...

    相信很多MIUI10开发版的用户已经体验到新版个性主题APP,新版个性主题采用顶部Tab栏+底部标签栏双向设计,加上首页人工智能推荐算法,让每个用户所看见的都是自己喜欢的.随个性主题APP升级,MIU ...

  6. 壁纸|锁屏和桌面套图壁纸,一套的,给手机来个套餐

    编辑|排版| @宅哥技术 壁纸来源{壁纸}APP如侵联删 来源:宅哥技术(zg_jishu) ---------♥--------- 套图壁纸 壁纸这些大家都喜欢吗?拿走这些壁纸的时候别忘记点个[再看 ...

  7. pap.er for mac高清壁纸下载后的储存位置在哪里?小编告诉你!!

    Pap.er Mac中文版是最好用的免费5K高清壁纸应用,让您可以每天享受来自全球新鲜精美的壁纸!pap.er 功能做到了极致简单,没有广告.没有弹窗,壁纸来源也是免版权图库的高清原图. 想了解更多内 ...

  8. 超火壁纸!隐藏 Dock 栏+AirTag 渐变

    AirTag 渐变+隐藏 Dock 来源:AR72014 一共有 4 组.全面屏.非全面屏的都有(左边为全面屏),特别适合 iOS 14 使用,在「深色模式」下,还能隐藏底部的 Dock 栏(要设置深 ...

  9. 最近超火的太空人动态壁纸,手机也能使用!

    大家都知道最近抖音最火的华为太空人表盘,想必大家也很喜欢,今天我就找到了一些这样的Lve壁纸,设置后长按就能转圈圈!还是很炫酷的! 一起看一下下面的效果吧!顺便点个关注!↓ 太空人动态壁纸 壁纸一共准 ...

最新文章

  1. Laravel开启跨域的方法
  2. Oracle之表分区、分区索引(二)
  3. 如何处理Docker错误消息:please add——insecure-registry
  4. Linux 牛书推荐:《Linux网络编程》
  5. 笔记:git常用操作,git使用,git命令行
  6. latex常用的公式
  7. jquery html页面跳转,HTML 链接
  8. C++ 时间操作(获取毫秒级)【转】
  9. 你的项目应当使用Spring Boot吗?(译文)
  10. 同步与异步、异步与回调
  11. MATLAB自学教程一1.显示图像图像基本信息
  12. 数字图像直方图匹配或规定化Histogram Matching (Specification)处理
  13. WORD里表格复制到另一WORD里表格会变形的解决办法
  14. 计算机专业设计(论文)内容及要求,计算机专业毕业设计要求.doc
  15. express静态文件
  16. 乡村少年宫计算机教师简介,乡村少年宫教师感言
  17. 磁链转种子,种子转磁链
  18. 电脑耳机拔出后,再插入没声音
  19. 围棋计算机运算,围棋冠军:用计算力赢计算机
  20. 学会这些网站优化技巧,秒变seo专家

热门文章

  1. 关闭微信朋友圈和公众号的广告
  2. Android项目的targetSDK=23,在低于Android6.0的部分测试机(类似华为)上运行时出现的系统权限问题...
  3. 机动车c1科三考试语言灯光,史上最全科目三灯光模拟图解
  4. Vue2源码解析 虚拟dom简介
  5. html 地区筛选插件,帝国CMS7.2实现地区三级联动并且前台可地区筛选的插件教程...
  6. 绝对定位元素的margin如何设置
  7. 用IDEA创建基于Spring Cloud的Feign的微服务:服务接口、服务提供者、服务使用者分离
  8. 为virtools写的插件进行一下总结
  9. 解决 IE下ajaxfileupload不兼容的问题
  10. 程序员有哪些必备技能?