Как получить приложение помощи устройства по умолчанию в Android по коду?

мой телефон установил два голосовых поиска: приложение google и приложение S-voice. Приложением по умолчанию является приложение S-voice, как показано на рисунке ниже. Мой вопрос заключается в том, как мы можем получить голосовое приложение по умолчанию с помощью программирования в Android 6.0. заранее спасибо

введите здесь описание изображения

Это то, что я сделал

private boolean isMyAppLauncherDefault(String myPackageName) {
    final IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
    filter.addCategory(Intent.CATEGORY_HOME);

    List<IntentFilter> filters = new ArrayList<IntentFilter>();
    filters.add(filter);
    List<ComponentName> activities = new ArrayList<ComponentName>();
    final PackageManager packageManager = (PackageManager) getPackageManager();

    packageManager.getPreferredActivities(filters, activities, null);
    for (ComponentName activity : activities) {

        Log.d(TAG,"======packet default:==="+activity.getPackageName());
    }
    for (ComponentName activity : activities) {

        if (myPackageName.equals(activity.getPackageName())) {
            return true;
        }
    }
    return false;
}

Вышеупомянутая функция всегда возвращает true, когда мой ввод com.samsung.voiceserviceplatform. В других случаях приложение по умолчанию всегда возвращает com.google.android.googlequicksearchbox (указывает на Google Voice).


comment
Вам нужно инициировать приложение Google программно?   -  person AndroidHacker    schedule 09.11.2016
comment
Нет, сэр, мне просто нужно включить приложение google или svoice из настроек по умолчанию. Например, если моя настройка по умолчанию — svoice, я запущу svoice. Если в качестве настройки голоса по умолчанию используется Google Voice, я буду звонить в Google Voice.   -  person Jame    schedule 09.11.2016


Ответы (3)


DefaultAssistPreference использует скрытый метод AssistUtils для получения текущей помощи. Вы можете использовать тот же метод, используя отражение:

public ComponentName getCurrentAssistWithReflection(Context context) {
    try {
        Method myUserIdMethod = UserHandle.class.getDeclaredMethod("myUserId");
        myUserIdMethod.setAccessible(true);
        Integer userId = (Integer) myUserIdMethod.invoke(null);

        if (userId != null) {
            Constructor constructor = Class.forName("com.android.internal.app.AssistUtils").getConstructor(Context.class);
            Object assistUtils = constructor.newInstance(context);

            Method getAssistComponentForUserMethod = assistUtils.getClass().getDeclaredMethod("getAssistComponentForUser", int.class);
            getAssistComponentForUserMethod.setAccessible(true);
            return (ComponentName) getAssistComponentForUserMethod.invoke(assistUtils, userId);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

Если вы не хотите использовать отражение, вы можете напрямую проверить настройки системы:

public ComponentName getCurrentAssist(Context context) {
    final String setting = Settings.Secure.getString(context.getContentResolver(), "assistant");

    if (setting != null) {
        return ComponentName.unflattenFromString(setting);
    }

    return null;
}

Это тот же параметр, который читается как AssistUtils, но AssistUtils также имеет запасной вариант, если параметр недействителен.

person Mattia Maestrini    schedule 12.11.2016
comment
Спасибо. Из вашего ответа я пытаюсь распечатать список приложений по умолчанию в помощнике, но это не работает. Я использовал код: ComponentName activity=getCurrentAssistWithReflection(getApplicationContext()); Log.d("TAG","======packet default:==="+activity.getPackageName()); - person Jame; 13.11.2016
comment
Этот код находится внутри блока try или ваше приложение аварийно завершает работу при выполнении кода? Потому что, если getCurrentAssistWithReflection не работает, он возвращает null, и вы не можете getPackageName нулевого экземпляра. - person Mattia Maestrini; 13.11.2016
comment
Попробую на своем реальном устройстве. Я думаю, что это не будет работать на моем эмуляторе. Кроме того, у меня есть два приложения в помощнике. Как я могу перечислить эти приложения? Приведенный выше скрипт может отображать только одно приложение. - person Jame; 13.11.2016
comment
Он возвращает приложение по умолчанию, а не список. Ваш вопрос мне понятен: how can we get the default voice application using programmingcally in Android 6.0. Вы не запрашивали список приложений-помощников. - person Mattia Maestrini; 13.11.2016
comment
Извините, вы правы. Он возвращает только одно приложение по умолчанию. Я проверю на своем реальном устройстве и подтвержу вам - person Jame; 13.11.2016
comment
Я подтвердил, что ваш код getCurrentAssistWithReflection работает хорошо, как я и ожидал. Я проверил это на своем реальном устройстве. Второй способ getCurrentAssist не работает. Однако мне достаточно первого способа. Как вы думаете, ваш первый метод также работает в Android L? Спасибо - person Jame; 14.11.2016
comment
Нет, AssistUtils добавлено в Android M, оно недоступно в Android L. - person Mattia Maestrini; 15.11.2016
comment
Знаете ли вы какой-либо способ получить голосовое приложение по умолчанию в Android L? Просто дополнительный вопрос. В Android L это можно увидеть, зайдя в Управление задачами (долгое нажатие кнопки «Домой») › По умолчанию - person Jame; 15.11.2016
comment
@MattiaMaestrini метод без отражения не работает на Android O - person Lior Iluz; 01.05.2017
comment
@LiorIluz Как и многие другие вещи в Android, способ справиться с этим состоит в том, чтобы вызвать getCurrentAssist и вернуться к getCurrentAssistWithReflection, чтобы вы обрабатывали каждый доступный сценарий. - person Abandoned Cart; 27.12.2018

Попробуй это.

startActivity(new Intent(Intent.ACTION_VOICE_COMMAND).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
person AndroidHacker    schedule 09.11.2016
comment
Я использовал его раньше, но он всегда вызывает голос Google, а не настройку голоса по умолчанию. - person Jame; 09.11.2016
comment
Спасибо, теперь это сработало. Это работало только в 5.0, а не в 6.0. Ты знаешь почему? - person Jame; 09.11.2016
comment
Я снова протестировал. Вышеупомянутая функция не является стабильной. Он покажет мне возможность выбора между Svoice и Google voice. Однако, если я не выберу какое-либо приложение. это будет Google по умолчанию, а затем, когда я включу намерение, голос Google иногда ничего не показывает. Я использовал код для Google `intent.setClassName(com.google.android.googlequicksearchbox, com.google.android.googlequicksearchbox.VoiceSearchActivity);` - person Jame; 09.11.2016
comment
Извиняюсь. Я не могу принять ваш ответ, потому что он не может решить мою проблему. Я снова тестирую в Android L и встречаю вышеуказанную проблему. Проблема в том, что когда я использовал ваш код, иногда не включался google voice или s-voice. Я вызываю вышеуказанную функцию в сервисе. - person Jame; 10.11.2016

Я пытаюсь ответить от Mattia Maestrini, это сработало, если возвращаемый компонент является действием, например

ComponentInfo{com.sec.android.app.sbrowser/com.sec.android.app.sbrowser.SBrowserMainActivity}

но если компонент является службой, я встречаю следующую проблему

java.lang.SecurityException: Not allowed to start service Intent { 
act=android.intent.action.ASSIST cmp=com.google.android.googlequicksearchbox/com.google.android.voiceinteraction.GsaVoiceInteractionService launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 } } without permission android.permission.BIND_VOICE_INTERACTION

и я добавляю

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

в файле манифеста.

Наконец я использую метод в Activity.java

public boolean showAssist(Bundle args)

Он добавлен из Android M и может успешно запустить службу помощника.

person zhanzhan0812    schedule 21.09.2017