以编程方式检索User-Agent

时间:2010-09-02 10:09:35

标签: android webview android-webview user-agent

有没有办法在没有活动WebView的情况下检索浏览器的用户代理?

我知道可以通过WebView获取它:

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

但在我的情况下,我没有/需要一个webview对象,我不想仅仅为了检索用户代理字符串而创建它。

6 个答案:

答案 0 :(得分:53)

如果你没有拥有,你可以尝试这样做

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

编辑 -

getUserAgentString()的文档说

返回WebView的用户代理字符串

所以除非你申报一个,否则我认为你不能得到它。如果我错了,有人会纠正我

答案 1 :(得分:51)

如果你使用Android 2.1或更高版本,有一种更简单的方法。当然,这与Webview将返回的用户代理字符串不完全相同,但可能对您有用。

作为从Web视图中提取的另一个优势,您可以从任何线程(而不仅仅是UI线程)中使用它。

有一个名为http.agent的系统属性,可用于检索用户代理字符串。

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

有关详细信息,请参阅Programmatically get User-Agent String

答案 2 :(得分:35)

我曾经使用过DeRagan提出的solution。但事实证明,创建单个WebView实例会启动一个“WebViewCoreThread”线程,该线程将保留在后台,直到系统终止应用程序。也许它不会消耗太多资源,但我还是不喜欢它。所以我现在使用稍微不同的方法,试图避免创建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);
  }
}

它直接使用package-visible构造函数创建WebSettings实例,如果由于某些原因(例如由于未来Android版本中的API更改)而无法使用 - 则默默地回退到“类似WebView”的解决方案。 / p>

<强>更新

正如@Skywalker5446指出的那样,从Android 4.2 / API 17开始,有一个公共静态方法来获取默认的用户代理值。我已经更新了我的代码,以便在支持的平台上使用该方法。

答案 3 :(得分:10)

从Android 2.1开始,你应该使用 System.getProperty(“http.agent”);

你也不需要先创建一个WebView,这就是优势, 你可以在非uithread中使用它。

问候史蒂夫

答案 4 :(得分:1)

感谢Idolon的回答,我的应用可以在后台处理。

但不知怎的,在运行2.3.3的AT&amp; T的HTC Inspire 4G上,它转到了catch语句,它不能再在后台线程上运行了。 我的解决方案如下:

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

(假设你在字段中有mContext和mUserAgent)

答案 5 :(得分:1)

这是基于以前的答案的更新解决方案,当您为KitKat编译时,该解决方案有效。现在WebSettings类是抽象的,WebSettingsClassic类已被删除。

@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();
        }
    }
}