【问题标题】:How to get default device assistance app in android by code?如何通过代码在android中获取默认设备辅助应用程序?
【发布时间】:2016-11-09 04:21:19
【问题描述】:

我的手机安装了两个语音搜索:google app 和 S-voice app。默认应用是 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;
}

当我的输入是com.samsung.voiceserviceplatform 时,上述函数总是返回true。另一方面,默认应用总是返回com.google.android.googlequicksearchbox(表示谷歌语音)

【问题讨论】:

  • 您需要以程序方式启动 Google App 吗?
  • 不,先生,我只需要从默认设置打开 google 或 svoice 应用程序。例如,如果我的默认设置是 svoice,我将启动 svoice。如果我的默认语音设置是谷歌语音,我会拨打谷歌语音

标签: android android-intent android-6.0-marshmallow android-settings google-voice


【解决方案1】:

DefaultAssistPreference 使用 AssistUtils 的隐藏方法来检索当前的 Assist。您可以通过反射使用相同的方法:

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 也有一个fallback

【讨论】:

  • 谢谢。根据您的回答,我尝试在助手中打印默认应用程序列表,但它不起作用。我使用了代码:ComponentName activity=getCurrentAssistWithReflection(getApplicationContext()); Log.d("TAG","======packet default:==="+activity.getPackageName());
  • 这段代码是在 try 块中还是在您执行代码时应用程序崩溃?因为如果 getCurrentAssistWithReflection 不起作用,它会返回 null 并且您不能 getPackageName 的 null 实例。
  • 我会在我的真机上试一试。我认为它不适用于我的模拟器。此外,我在助手中有两个应用程序。如何列出这些应用程序?上述脚本只能显示一个应用程序。
  • 返回默认应用程序,不返回列表。你的问题对我来说很清楚:how can we get the default voice application using programmingcally in Android 6.0。您没有要求提供助手应用列表。
  • 不,AssistUtils 在 Android M 中添加,在 Android L 中不可用
【解决方案2】:

试试这个。

startActivity(new Intent(Intent.ACTION_VOICE_COMMAND).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));

【讨论】:

  • 我以前用过,但它总是调用谷歌语音,而不是我的默认语音设置
  • 感谢它现在有效。它仅适用于 5.0,而不是 6.0。你知道为什么吗?
  • 我又测试了一遍。上述功能不稳定。它将向我显示在 Svoice 和 Google 语音之间进行选择的选项。但是,如果我不选择任何应用程序。它会默认谷歌,然后当我打开意图时,谷歌语音有时什么也没有显示。我使用了谷歌的代码`intent.setClassName("com.google.android.googlequicksearchbox", "com.google.android.googlequicksearchbox.VoiceSearchActivity");`
  • 对不起。我不能接受你的回答,因为它不能解决我的问题。我在 Android L 中再次测试并遇到上述问题。问题是当我使用你的代码时,谷歌语音或 s-voice 有时无法打开。我在服务中调用上述函数。
【解决方案3】:

我尝试从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添加,可以成功启动助手服务。

【讨论】:

    【解决方案4】:

    如果有人为此搜索快速的 kotlin 版本:

    fun getCurrentlySelecetedDefaultAssistant(context: Context): ComponentName? =
        Settings.Secure.getString(context.contentResolver, "assistant").let { assistantIdentifier ->
            if (assistantIdentifier.isNotEmpty()) {
                ComponentName.unflattenFromString(assistantIdentifier)
            } else {
                null
            }
        }
    

    感谢:https://stackoverflow.com/a/40566276/371749 刚刚重写。

    【讨论】:

      猜你喜欢
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 2017-01-16
      • 2019-03-13
      • 2022-09-27
      • 2013-08-20
      • 1970-01-01
      • 2014-06-21
      相关资源
      最近更新 更多