2010-10-01 168 views
23

对于一些特定的要求 我需要改变Android的默认主页应用 与我的个性主页的应用程序(我的应用程序内的设置,将切换默认主页=我的应用程序或以前的家)安卓:更改默认主页应用

我不希望用户移动非常复杂的android设置。

任何一个可以帮助我喜欢在那里注册launcher.apk默认 家庭应用或者如何更改

我能找到的唯一的事情就是那个老问题:How to change default Android's Desktop application?

,但没有答案在所有。

我已经看到了HomeSwitcher在市场上做的伎俩,但没有回答开发人员可能一定会很忙。

编辑

,我发现这个网页http://www.mail-archive.com/[email protected]/msg74167.html

上,但我得到了同样的问题:

这是我的代码:

private void makePreferred() { 
      PackageManager pm = getPackageManager(); 
      IntentFilter f = new IntentFilter("android.intent.action.MAIN"); 
      f.addCategory("android.intent.category.HOME"); 
      f.addCategory("android.intent.category.DEFAULT"); 
      ComponentName cn = new ComponentName("com.example.android.home", "com.example.android.home.Home"); 
      pm.addPreferredActivity(f, IntentFilter.MATCH_CATEGORY_EMPTY, null, cn); 

我有android.permission.SET_PREFERRED_APPLICATIONS集在 清单中。在执行上面的代码之后,日志宣称已添加 像预期的那样(与从IntentResolver列表中勾选“设为默认” 时的日志相同)。然而,当我继续点击回家, 列表中仍然显示和记录说:

INFO/PackageManager(52): Result set changed, dropping preferred 
activity for Intent { act=android.intent.action.MAIN cat= 
[android.intent.category.HOME] flg=0x10200000 } type null 

如此看来解析器删除默认项。我在做 有什么问题,或者这是安全措施?这背后有什么想法 ?

+1

我敢肯定你不能强迫用户使用你的意图,作为默认的任何东西 - 它应该永远是他们的选择。将其注册为家庭意图应该足以让用户获得询问他们想要启动哪个家庭应用程序的对话。 – 2010-11-05 15:34:17

+0

这是不可能的,除非你正在使用手机的主要版本,甚至还有风险。考虑告诉你的请求者没有。因为这不是从应用程序的角度来看的行为。 – JoxTraex 2012-01-29 07:39:27

回答

8

我做了一个广泛的研究,并从2.2开始,没有办法做到这一点。唯一的办法是使用一些蹒跚学步的锁应用程序黑客,但这个应用程序最近在无限循环中放置三星手机,所以这是一个冒险的方法。

如果你看一下packagemanager类的Froyo的源代码here,你会看到在addPreferredActivity方法这个小状况:

if (getUidTargetSdkVersionLockedLP(Binder.getCallingUid()) 
        < Build.VERSION_CODES.FROYO) { 
       Slog.w(TAG, "Ignoring addPreferredActivity() from uid" 
         + Binder.getCallingUid()); 
       return; 
      } 

HomeSwitcher不正常的2.2工作,因为它使用了这种非常方法和开发由应用页面上的评论“升级Froyo(2.2)不支持 由于API的变化

+0

OP没有击中那条路。他的错误是“放弃首选活动...”,这是在代码中进一步生成的。所有检查都会阻止您从未针对Froyo构建的应用程序调用addPreferredActivity。 – 2011-01-10 15:56:35

7

“结果集改变”意味着该组匹配的这一意图的包已经从您指定的组更改了C重新设定了默认值 - - 因此默认值不再有效。您的组件列表(您当前设置为空)需要包含设备上的所有主屏幕应用程序,而不仅仅是您的设备。

下面是我测试过的示例代码(使用adb shell am start http://www.google.co.uk/)并用于设置默认浏览器。XXX代表我必须停用的客户名称。

请注意,为了调用addPreferredActivity,您必须针对最低sdk版本8(2.2)进行编译,并且您必须指定SET_PREFERRED_APPLICATIONS权限。该权限是保护级别2,因此您需要使用与PackageManager相同的证书进行签名。

IntentFilter filter = new IntentFilter(); 
filter.addAction("android.intent.action.VIEW"); 
filter.addCategory("android.intent.category.DEFAULT"); 
filter.addDataScheme("http"); 
Context context = getApplicationContext(); 
ComponentName component = new ComponentName("com.opera.mini.XXX", "com.opera.mini.XXX.CustomerBrowser"); 
ComponentName[] components = new ComponentName[] {new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"), 
                component}; 
pm.addPreferredActivity(filter, IntentFilter.MATCH_CATEGORY_SCHEME, components, component); 

ETA - 如果你标记了这个响应,你能让我知道为什么。我上面贴测试及工作中的代码...

+6

如何用相同的证书签名? – hoffmanc 2012-01-13 18:01:47

+0

我也想实现它,我想在第一次启动后更改默认启动程序。我已经把代码放到PackageManagerService的构造函数中,但它总是失败。你能告诉我如果我想这样做,我应该把代码放在哪个位置?非常感谢! – alexunder 2013-09-24 13:43:51

+0

@hoffmanc你将需要构建操作系统的平台密钥。除非您正在构建和签署自己的ROM,否则您将无法访问这些内容。 – amitav13 2016-03-01 19:36:25

0

此代码的工作我的ICS设备上:我使用一种服务,是明智的一些电话,其中一个被称为SET_PREFERRED_LAUNCHER,看跌期权在捆绑新默认启动包(PREFERRED_PACKAGE_KEY)和它的活动(PREFERRED_ACTIVITY_KEY)

Method installPackageMethod = null; 
Method deletePackageMethod = null; 
Method setPreferredActivityMethod = null; 
Method replacePreferredActivityMethod = null; 
Object pm = null; 


    @Override 
public void onCreate() { 
    super.onCreate(); 
     if (pm == null) 
     pm = getPackageManager(); 
    try { 
     if (setPreferredActivityMethod == null) 
      setPreferredActivityMethod = pm.getClass().getMethod(
        "addPreferredActivity", IntentFilter.class, int.class, 
        ComponentName[].class, ComponentName.class); 
    } catch (NoSuchMethodException e) { 
     e.printStackTrace(); 
    } 
} 


private final class ServiceHandler extends Handler { 
    private Context context; 

    public ServiceHandler(Looper looper, Context ctx) { 
     super(looper); 
     context = ctx; 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     Intent intent = (Intent) msg.getData().getParcelable(
       UPDATER_SERVICE_ACTION); 
     int request = intent.getIntExtra(
       REQUEST_KEY, 
       REQUEST_UNKNOWN); 
     Bundle bundle = intent.getExtras(); 

     switch (request) { 
     case INSTALL_APPLICATION: { 
      if (bundle != null) { 
       String appPath = bundle 
         .getString(APP_PATH_KEY); 
       if (appPath != null) { 
        LogUtil.e(TAG, "try to install " + appPath); 

        try { 
         am.installPackage(appPath); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 

        LogUtil.e(TAG, "install of " + appPath + " done"); 
       } 
      } 
      break; 
     } 
     case UNISTALL_PACKAGE: { 
      if (bundle != null) { 
       String packagename = bundle 
         .getString(PACKAGE_NAME_KEY); 
       if (packagename != null) { 
        LogUtil.e(TAG, "unistall " + packagename); 

        try { 
         deletePackageMethod 
           .invoke(pm, packagename, null, 0); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
      break; 
     } 
     case SET_PREFERRED_LAUNCHER: { 
      if (bundle != null) { 
       String package_name = bundle 
         .getString(PREFERRED_PACKAGE_KEY); 
       if (package_name == null) { 
        LogUtil.e(TAG, 
          "WARNING: setDefaultActivity cannot continue, package is NULL"); 
        return; 
       } 
       String activity_name = bundle 
         .getString(PREFERRED_ACTIVITY_KEY); 
       if (activity_name == null) { 
        LogUtil.e(TAG, 
          "WARNING: setDefaultActivity cannot continue, activity is NULL"); 
        return; 
       } 

       LogUtil.e(TAG, "setDefaultActivity activity=" 
         + activity_name + " package=" + package_name); 

       IntentFilter filter = new IntentFilter(
         "android.intent.action.MAIN"); 
       filter.addCategory("android.intent.category.HOME"); 
       filter.addCategory("android.intent.category.DEFAULT"); 
       ComponentName[] components = new ComponentName[] { 
         new ComponentName("com.android.launcher", 
           "com.android.launcher2.Launcher"), 
         new ComponentName(package_name, activity_name) }; 
       ComponentName activity = new ComponentName(package_name, 
         activity_name); 
       try { 
        setPreferredActivityMethod.invoke(pm, filter, 
          IntentFilter.MATCH_CATEGORY_EMPTY, components, 
          activity); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     } 

    } 

} 

记得在您的清单文件中添加以下权限:

<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"/> 

用法:

public void setPreferredLauncher(String activity_name,String package_name) 
{ 
    Intent intent = new Intent(UPDATER_SERVICE_ACTION); 
    intent.putExtra(REQUEST_KEY, SET_PREFERRED_LAUNCHER); 
    intent.putExtra(PREFERRED_ACTIVITY_KEY, activity_name); 
    intent.putExtra(PREFERRED_PACKAGE_KEY, package_name); 
    context.startService(intent); 
} 

其中:

public static final String _UPDATER_SERVICE_ACTION = "com.android.updaterservice.ACTION"; 
public static final String REQUEST_KEY = "com.android.updaterservice.REQUEST_KEY"; 
public static final String PACKAGE_NAME_KEY = "com.android.updaterservice.PACKAGE_NAME_KEY"; 
public static final String APP_PATH_KEY = "com.android.updaterservice.APP_PATH_KEY"; 
public static final String PREFERRED_ACTIVITY_KEY = "com.android.updaterservice.PREFERRED_ACTIVITY_KEY"; 
public static final String PREFERRED_PACKAGE_KEY = "com.android.updaterservice.PREFERRED_PACKAGE_KEY"; 
public static final String INSTALL_PACKAGE_RESULT = "com.android.updaterservice.INSTALL_PACKAGE_RESULT"; 
public static final String PACKAGE_NAME = "PACKAGE_NAME"; 
public static final String INSTALL_SUCCEEDED = "INSTALL_SUCCEEDED"; 
public static final int REQUEST_UNKNOWN = -1; 
public static final int INSTALL_APPLICATION = 1; 
public static final int UNISTALL_PACKAGE = 2; 
public static final int SET_PREFERRED_LAUNCHER = 3; 
+1

请注意,只有使用与签署固件相同的签名密钥签名的应用才能保存“SET_PREFERRED_APPLICATIONS”权限。 – CommonsWare 2012-10-12 22:16:18

+0

在am.installPackage()..什么是我?要申报什么?并没有serviceHandler的使用..请更新它正确 – 2013-04-12 15:04:38

0
startActivity(new Intent(Settings.ACTION_HOME_SETTINGS)); 
+0

这需要设置,并使您能够手动设置主页启动程序,但不会将其设置回默认的启动程序。 – saiyancoder 2016-04-08 05:08:35