Java 清除和设置默认主应用程序
Nova究竟是如何做到这一点的?我真的在尝试做完全相同的事情:为用户提供一个按钮来清除并选择他们的新默认启动器 我可以获取默认应用程序名称并显示它:Java 清除和设置默认主应用程序,java,android,launcher,Java,Android,Launcher,Nova究竟是如何做到这一点的?我真的在尝试做完全相同的事情:为用户提供一个按钮来清除并选择他们的新默认启动器 我可以获取默认应用程序名称并显示它: private String getPrefered(Intent i) { PackageManager pm = this.getActivity().getPackageManager(); final ResolveInfo mInfo = pm.resolveActivity(i, 0);
private String getPrefered(Intent i) {
PackageManager pm = this.getActivity().getPackageManager();
final ResolveInfo mInfo = pm.resolveActivity(i, 0);
return (String) pm.getApplicationLabel(mInfo.activityInfo.applicationInfo);
}
其中意图i
为
Intent home = new Intent("android.intent.action.MAIN");
home.addCategory("android.intent.category.HOME");
然后我调用系统解析活动
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);
}
选择器出现并正常工作,但它实际上没有设置或清除任何值。在调试它的时候,我好像遗漏了一些额外的东西?当我调用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
实现这一点的代码实际上只是一个非常巧妙的解决方法 当一个组件
<category android:name="android.intent.category.HOME" />
最终的结果是,系统认为安装了新的家庭应用程序,因此默认设置被清除,允许您在没有特殊权限的情况下设置自己的应用程序
感谢TeslaCoil和NovaLauncher的Kevin提供有关如何完成此任务的信息 r2DoesInc的解决方案在我的4.2.2测试设备上不起作用。
我的解决方案:禁用然后重新启用我的应用程序的HomeActivity,它不必创建
FakeHome
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上使用以下代码,并在工业平板电脑上使用平台签名的kiosk模式应用程序。它使用了不推荐使用的
PackageManager.addPreferredActivity()
,但其优点是无需用户交互即可工作。它甚至可以在标准安卓启动器选择了“始终”选项后工作
//需要权限集\首选\应用程序。
公共静态布尔setPreferredHomeActivity(上下文上下文、字符串packageName、字符串类名){
ComponentName oldPreferredActivity=getPreferredHomeActivity(上下文);
if(oldprefereredactivity!=null&&packageName.equals(oldprefereredactivity.getPackageName())&&className.equals(oldprefereredactivity.getClassName()){
返回false;}
如果(oldPreferredActivity!=null){
context.getPackageManager().clearPackagePreferredActivities(oldPreferredActivity.getPackageName());}
IntentFilter过滤器=新的IntentFilter(Intent.ACTION\u MAIN);
filter.addCategory(Intent.CATEGORY\u HOME);
filter.addCategory(Intent.CATEGORY\u默认值);
ComponentName[]currentHomeActivities=getActivitiesListByActionAndCategory(上下文,Intent.ACTION\u MAIN,Intent.CATEGORY\u HOME);
ComponentName newPreferredActivity=新的ComponentName(packageName,className);
context.getPackageManager().addPreferredActivity(筛选器、IntentFilter.MATCH_CATEGORY_EMPTY、currentHomeActivities、newPreferredActivity);
返回true;}
私有静态组件名getPreferredHomeActivity(上下文){
ArrayList过滤器=新的ArrayList();
List componentNames=new ArrayList();
context.getPackageManager().getPreferredActivities(筛选器、组件名称、null);
对于(int i=0;i
进一步了解@Bruce的答案(不使用假主活动),您可以使用PackageManager.setComponentEnabledSetting先禁用组件,然后根据主意图解析活动(而不是使用startActivity),然后启用组件,然后根据意图启动Tactivity
Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME);
PackageManager pm = getPackageManager();
ResolveInfo rInfo = pm.resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (!rInfo.activityInfo.packageName.equals(getPackageName())) { // your app is not the default HOME
ComponentName cn = <ComponentName object of your home activity>
pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
startActivity(homeIntent);
}
Intent homeentent=newintent(Intent.ACTION\u MAIN)。addCategory(Intent.CATEGORY\u HOME);
PackageManager pm=getPackageManager();
ResolveInfo rInfo=pm.resolveActivity(仅限homeIntent、PackageManager.MATCH_DEFAULT_);
如果(!rInfo.activityInfo.packageName.equals(getPackageName()){//您的应用程序不是默认的主应用程序
组件名称cn=
pm.setComponentEnabledSetting(cn,PackageManager.COMPONENT\u ENABLED\u STATE\u DISABLED,PackageManager.DONT\u KILL\u APP);
pm.resolveActivity(仅限homeIntent、PackageManager.MATCH_DEFAULT_);
pm.setComponentEnabledSetting(cn,PackageManager.COMPONENT\u ENABLED\u STATE\u ENABLED,PackageManager.DONT\u KILL\u APP);
startActivity(家庭意向);
}
我在4.2.2上尝试过这个,但它不起作用。。。仅当安装新的Home Launcher时,行为如您所述。很好,即使有权限,我也无法使用set_preferred_application()。此示例需要在某些设备上具有权限“”。您好,r2DoesInc,我还尝试处理Home按钮,在我的应用程序中,我处理Home键,但在应用程序的外侧,当按下home键时,我的启动器正在调用。有什么我错过的吗。请给我一些指导,谢谢。如果已经设置了另一个默认启动程序,那么这在4.4.2上似乎不起作用(有人能确认吗?)。启用假活动似乎没有什么区别,当设备达到c.startActivity(选择器)时,不会显示任何对话框并返回到原始默认应用程序代码>对我来说。你是如何在4.1.2上请求权限android.permission.SET_PREFERRED_应用程序的??我看到它被弃用了“这个常量在API级别7中被弃用了”。@umesh I
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);
// 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; }
Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME);
PackageManager pm = getPackageManager();
ResolveInfo rInfo = pm.resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (!rInfo.activityInfo.packageName.equals(getPackageName())) { // your app is not the default HOME
ComponentName cn = <ComponentName object of your home activity>
pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY);
pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
startActivity(homeIntent);
}