以编程方式检索用户代理

有没有办法检索浏览器的用户代理没有一个WebView的活动?

我知道有可能通过WebView获取它:

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

但在我的情况下,我没有/需要一个WebView对象,我不想创build它只是为了检索用户代理string。

Solutions Collecting From Web of "以编程方式检索用户代理"

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

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

编辑-

getUserAgentString()的文档说

返回WebView的用户代理string

所以我不认为你可以得到它,除非你声明。 有人纠正我,如果我错了

如果您使用的是Android 2.1或更高版本,则有更简单的方法。 当然,这不是webview将返回的完全相同的用户代理string,但可能为您的目的足够好。

作为从Web视图拉出的额外优势,您可以从任何线程(而不仅仅是UI线程)使用此function。

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

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

请参阅编程获取用户代理string了解更多详细信息。

我曾经使用DeRagan提出的解决scheme 。 但事实certificate,创build一个单独的WebView实例将启动一个线程“WebViewCoreThread”,直到应用程序被系统终止后才停留在后台。 也许它不会消耗太多的资源,但我不喜欢它。 所以我现在使用稍微不同的方法,它试图避免WebViewCoreThread创build:

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

它直接使用包可见构造函数创buildWebSettings实例,如果由于某种原因(例如,由于未来Android版本的API更改)而无法使用该实例,则会默默地回退到“类似WebView”的解决scheme。

UPDATE

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

由于Android 2.1,你应该使用System.getProperty(“http.agent”);

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

问候史蒂夫

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

但不知何故,从运行2.3.3的AT&T的HTC Inspire 4G,它进入catch语句,它可以不再运行在后台线程。 我的解决scheme如下:

 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)

这是一个更新的解决scheme,基于以前的答案,适用于您为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(); } } }