web-dev-qa-db-fra.com

Récupérer l'agent utilisateur par programme

Existe-t-il un moyen de récupérer l'agent utilisateur du navigateur sans avoir un WebView en activité?

Je sais qu'il est possible de l'obtenir via WebView:

WebView view = (WebView) findViewById(R.id.someview);
String ua = view.getSettings().getUserAgentString() ;

Mais dans mon cas, je n'ai pas/n'ai pas besoin d'un objet webview et je ne veux pas le créer juste pour récupérer la chaîne de l'agent utilisateur.

36
Laimoncijus

Si vous n'en avez pas en avoir un, vous pouvez essayer de le prendre comme ceci

String ua=new WebView(this).getSettings().getUserAgentString();

Éditer-

Le doc pour getUserAgentString() dit

Retourne la chaîne d'agent utilisateur de WebView.

Je ne pense donc pas que vous puissiez l'obtenir à moins d'en déclarer un. Quelqu'un me corrige si je me trompe

54
DeRagan

Il existe un moyen beaucoup plus simple si vous êtes sur Android 2.1 ou supérieur. Certes, ce n'est pas exactement la même chaîne d'agent utilisateur qu'une vue Web retournerait, mais pourrait vous servir assez bien pour vos besoins .

Pour tirer un avantage supplémentaire de la vue Web, vous pouvez l'utiliser à partir de n'importe quel thread (et pas seulement du thread d'interface utilisateur).

Il existe une propriété système appelée http.agent, qui peut être utilisée pour récupérer la chaîne User-Agent.

String userAgent = System.getProperty("http.agent");

Voir Obtenir par programme la chaîne de l'agent utilisateur pour plus de détails.

56
Craig Russell

J'avais l'habitude d'utiliser solution proposé par DeRagan. Mais il s'est avéré que la création d'une seule instance WebView démarre un thread "WebViewCoreThread" qui reste en arrière-plan jusqu'à la fin de l'application par le système. Peut-être qu'il ne consomme pas trop de ressources mais je ne l'aime pas de toute façon. J'utilise donc maintenant une méthode légèrement différente, qui essaie d'éviter la création de WebViewCoreThread:

// You may uncomment next line if using Android Annotations library, otherwise just be sure to run it in on the UI thread
// @UiThread 
public static String getDefaultUserAgentString(Context context) {
  if (Build.VERSION.SDK_INT >= 17) {
    return NewApiWrapper.getDefaultUserAgent(context);
  }

  try {
    Constructor<WebSettings> constructor = WebSettings.class.getDeclaredConstructor(Context.class, WebView.class);
    constructor.setAccessible(true);
    try {
      WebSettings settings = constructor.newInstance(context, null);
      return settings.getUserAgentString();
    } finally {
      constructor.setAccessible(false);
    }
  } catch (Exception e) {
    return new WebView(context).getSettings().getUserAgentString();
  }
}

@TargetApi(17)
static class NewApiWrapper {
  static String getDefaultUserAgent(Context context) {
    return WebSettings.getDefaultUserAgent(context);
  }
}

Il crée WebSettings instance directement à l'aide du constructeur visible par le package et si cela n'est pas disponible pour une raison quelconque (par exemple en raison de modifications de l'API à l'avenir Android Android) - revient silencieusement à " Solution de type "WebView".

[~ # ~] mise à jour [~ # ~]

Comme indiqué par @ Skywalker5446 , à partir de Android 4.2/API 17, il existe une méthode statique publique pour obtenir la valeur par défaut de l'agent utilisateur. J'ai mis à jour mon code pour utilisez cette méthode sur les plates-formes prises en charge.

35
Idolon

Depuis Android 2.1 vous devez utiliser System.getProperty ("http.agent");

Vous n'avez pas non plus besoin de créer un WebView en premier ET, c'est l'avantage, vous pouvez l'utiliser dans un non-uithread.

salutations steve

10
JacksOnF1re

Il s'agit d'une solution mise à jour basée sur les réponses précédentes qui fonctionne lorsque vous compilez pour KitKat. Maintenant, la classe WebSettings est abstraite et la classe WebSettingsClassic a été supprimée.

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static String getUserAgent(final Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        return WebSettings.getDefaultUserAgent(context);
    }
    else {
        try {
            final Class<?> webSettingsClassicClass = Class.forName("Android.webkit.WebSettingsClassic");
            final Constructor<?> constructor = webSettingsClassicClass.getDeclaredConstructor(Context.class, Class.forName("Android.webkit.WebViewClassic"));
            constructor.setAccessible(true);
            final Method method = webSettingsClassicClass.getMethod("getUserAgentString");
            return (String) method.invoke(constructor.newInstance(context, null));
        }
        catch (final Exception e) {
            return new WebView(context).getSettings()
                    .getUserAgentString();
        }
    }
}
1
Monstieur

Grâce à la réponse d'Idolon, mon application a pu traiter cela en arrière-plan.

Mais d'une manière ou d'une autre sur HTC Inspire 4G d'AT & T qui exécute 2.3.3, cela va à la déclaration de capture et il ne peut plus être exécuté sur le thread d'arrière-plan. Ma solution est la suivante:

public static String getUserAgent(Context context) {
    try {
        Constructor<WebSettings> constructor = WebSettings.class.getDeclaredConstructor(Context.class, WebView.class);
        constructor.setAccessible(true);
        try {
            WebSettings settings = constructor.newInstance(context, null);
            return settings.getUserAgentString();
        } finally {
            constructor.setAccessible(false);
        }
    } catch (Exception e) {
        String ua;
        if(Thread.currentThread().getName().equalsIgnoreCase("main")){
            WebView m_webview = new WebView(context);
            ua = m_webview.getSettings().getUserAgentString();
        }else{
            mContext = context;
            ((Activity) mContext).runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    WebView webview = new WebView(mContext);
                    mUserAgent = webview.getSettings().getUserAgentString();
                }

            });
            return mUserAgent;
        }
        return ua;
    }
}

(supposons que vous ayez mContext et mUserAgent sur le terrain)

1
st_bk