How to get default device assistance app in androi

2019-08-02 04:13发布

my phone installed two voice searches: google app and S-voice app. The default app is S-voice app as figure bellow. My question is that how can we get the default voice application using programmingcally in Android 6.0. Thank you in advance

enter image description here

This is what I did

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;
}

The above function is alway return true when my input is com.samsung.voiceserviceplatform. In other hands, the default app always returns com.google.android.googlequicksearchbox (indicates google voice)

3条回答
做自己的国王
2楼-- · 2019-08-02 04:45

I try answer from Mattia Maestrini, it did work if returned component is an activity, like

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

but if the component is a service, I meet following problem

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

and I do add

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

in Manifest file.

At last I use method in Activity.java

public boolean showAssist(Bundle args)

It's added from Android M and it could start assistant service successfully.

查看更多
我只想做你的唯一
3楼-- · 2019-08-02 04:50

The DefaultAssistPreference uses an hidden method of AssistUtils to retrieve the current Assist. You can use the same method using reflection:

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;
}

If you don't want to use reflection you can directly check the system settings:

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

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

    return null;
}

It is the same setting that reads AssistUtils, but AssistUtils has also a fallback if the setting is not valid.

查看更多
走好不送
4楼-- · 2019-08-02 04:54

Try this.

startActivity(new Intent(Intent.ACTION_VOICE_COMMAND).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
查看更多
登录 后发表回答