IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> work profile关闭时桌面图标变灰 -> 正文阅读

[移动开发]work profile关闭时桌面图标变灰

work profile关闭时桌面图标变灰

应用变为不可用,图标变灰色,和刚毕业第一家公司当时还是Android4.4版本,Launcher做的图标变色功能有点像:用豌豆荚把安装的应用移动到sd卡,拔掉sd卡,图标变灰色,插入sd卡,应用重新变成彩色。
翻了一下之前的blog,才发现关于插卡sd卡的launcher没有写。好尴尬啊。。。

简单来写一下work profile的Launcher流程吧

操作步骤

1、work profile是Google mada测试的一项,安装Test DPC 之后,Launcher的all apps列表会有一个worp profile的栏目,里面有几个默认的apk带角标。
2、Google的launcher3默认实现了workprofile图标信息的展示
3、拖动图标到桌面,关闭work profile,图标变灰色。

图标更新逻辑

1、app/src/com/tblenovo/launcher/LauncherModel.java中收到work profile关闭的广播

public void onReceive(Context context, Intent intent) {
        if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent);

        final String action = intent.getAction();
        if (Intent.ACTION_LOCALE_CHANGED.equals(action)) {
            // If we have changed locale we need to clear out the labels in all apps/workspace.
            forceReload();
        } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)
                || Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
            UserManagerCompat.getInstance(context).enableAndResetCache();
            forceReload();
        } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) ||
                Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) ||
                Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
            UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
            if (user != null) {
                if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) ||
                        Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) {
                    enqueueModelUpdateTask(new PackageUpdatedTask(
                            PackageUpdatedTask.OP_USER_AVAILABILITY_CHANGE, user));
                }

                // ACTION_MANAGED_PROFILE_UNAVAILABLE sends the profile back to locked mode, so
                // we need to run the state change task again.
                if (Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) ||
                        Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) {
                    enqueueModelUpdateTask(new UserLockStateChangedTask(user));
                }
            }
        }else if (Intent.ACTION_WALLPAPER_CHANGED.equals(action)) {
            WallpaperBgCompat.getInstance(context.getApplicationContext()).getCompressWallpaper(true);
        } else if (BaseFlags.IS_DOGFOOD_BUILD && ACTION_FORCE_ROLOAD.equals(action)) {
            Launcher l = (Launcher) getCallback();
            l.reload();
        }
    }

2、app/src/com/android/launcher/model/PackageUpdatedTask.java中,OP_USER_AVAILABILITY_CHANGE操作,然后更新图标数据。
workprofile像是基于多用户去做的一个功能,默认主用户user 0,workprofile的user 我当时打断点的时候是user 10
3、省略中间的逻辑部分
4、bindUpdatedWorkspaceItems(updatedWorkspaceItems);更新图标
5、app/src/com/android/launcher/Workspace.java的updateShortcuts更新图标

void updateShortcuts(ArrayList<WorkspaceItemInfo> shortcuts) {
        ...
        mapOverItems(MAP_RECURSE, new ItemOperator() {
            @Override
            public boolean evaluate(ItemInfo info, View v) {
                if (info instanceof WorkspaceItemInfo && v instanceof BubbleTextView &&
                        updates.contains(info)) {
                    WorkspaceItemInfo si = (WorkspaceItemInfo) info;
                    BubbleTextView shortcut = (BubbleTextView) v;
                    Drawable oldIcon = shortcut.getIcon();
                    boolean oldPromiseState = (oldIcon instanceof PreloadIconDrawable)
                            && ((PreloadIconDrawable) oldIcon).hasNotCompleted();
                    shortcut.applyFromWorkspaceItem(si, si.isPromise() != oldPromiseState);
                }
                // process all the shortcuts
                return false;
            }
        });
        ...
    }

6、app/src/com/android/launcher/BubbleTextView.java

public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean promiseStateChanged) {
        applyIconAndLabel(info);//这里更新图标和应用名称
        setTag(info);
        if (promiseStateChanged || (info.hasPromiseIconUi())) {
            applyPromiseState(promiseStateChanged);
        }

        applyDotState(info, false /* animate */);
    }
private void applyIconAndLabel(ItemInfoWithIcon info) {
        FastBitmapDrawable iconDrawable = DrawableFactory.INSTANCE.get(getContext())
                .newIcon(getContext(), info);//创建图标
        mDotParams.color = IconPalette.getMutedColor(info.iconColor, 0.54f);

        setIcon(iconDrawable);
        setText(info.title);
        if (info.contentDescription != null) {
            setContentDescription(info.isDisabled()
                    ? getContext().getString(R.string.disabled_app_label, info.contentDescription)
                    : info.contentDescription);
        }
    }

7、app/src/com/android/launcher/graphics/DrawableFactory.java

	/**
     * Returns a FastBitmapDrawable with the icon.
     */
    public FastBitmapDrawable newIcon(Context context, ItemInfoWithIcon info) {
        FastBitmapDrawable drawable = info.usingLowResIcon()
                ? new PlaceHolderIconDrawable(info, IconShape.getShapePath(), context)
                : new FastBitmapDrawable(info);
        drawable.setIsDisabled(info.isDisabled());//这个disable就很灵性,点进去果然就是图标的处理部分代码太长就不贴了。
        return drawable;
    }
尾注

简单写一点图标颜色的部分逻辑分析,没有完整的打开,launcher更新、关闭、图标变化、主菜单更新等等。
有点费时间写。

授之以渔

灵感: 我是怎么找到这个逻辑的
因为之前做过launcher,所以对桌面图标印象还是比较深的,直接找到BubbleTextView.java这个类
它其实是一个textview,设置了文字和图标在文字的那个方向

protected void applyCompoundDrawables(Drawable icon) {
        // If we had already set an icon before, disable relayout as the icon size is the
        // same as before.
        mDisableRelayout = mIcon != null;

        icon.setBounds(0, 0, mIconSize, mIconSize);
        if (mLayoutHorizontal) {
            setCompoundDrawablesRelative(icon, null, null, null);
        } else {
            setCompoundDrawables(null, icon, null, null);
        }
        mDisableRelayout = false;
    }

直接在这里打断点就可以了,所以桌面图标更新都会走到这里,被调用的有点多,慢慢过滤了一下就找到了上面的流程。。。。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-12 17:41:04  更:2022-03-12 17:42:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/30 9:21:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码