Очистка и настройка домашнего приложения по умолчанию
Как в мире Нова справляется с этим? Я буквально пытаюсь сделать то же самое: предоставить пользователям кнопку, чтобы нажать, чтобы очистить и выбрать новую пусковую установку по умолчанию.
Я могу получить имя приложения по умолчанию и показать его:
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);
}
Сборщик подходит и работает правильно, но на самом деле он не устанавливает или не очищает любые значения. Во время отладки, кажется, мне не хватает некоторых дополнительных услуг? Когда я вызываю метод 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
- Как я могу попасть туда и посмотреть, что отправляется вместе с этим пакетом?
- Как я могу просто удалить предпочтительное приложение? Не говорите мне, что не можете, я видел достаточно ответов. Nova делает это и делает это именно так, как хотелось бы.
Ответы
Ответ 1
Код для этого - на самом деле просто очень умная работа.
Когда компонент с
<category android:name="android.intent.category.HOME" />
включен, как правило, из установки нового домашнего приложения, стандартное домашнее приложение очищается.
Чтобы воспользоваться этим, создав пустую активность с домашним компонентом, подобным этому.
<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 за информацию о том, как это делается!
Ответ 2
Решение 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);
Ответ 3
Я использую следующий код на Android 4.1.2 с платформенным приложением на киоск-режиме на промышленном планшете. Он использует устаревший PackageManager.addPreferredActivity()
, но преимущество в том, что он работает без взаимодействия с пользователем. Он даже работает после того, как стандартная пусковая установка Android была выбрана с опцией "всегда".
// 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; }
Ответ 4
Продолжая ответ @Bruce (без использования фальшивой домашней активности), вы можете использовать PackageManager.setComponentEnabledSetting, чтобы сначала отключить компонент, затем resolActivity для домашнего намерения (вместо использования startActivity), затем включить компонент, а затем запустить с намерением startActivity.
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);
}