androidandroid-intentandroid-6.0-marshmallowandroid-settingsgoogle-voice

How to get default device assistance app in android by code?


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)


Solution

  • 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.