清除并设置默认的家庭应用程序

Nova如何pipe理这个? 我实际上正在尝试做同样的事情:为用户提供一个button来清除并select他们的新默认启动器。

我能够得到默认的应用程序名称并显示它:

private String getPrefered(Intent i) { PackageManager pm = this.getActivity().getPackageManager(); final ResolveInfo mInfo = pm.resolveActivity(i, 0); return (String) pm.getApplicationLabel(mInfo.activityInfo.applicationInfo); } 

Intent i

 Intent home = new Intent("android.intent.action.MAIN"); home.addCategory("android.intent.category.HOME"); 

然后我调用系统ResolveActivity,

 private void makePrefered() { Intent selector = new Intent("android.intent.action.MAIN"); selector.addCategory("android.intent.category.HOME"); selector.setComponent(new ComponentName("android", "com.android.internal.app.ResolverActivity")); startActivity(selector); } 

拾取器启动并正常工作,但它并没有设置或清除任何值。 在debugging的时候,好像我错过了一些额外的东西? 当我调用makePrefered方法时,我得到以下日志消息,

 I/ActivityManager( 602): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] cmp=android/com.android.internal.app.ResolverActivity u=0} from pid 22641 

当我使用Nova实现时,我看到所有这些,

  I/PackageManager( 602): Result set changed, dropping preferred activity for Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 (has extras) } type null I/ActivityManager( 602): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=android/com.android.internal.app.ResolverActivity (has extras) u=0} from pid 22905 I/ActivityManager( 602): START {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.mycolorscreen.canvas/.Launcher (has extras) u=0} from pid 22905 
  1. 我怎样才能进去看看这个包里面发了些什么?
  2. 我怎样才能清除首选的应用程序? 不要告诉我你不能,我已经看到了足够的答案。 Nova做到了,并且完全按照我想要的方式来做。

这样做的代码实际上只是一个非常聪明的工作。

当一个组件与

  <category android:name="android.intent.category.HOME" /> 

启用,通常从一个新的家庭应用程序的安装,默认的家庭应用程序被清除。

通过像这样使用home组件创build一个空的活动来利用这一点。

 <activity android:name="com.t3hh4xx0r.haxlauncher.FakeHome" android:enabled="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> 

当你想设置新的默认值时,你启用这个组件,然后调用家庭意图,然后再次禁用你的假的家庭组件。

 public static void makePrefered(Context c) { PackageManager p = c.getPackageManager(); ComponentName cN = new ComponentName(c, FakeHome.class); p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); Intent selector = new Intent(Intent.ACTION_MAIN); selector.addCategory(Intent.CATEGORY_HOME); c.startActivity(selector); p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } 

最终的结果是系统认为已经安装了一个新的家庭应用程序,所以默认设置被清除,允许你设置你的没有特殊的权限。

感谢TeslaCoil和NovaLauncher的Kevin提供的信息。

r2DoesInc的解决scheme不适用于我的4.2.2testing设备。
我的解决scheme:禁用,然后重新启用我的应用程序的HomeActivity,它不必创buildFakeHome

 PackageManager p = getPackageManager(); ComponentName cN = new ComponentName(this, HomeActivity.class); p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); startActivity(new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)); p.setComponentEnabledSetting(cN, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); 

我在Android 4.1.2上使用以下代码,在工业平板电脑上使用平台签名的信息亭模式应用程序。 它使用了弃用的PackageManager.addPreferredActivity() ,但是它的优点是它在没有用户交互的情况下工作。 它甚至可以在标准Android启动器select“always”选项之后运行。

 // Requires permission SET_PREFERRED_APPLICATIONS. public static boolean setPreferredHomeActivity (Context context, String packageName, String className) { ComponentName oldPreferredActivity = getPreferredHomeActivity(context); if (oldPreferredActivity != null && packageName.equals(oldPreferredActivity.getPackageName()) && className.equals(oldPreferredActivity.getClassName())) { return false; } if (oldPreferredActivity != null) { context.getPackageManager().clearPackagePreferredActivities(oldPreferredActivity.getPackageName()); } IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); filter.addCategory(Intent.CATEGORY_HOME); filter.addCategory(Intent.CATEGORY_DEFAULT); ComponentName[] currentHomeActivities = getActivitiesListByActionAndCategory(context, Intent.ACTION_MAIN, Intent.CATEGORY_HOME); ComponentName newPreferredActivity = new ComponentName(packageName, className); context.getPackageManager().addPreferredActivity(filter, IntentFilter.MATCH_CATEGORY_EMPTY, currentHomeActivities, newPreferredActivity); return true; } private static ComponentName getPreferredHomeActivity (Context context) { ArrayList<IntentFilter> filters = new ArrayList<>(); List<ComponentName> componentNames = new ArrayList<>(); context.getPackageManager().getPreferredActivities(filters, componentNames, null); for (int i = 0; i < filters.size(); i++) { IntentFilter filter = filters.get(i); if (filter.hasAction(Intent.ACTION_MAIN) && filter.hasCategory(Intent.CATEGORY_HOME)) { return componentNames.get(i); }} return null; } private static ComponentName[] getActivitiesListByActionAndCategory (Context context, String action, String category) { Intent queryIntent = new Intent(action); queryIntent.addCategory(category); List<ResolveInfo> resInfos = context.getPackageManager().queryIntentActivities(queryIntent, PackageManager.MATCH_DEFAULT_ONLY); ComponentName[] componentNames = new ComponentName[resInfos.size()]; for (int i = 0; i < resInfos.size(); i++) { ActivityInfo activityInfo = resInfos.get(i).activityInfo; componentNames[i] = new ComponentName(activityInfo.packageName, activityInfo.name); } return componentNames; }