Android: изменить стандартное домашнее приложение

по некоторым конкретным требованиям я должен изменить приложение Android по умолчанию для дома с помощью своего настраиваемого приложения Home (параметр внутри моего приложения, который будет переключаться по умолчанию home = мое приложение или предыдущий дом)

Я не хочу, чтобы пользователь путешествовал с настройками Android, которые очень сложны.

Может ли кто-нибудь помочь мне, например, где он регистрирует launcher.apk для домашнего приложения по умолчанию или как это изменить

Единственное, что я смог найти, это старый вопрос:Как изменить стандартное приложение Android для рабочего стола?

но ответов нет вообще.

Я видел 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

Так что, похоже, распознаватель удаляет запись по умолчанию. Я что-то не так делаю или это мера безопасности? Какие идеи стоят за этим?

 JoxTraex29 янв. 2012 г., 08:39
Это невозможно, если вы не работаете с основной сборкой для телефона, и даже тогда это все еще рискованно. Подумайте о том, чтобы сообщить своему заказчику НЕТ. Потому что это не ожидаемое поведение с точки зрения приложений.
 Kyle P05 нояб. 2010 г., 16:34
Я почти уверен, что вы не можете заставить пользователя использовать ваше намерение как значение по умолчанию - это всегда должно быть их выбором. Регистрация его в качестве домашней цели должна быть достаточной для того, чтобы пользователь получил диалоговое окно с вопросом, какое домашнее приложение он хочет запустить.

Ответы на вопрос(4)

«Результирующий набор изменен» означает, что набор пакетов, соответствующих этому намерению, изменился по сравнению с набором, который вы указали при создании значения по умолчанию - поэтому значение по умолчанию больше не действует.а ноль) должен содержать все приложения рабочего стола, присутствующие на устройстве, а не только ваши.

Вот пример кода, который я протестировал (с помощью adb shell я начинаю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);

ЭТА - если вы отметили этот ответ, не могли бы вы дать мне знать, почему. Код, который я разместил выше, протестирован и работает ...

 hoffmanc13 янв. 2012 г., 19:01
как подписать его тем же сертификатом?
 amitav1301 мар. 2016 г., 20:36
@hoffmanc вам понадобятся ключи платформы, на которых была создана ОС. Если вы не создаете и не подписываете свой собственный ROM, у вас не будет доступа к ним.
 alexunder24 сент. 2013 г., 15:43
Я тоже хочу это реализовать, я хочу сменить панель запуска по умолчанию после первой загрузки. Я поместил код в конструктор PackageManagerService, но он всегда терпел неудачу. Можете ли вы сказать мне, если я хочу сделать это, какую позицию я должен поставить код? Спасибо большое!
Решение Вопроса

и, начиная с версии 2.2, я не могу этого сделать. Единственный способ - это взломать приложение для блокировки малышей, но это приложение недавно поставило телефоны Samsung в бесконечный цикл, так что это рискованный подход.

если вы посмотрите на исходный код FroyoВот класса packagemanager вы увидите это небольшое условие в методе 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"

 Airsource Ltd10 янв. 2011 г., 16:56
ОП не бьет этого бандита. Его ошибка - «отбрасывание предпочтительной активности ...», которая генерируется далее в коде. Все, что делает проверка, - это запрещает вам вызывать addPreferredActivity из приложения, которое не было построено для Froyo.
startActivity(new Intent(Settings.ACTION_HOME_SETTINGS));
 saiyancoder08 апр. 2016 г., 07:08
Это принимает к настройкам и позволяет вам вручную установить Home Launcher, но не устанавливает его обратно на Launcher по умолчанию программно.

я использую службу, которая подходит для какого-либо вызова, один из них называется 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;
 Nirav Dangi12 апр. 2013 г., 17:04
В am.installPackage () .. что это такое? что объявить? и там нет использования serviceHandler .. пожалуйста, обновите его правильно
 CommonsWare13 окт. 2012 г., 00:16
Обратите внимание, что только приложения, подписанные с тем же ключом подписи, что и прошивка, могут хранитьSET_PREFERRED_APPLICATIONS разрешение.

Ваш ответ на вопрос