Domanda

C'è un modo per recuperare user-agent del browser senza avere un WebView in attività?

So che è possibile ottenere tramite WebView:

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

Ma nel mio caso non ho / bisogno di un oggetto WebView e non voglio creare solo per il recupero stringa user-agent.

È stato utile?

Soluzione

Se non si sono quello che si può provare a prendere in questo modo

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

Modifica -

Il dottore per getUserAgentString() dice

Return stringa user-agent del WebView .

Quindi, non credo che si può ottenere se non si dichiara uno. Qualcuno mi corregga se sbaglio

Altri suggerimenti

C'è un modo molto più semplice se si è su Android 2.1 o superiore. Concesso questo non è esattamente lo stesso utente stringa agente che una WebView sarebbe tornato, ma potrebbe servire bene abbastanza per i vostri scopi.

Come un ulteriore vantaggio a tirare dalla vista web, è possibile utilizzare questo da qualsiasi thread (non solo il thread dell'interfaccia utente).

C'è una proprietà di sistema denominata http.agent, che può essere utilizzato per recuperare la stringa User-Agent.

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

programmazione get-User Agent String per più i dettagli.

Ho usato per usare href="https://stackoverflow.com/questions/3626071/retrieve-user-agent-programatically/3626156#3626156"> proposta da DeRagan. Ma si è scoperto che la creazione di una singola istanza WebView avvia un thread "WebViewCoreThread" che rimane sul fondo fino dell'applicazione viene terminata dal sistema. Forse non consuma troppe risorse, ma non mi piace comunque. Quindi io uso metodo leggermente diverso ora, che cerca di evitare la creazione 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);
  }
}

Si crea un'istanza WebSettings direttamente utilizzando il costruttore pacchetto-visibile e se questo non è disponibile per qualche motivo (ad esempio a causa di cambiamenti di API in futuro versioni di Android) -. Cade in silenzio torna a "WebView-like" soluzione

Aggiorna

Come indicato da @ Skywalker5446 , partendo da Android 4.2 / API 17 , v'è un metodo statico pubblico per ottenere il valore user agent di default. Ho aggiornato il mio codice per utilizzare quel metodo sulle piattaforme supportate.

Dal momento che Android 2.1 è necessario utilizzare System.getProperty ( "http.agent");

Inoltre non necessità di creare un WebView prima E, questo è il vantaggio, è possibile utilizzarlo all'interno di un non-uithread.

saluti Steve

Grazie alla risposta di Idolon mia app potrebbe elaborare questo sullo sfondo.

Ma in qualche modo su HTC Inspire 4G da AT & T che corre 2.3.3, va alla dichiarazione cattura e non può più essere eseguito sul thread in background. La mia soluzione per questo è il seguente:

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

(si supponga di avere mContext e mUserAgent in campo)

Questa è una soluzione aggiornata in base alle risposte precedenti che funziona quando si compila per KitKat. Ora la classe WebSettings è astratta e la classe WebSettingsClassic è stato rimosso.

@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();
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top