Launcher壁纸来源
来源:互联网 发布:java校验图片尺寸 编辑:程序博客网 时间:2024/05/17 04:12
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()方法。
经过断点调试,发现来自/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壁纸来源
- Launcher: 设置壁纸_IntentChooser
- Launcher壁纸修改
- Android Launcher 设置壁纸
- 通过壁纸修改launcher桌面背景
- launcher 解读之设置壁纸
- .修改android选择壁纸来源列表
- Launcher 3.0设置壁纸后壁纸被拉伸
- 实现Launcher默认壁纸、选择壁纸定制化功能
- 给Launcher添加壁纸的方法
- Launcher修改默认壁纸(default_wallpaper)
- Launcher: 设置壁纸_源码跟踪
- Launcher修改默认壁纸(default_wallpaper)
- Android launcher 循环优化-壁纸切换
- Launcher修改默认壁纸(default_wallpaper)
- Launcher修改默认壁纸(default_wallpaper)
- 【Android】Launcher开发之壁纸设置
- Launcher修改默认壁纸(default_wallpaper.drawable)
- leetcode 279. Perfect Squares
- 手动安装docker-ce版本
- kubeadm快速部署kubernetes(HA)
- python脚本,完成mulan项目的输入文件生成
- 使用Python模拟蒙蒂霍尔悖论游戏
- Launcher壁纸来源
- Word2010中插入自定义的图片作为项目符号
- 关于CameraDS类
- React native 入门一
- 安卓recyclerView,出来很久了,之前写了个公共adapter,希望能帮助到别人,大神勿喷
- 厂商是怎样的关系?饮料代理商该如何处理
- ORB_SLAM2+IMU详解
- 深入Android 【三】 —— 组件入门(新)
- 向大家介绍Word2010中复选框的制作方法