web-dev-qa-db-ja.com

プログラムでユーザーエージェントを取得する

WebViewを実行せずにブラウザのユーザーエージェントを取得する方法はありますか?

WebViewから取得できることを知っています。

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

しかし、私の場合、私はwebviewオブジェクトを持っていません/必要としません。ユーザーエージェント文字列を取得するためだけに作成したくありません。

36
Laimoncijus

もしあなたがhaveをしていなければ、このようにしてみることができます

_String ua=new WebView(this).getSettings().getUserAgentString();
_

編集-

getUserAgentString()のドキュメントには、

WebViewのユーザーエージェント文字列を返す

だから私はあなたがそれを宣言しない限りそれを手に入れることができるとは思いません。私が間違っている場合、誰かが私を修正します

54
DeRagan

Android 2.1以上を使用している場合、はるかに簡単な方法があります。これは、WebViewが返すのとまったく同じユーザーエージェント文字列ではありませんが、目的に十分役立つ可能性があります。 。

Webビューからプルすることの追加の利点として、これを(UIスレッドだけでなく)任意のスレッドから使​​用できます。

User.Agent文字列を取得するために使用できるhttp.agentというシステムプロパティがあります。

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

詳細は Programmatically get User-Agent String を参照してください。

56
Craig Russell

以前は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);
  }
}

パッケージから見えるコンストラクタを使用してWebSettingsインスタンスを直接作成し、それが何らかの理由で(たとえば、将来のAPIの変更のために)利用できない場合Androidバージョン)-静かに「 WebViewのような」ソリューション。

[〜#〜]更新[〜#〜]

@ Skywalker5446 で指摘されているように、Android 4.2/API 17から始まる)、デフォルトのユーザーエージェント値を取得するパブリック静的メソッドがあります。コードを次のように更新しましたサポートされているプラ​​ットフォームでそのメソッドを使用します。

35
Idolon

Android 2.1なので、System.getProperty( "http.agent");)を使用する必要があります

また、最初にWebViewを作成する必要もありません。これは利点です。非UIスレッド内で使用できます。

あいさつ

10
JacksOnF1re

これは、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();
        }
    }
}
1
Monstieur

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があるとします)

1
st_bk