Aandroid 应用icon动态加载到launcher方法及framework分析
来源:互联网 发布:二手淘宝手机店 编辑:程序博客网 时间:2024/06/03 15:50
Android launcher动态加载应用icon的方法
在android 应用开发中,我们会遇到应用icon需要动态加载到launcher中的问题。
实现的方法是:
private PackageManager pm;pm = context.getPackageManager();pm.setComponentEnabledSetting(new ComponentName(context,"com.uid.pid.New1MainActivity"),PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);//加载到launcher中pm.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);//从launcher中remove
这个setComponentEnabledSetting 具体是怎么工作的,我们通过framework源码可以知道:
PackageManagerService.java
@Overridepublic void setComponentEnabledSetting(ComponentName componentName, int newState, int flags, int userId) { if (!sUserManager.exists(userId)) return; /* SPRD: update label and icon for app @{ */ String packege = componentName.getPackageName(); Log.w(TAG, packege+" == "+newState+" == "+flags+" "+userId); if(packege.startsWith("com.android.stk")){ isOpen = true; } /* @} */ Log.d(TAG, "kings:packageName=" + componentName.getPackageName() + ", className=" + componentName.getClassName()); setEnabledSetting(componentName.getPackageName(), componentName.getClassName(), newState, flags, userId, null);}
>
private void setEnabledSetting(final String packageName, String className, int newState, final int flags, int userId, String callingPackage) { if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT || newState == COMPONENT_ENABLED_STATE_ENABLED || newState == COMPONENT_ENABLED_STATE_DISABLED || newState == COMPONENT_ENABLED_STATE_DISABLED_USER || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { throw new IllegalArgumentException("Invalid new component state: " + newState); } ... scheduleWritePackageRestrictionsLocked(userId); ... } void scheduleWritePackageRestrictionsLocked(int userId) { if (!sUserManager.exists(userId)) return; mDirtyUsers.add(userId); if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); } } case WRITE_PACKAGE_RESTRICTIONS: { Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); synchronized (mPackages) { removeMessages(WRITE_PACKAGE_RESTRICTIONS); for (int userId : mDirtyUsers) { mSettings.writePackageRestrictionsLPr(userId); } mDirtyUsers.clear(); } Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } break;
从上面可以知道最终调用Settings.java中的writePackageRestrictionsLPr()来实现。
SettingS.java
void writePackageRestrictionsLPr(int userId) { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); } // Keep the old stopped packages around until we know the new ones have // been successfully written. File userPackagesStateFile = getUserPackagesStateFile(userId); File backupFile = getUserPackagesStateBackupFile(userId); new File(userPackagesStateFile.getParent()).mkdirs(); if (userPackagesStateFile.exists()) { // Presence of backup settings file indicates that we failed // to persist packages earlier. So preserve the older // backup for future reference since the current packages // might have been corrupted. if (!backupFile.exists()) { if (!userPackagesStateFile.renameTo(backupFile)) { Slog.wtf(PackageManagerService.TAG, "Unable to backup user packages state file, " + "current changes will be lost at reboot"); return; } } else { userPackagesStateFile.delete(); Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup"); } } try { final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile); final BufferedOutputStream str = new BufferedOutputStream(fstr); final XmlSerializer serializer = new FastXmlSerializer(); serializer.setOutput(str, StandardCharsets.UTF_8.name()); serializer.startDocument(null, true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS); for (final PackageSetting pkg : mPackages.values()) { PackageUserState ustate = pkg.readUserState(userId); if (ustate.stopped || ustate.notLaunched || !ustate.installed || ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT || ustate.hidden || (ustate.enabledComponents != null && ustate.enabledComponents.size() > 0) || (ustate.disabledComponents != null && ustate.disabledComponents.size() > 0) || ustate.blockUninstall || (ustate.domainVerificationStatus != PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED)) { serializer.startTag(null, TAG_PACKAGE); serializer.attribute(null, ATTR_NAME, pkg.name); if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled); if (!ustate.installed) { serializer.attribute(null, ATTR_INSTALLED, "false"); } if (ustate.stopped) { serializer.attribute(null, ATTR_STOPPED, "true"); } if (ustate.notLaunched) { serializer.attribute(null, ATTR_NOT_LAUNCHED, "true"); } if (ustate.hidden) { serializer.attribute(null, ATTR_HIDDEN, "true"); } if (ustate.blockUninstall) { serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true"); } if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) { serializer.attribute(null, ATTR_ENABLED, Integer.toString(ustate.enabled)); if (ustate.lastDisableAppCaller != null) { serializer.attribute(null, ATTR_ENABLED_CALLER, ustate.lastDisableAppCaller); } } if (ustate.domainVerificationStatus != PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { serializer.attribute(null, ATTR_DOMAIN_VERIFICATON_STATE, Integer.toString(ustate.domainVerificationStatus)); } if (ustate.appLinkGeneration != 0) { serializer.attribute(null, ATTR_APP_LINK_GENERATION, Integer.toString(ustate.appLinkGeneration)); } if (ustate.enabledComponents != null && ustate.enabledComponents.size() > 0) { serializer.startTag(null, TAG_ENABLED_COMPONENTS); for (final String name : ustate.enabledComponents) { serializer.startTag(null, TAG_ITEM); serializer.attribute(null, ATTR_NAME, name); serializer.endTag(null, TAG_ITEM); } serializer.endTag(null, TAG_ENABLED_COMPONENTS); } if (ustate.disabledComponents != null && ustate.disabledComponents.size() > 0) { serializer.startTag(null, TAG_DISABLED_COMPONENTS); for (final String name : ustate.disabledComponents) { serializer.startTag(null, TAG_ITEM); serializer.attribute(null, ATTR_NAME, name); serializer.endTag(null, TAG_ITEM); } serializer.endTag(null, TAG_DISABLED_COMPONENTS); } serializer.endTag(null, TAG_PACKAGE); } } writePreferredActivitiesLPr(serializer, userId, true); writePersistentPreferredActivitiesLPr(serializer, userId); writeCrossProfileIntentFiltersLPr(serializer, userId); writeDefaultAppsLPr(serializer, userId); serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endDocument(); str.flush(); FileUtils.sync(fstr); str.close(); // New settings successfully written, old ones are no longer // needed. backupFile.delete(); FileUtils.setPermissions(userPackagesStateFile.toString(), FileUtils.S_IRUSR|FileUtils.S_IWUSR |FileUtils.S_IRGRP|FileUtils.S_IWGRP, -1, -1); // Done, all is good! return; } catch(java.io.IOException e) { Slog.wtf(PackageManagerService.TAG, "Unable to write package manager user packages state, " + " current changes will be lost at reboot", e); } // Clean up partially written files if (userPackagesStateFile.exists()) { if (!userPackagesStateFile.delete()) { Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: " + mStoppedPackagesFilename); } }}
通过上面接口发现,android最终将这些componame 保存到手机系统/data/system/users/0/package-restrictions.xml 中
<pkg name="com.uid.pid"> <enabled-components> <item name="com.uid.pid.New1MainActivity" /> <item name="com.uid.pid.SecondActivity" /> </enabled-components> <disabled-components> <item name="com.uid.pid.MainActivity" /> <item name="com.uid.pid.New2MainActivity" /> </disabled-components> </pkg>
0 0
- Aandroid 应用icon动态加载到launcher方法及framework分析
- Android launcher动态Icon的实现方法
- Android launcher动态Icon的实现方法
- Android Launcher 动态icon【时钟】【日历】
- 动态更换应用Icon
- Aandroid 退出应用
- android应用icon动态更换
- Android动态改变App在Launcher里面的icon
- 给launcher上的应用图标ICON加上背景框
- Aandroid 图片加载库Glide 实战(一),初始,加载进阶到实践
- Flex里用IconUtility动态加载Icon
- Flex里用IconUtility动态加载Icon
- Flex里用IconUtility动态加载Icon
- BaseAdapter应用分析及异步加载
- Android launcher icon size
- Android Launcher icon 放大
- Android launcher icon size
- Android launcher icon size
- 基础总结篇之一:Activity生命周期
- JavaScript 三种创建对象的方法
- 网站如何对应10万级请求响应
- java值传递
- 13、Power Query-逆透视列的实例(下)
- Aandroid 应用icon动态加载到launcher方法及framework分析
- Python-002-HelloWorld程序
- android开发小问题汇总
- sql 查询,把查出的数据作为临时表在进行查询
- PHP开发小技巧⑨—获取url中的各个参数
- iOS设计模式——适配器
- onConfigurationChanged未被调用的原因
- [学习笔记] bootstrap (三): 按钮,图片,图标
- Xshell、Xftp的使用