Launcher壁纸来源

2023-05-16

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

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

        View wallpaperButton = findViewById(R.id.wallpaper_button);
        wallpaperButton.setOnClickListener(new OnClickListener() {
            @Override
            public 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 wallpapers
        ArrayList<WallpaperTileInfo> wallpapers = findBundledWallpapers();
        mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list);
        SimpleWallpapersAdapter ia = new SimpleWallpapersAdapter(getContext(), wallpapers);
        populateWallpapersFromAdapter(mWallpapersView, ia, false);

        // Populate the saved wallpapers
        mSavedImages = 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 wallpapers
            File 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 thumbnail
                        continue;
                    }

                    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中获取到了壁纸1
        if (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方法, 壁纸2
            if (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()方法。
default wallpaper

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

这就时我们系统中第一张壁纸。经过再三验证,此图片即来自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,都在这儿了。
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Launcher壁纸来源 的相关文章

  • 轻松解决vscode官网下载慢问题

    下载vscode安装包时 xff0c 都习惯去官网下载 xff0c 但是会如下图第一次下载那样缓慢 xff0c 对着下载处右击 xff0c 复制出下载链接 xff0c 把下载链接中code visualstudio com换成vscode
  • redis获取缓存对象bean时报:SerializationException: Could not read JSON: Could not resolve type

    一 在单个应用内进行 存 取 工作中的问题场景 xff1a 将一个实体类对象set存入 redis中 xff0c 用的时候去get时 xff0c 报错提示 xff1a SerializationException Could not rea
  • window 2012 R2 忘记密码处理方案

    方案一 xff1a 你是否开启了内置管理员 xff0c 或是还建立了其他的管理员账户 如果有的话 xff0c 请先以其他管理员账户登入电脑 xff0c 在本地计算机和组中 xff0c 更改你的账户密码 方案二 xff1a 如果没有的话 xf
  • 达梦数据库不同模式导入时系统提示字符集异常的解决办法

    近期参加了达梦DCA的培训 xff0c 练习的时候遇到一个问题 xff1a 同一模式导出导入正常 xff0c 但是在将DMTEST模式导出的dmp文件导入DMTEST02时 xff0c 遇到了如下报错 xff1a 提示本地编码 PG UTF
  • gradle 插件与gradle版本对应关系

    https developer android google cn studio releases gradle plugin html updating gradle 插件版本所需的Gradle版本1 0 0 1 1 3 2 2 1 2
  • 程序员的硬件设备

    程序员的硬件设备 程序员的工作台 很多人从网上 或者公司里 xff0c 看到程序员开发的工作台是这样的 其实这是个误区 xff0c 不同的人习惯不一样 xff0c 对于程序员来说 xff0c 一台性能好点的电脑就做够了 市场上有很多驻场外包
  • scp 本地复制文件到服务器

    1 本地复制文件到服务器 scp Users guolm Desktop ROOT war root 64 192 168 1 228 opt tomcat webapps 2 服务器到本地文件 scp root 64 192 168 1
  • Wireshark 认识捕获的分析数据包(及各个分层协议的介绍)

    综述 xff1a 认识Wireshark捕获数据包 当我们对Wireshark主窗口各部分作用了解了 xff0c 学会捕获数据了 xff0c 接下来就该去认识这些捕获的数据包了 Wireshark将从网络中捕获到的二进制数据按照不同的协议包
  • 禁用virtualbox自带的dhcp服务

    在你安装虚拟机的系统上面 xff0c 打开cmd xff1a cd D cd D softInstall VMvirtualbox6 D softInstall VMvirtualbox6 gt VBoxManage list dhcpse
  • MATLAB并行计算

    先上图 xff0c 图中求500次随机矩阵的特征值 xff0c 串行14 85s xff0c 并行3 63s 串行计算 tic S1 61 1 for i 61 1 500 S1 61 S1 43 max eig rand i end di
  • libsvm参数说明

    因为要用svm做regression xff0c 所以看了一些关于libsvm xff0c 总结以备用 libsvm在训练model的时候 xff0c 有如下参数要设置 xff0c 当然有默认的参数 xff0c 但是在具体应用方面效果会大大
  • Windows C# RabbitMQ 安装--配置--信息收发

    前言 近期要实现一个图片异步上传的需求 xff0c 需要用到RabbitMQ xff0c 辅助客户端完成对高并发请求的处理 一 安装Erlang 由于RabbitMQ服务器是用Erlang语言编写 xff0c 所以我们需要先安装Erlang
  • .MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1

    MalformedJsonException Use JsonReader setLenient true to accept malformed JSON at line 1 column 1 path 像这种低级错误 xff0c 我今天
  • 离线升级curl采坑

    先在线yum打包 1 安装repo rpm Uvh http www city fan org ftp contrib yum repo rhel6 x86 64 city fan org release 2 1 rhel6 noarch
  • uos桌面系统获取串口日志

    文章目录 一 准备工作1 问题机器2 收集日志机器 二 串口线连接三 收集日志机器上查看串口信息四 问题机器上设置gurb五 cutecom调试串口六 使用minicom工具收集串口信息 一 准备工作 1 问题机器 span class t
  • Ubuntu18.04.3安装GTX1650显卡驱动 安装CUDA 安装CUDNN

    0 前期准备 禁用BIOS的secure boot xff0c 即disable它 xff0c 如果不关闭 xff0c 使用第三方源安装显卡驱动会安装后不能使用 1 禁用nouveau 1 创建文件 xff0c 如果没有下载vim编辑器 x
  • mybatis中resultMap使用之返回分组数据

    1 resultMap 1 1 引言 resultMap是mybatis最重要的强大元素 通过描述数据的关系结构 xff0c 将结果集进行映射到java类或java bean中 xff0c 达到结果集复杂处理的目的 本文解决的主要问题的分组
  • 项目中使用JPush推送,遇到的问题

    JPush初始化错误 Android版本是4 0以上的 xff0c JPush包是1 60的 报错 xff1a 02 24 18 46 54 306 E AndroidRuntime 22522 FATAL EXCEPTION Thread
  • HIDL最全编译流程

    想了解HIDL介绍的可以参考 HIDL概述 xff0c 本篇文章主要介绍HIDL的详细编译流程及简单的客户端应用 xff08 C 43 43 跟Android客户端的应用 xff09 一 准备工作 整一套源码 xff0c Android O
  • 【mysql】如何在MySQL中导入超大的SQL文件?

    mysql 如何在MySQL中导入超大的SQL文件 xff1f 方法 1 在navicat中导入 xff08 速度慢 xff09 2 使用source命令导入 xff08 速度快 xff09 第一种很简单 xff0c 本文只介绍第二种 步骤

随机推荐

  • (转)imageIO异常:Unsupported Image Type, 不支持图像类型

    是不是在使用iamgeio导入图片的时候出现了这个异常呢 xff1a javax imageio IIOException Unsupported Image Type 如果你确定图片格式没有错 xff0c 那我想你可能使用过photosh
  • 遗传算法与进化算法

    引言 1858年7月1日C R 达尔文与A R 华莱士在伦敦林奈学会上宣读了进化论的论文 xff0c 至此进化理论深入人心 xff0c 为广大吃瓜群众开辟了一个思想的新的天地 而我们的机器学习大师们向来喜欢从生物学家那里找灵感 xff0c
  • Git使用手册/Git教程:git pull origin 拉取代码到本地,解决拉取代码时发生的文件冲突

    相关文章 xff1a 关于验证是否存在ssh配置以及生成SSH Key的方法可以参照文章 xff1a Git使用手册 生成SSH Key 关于SSH Key的使用和公钥在gitHub gitLab的配置等 xff0c 请参考文章 xff1a
  • 基于SSM的社区团购小程序的设计与实现

    社区团购的设计与实现 该项目含有源码 论文等资料 配套开发软件 软件安装教程 项目发布教程等 系统功能完整 xff0c 适合作为毕业设计 课程设计 数据库大作业学习使用 项目功能介绍 社区团购系统中的功能模块主要是实现管理员服务端 xff1
  • AFNetWorking(3.0)源码分析(五)——AFHTTPRequestSerializer & AFHTTPResponseSerializer

    在前面的几篇博客中 xff0c 我们分析了AFURLSessionMangerd以及它的子类AFHTTPSessionManager 我们对AF的主要两个类 xff0c 有了一个比较全面的了解 对于AFHTTPSessionManager
  • java String 最长长度和占用内存大小

    一 序 String在内存中的最大长度理论上是int型变量的最大值 xff0c Integer MAX VALUE String的字面常量的最大长度为CONSTANT Utf8 info表决定 xff0c 一般为65535 二 介绍 1 S
  • Android常用检查判断方法

    自己工作中比较常用的一些判断检测 span class hljs keyword import span android app ActivityManager span class hljs keyword import span and
  • 小米、魅族状态栏字体变色整理

    span class hljs javadoc 设置小米手机状态栏字体图标颜色模式 xff0c 需要MIUIV6以上 span class hljs javadoctag 64 param span window 需要设置的窗口 span
  • C语言学习:初接触

    C程序结构 C程序结构主要包括以下部分 xff1a 预处理指令器 函数 变量 语句 amp 函数体 注释 用一个简单的 Hello World 代码说明 xff1a span class hljs preprocessor include
  • C语言学习:基本语法

    分号 如果你有其它编程语言的基础 xff0c 相信你已经明白了分号的意义 分号在C语言中与多数语言相同 xff0c 它代表了语句的结束 也就是说 xff0c 一个完整的语句必须以分号结尾 注释 注释就像是帮助文件一样 xff0c 它可以帮助
  • C语言学习:数据类型

    在C语言中 xff0c 数据类型可以分为以下几种 xff1a 类型描述基本类型C语言中的算术类型 xff0c 包含整数型和浮点型枚举类型C语言中的算术类型 xff0c 用来定义在程序中只能赋予其一定的离散整数值的变量 void类型类型说明符
  • 典型相关分析(CCA)

    CCA是数据挖掘中重要的算法 xff0c 可以挖掘出数据间的关联关系的算法 基础知识 如何衡量两个变量之间的相关性呢 xff1f 我们有相关系数 xff0c 如下所示 xff1a X Y 61 c o v X Y D X D Y X
  • Android 按键模拟输入事件和Monitor工具的使用

    有时候 xff0c 进行Android开发 xff0c 会遇到屏幕会失灵的情况 xff0c 但是显示无问题 xff0c 这时候可以使用一些工具 手段 xff0c 在电脑端控制模拟屏幕输入 xff0c 或者使用adb 相关命令模拟按键事件输入
  • Android APK获取平台系统签名权限

    1 修改AndroidManifest xml xff0c 改变uid为android uid system xff0c 使之与Settings能够共享数据空间 lt xml version 61 34 1 0 34 encoding 61
  • gradlew编译时出现Unsupported major.minor version 52.0

    Android apk命令行编译时 xff0c 出现如下错误 xff1a Unsupported major minor version 52 0 先摆上结论 xff1a 1 有可能是compileSdkVersion和buildToolV
  • Android NE发生定位辅助之addr2line

    当发生NE时 xff0c 可以通过addr2line来辅助定位发生点 举个例子 Exception Class Native NE Exception Type SIGABRT Current Executing Process pid 3
  • Android N编译之Out of memory error

    之前本地环境编译一直是正常的 xff0c 后来更新代码后 xff0c 出现编译不过 提示out of memory 但是查看swap和内存都还是够的 里面有个提示 xff0c try increasing heap size with ja
  • Android R源码Settings之NFC与Tap&pay

    Android R 又对 Tap amp pay菜单 进行了更新 xff0c 变得更加合理化 xff0c 人性化了 编辑于2020 4 20 12 24 10 xff09 Android R Tap amp pay菜单 如图可知 xff0c
  • [NOTE]Android N SmartLock缺少很多功能

    有个Android项目刚启动不久时 xff0c 测试SmartLock时 xff0c 发现里面只有On body detection xff0c Trusted places Trusted devices Trusted face和Tru
  • Launcher壁纸来源

    Launcher是个特殊APK xff0c 但说到底还是个应用 xff0c 想要在上面展示壁纸 xff0c 自然是来自应用本身 xff0c 要么就是Framework public资源 首先 xff0c 根据长按Launcher主界面空白处