42

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

我知道可以通过以下方式获得它WebView

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

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

4

6 回答 6

62

如果你没有你可以试试这样

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

编辑-

文档getUserAgentString()

返回 WebView 的用户代理字符串

因此,除非您声明一个,否则我认为您无法获得它。如果我错了,有人纠正我

于 2010-09-02T10:21:48.477 回答
60

如果您使用的是 Android 2.1 或更高版本,则有一种更简单的方法。当然,这与 webview 将返回的用户代理字符串并不完全相同,但可能会为您提供足够好的服务来满足您的目的。

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

有一个名为 http.agent 的系统属性,可用于检索 User-Agent 字符串。

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

有关详细信息,请参阅以编程方式获取用户代理字符串

于 2012-09-07T08:13:49.970 回答
38

我曾经使用DeRagan 提出的解决方案。但事实证明,创建单个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);
  }
}

它直接使用包可见的构造函数创建WebSettings实例,如果由于某种原因(例如由于未来 Android 版本中的 API 更改)不可用 - 默默地回退到“类似 WebView”的解决方案。

更新

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

于 2011-03-10T14:56:08.830 回答
10

从 Android 2.1 开始,您应该使用System.getProperty("http.agent");

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

问候史蒂夫

于 2013-11-05T18:09:42.433 回答
2

这是基于先前答案的更新解决方案,当您为 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();
        }
    }
}
于 2014-06-02T08:21:56.517 回答
1

感谢 Idolon 的回答,我的应用程序可以在后台处理这个问题。

但不知何故,在运行 2.3.3 的 AT&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)

于 2011-09-02T21:50:41.753 回答