Recuperar o agente de usuário programaticamente
-
26-09-2019 - |
Pergunta
Existe uma maneira de recuperar o agente de usuário do navegador sem ter um WebView
em atividade?
Eu sei que é possível obtê -lo via WebView
:
WebView view = (WebView) findViewById(R.id.someview);
String ua = view.getSettings().getUserAgentString() ;
Mas, no meu caso, não tenho/preciso de um objeto WebView e não quero criá-lo apenas para recuperar a sequência agente do usuário.
Solução
Se você não o fizer tenho um que você pode tentar levá -lo assim
String ua=new WebView(this).getSettings().getUserAgentString();
Editar-
O documento para getUserAgentString()
diz
Retorne a string de agente de usuário do WebView.
Então, acho que você não pode obtê -lo, a menos que declare um. Alguém me corrija se eu estiver errado
Outras dicas
Existe uma maneira muito mais simples se você estiver no Android 2.1 ou acima. É verdade que esta não é exatamente a mesma sequência de agentes de usuário que uma WebView retornaria, mas pode atendê -lo o suficiente para seus propósitos.
Como uma vantagem adicional para extrair da Web View, você pode usá -lo em qualquer encadeamento (não apenas o thread da interface do usuário).
Existe uma propriedade do sistema chamada http.agent, que pode ser usada para recuperar a sequência agente do usuário.
String userAgent = System.getProperty("http.agent");
Ver Obtenha programaticamente string de agente de usuário para mais detalhes.
Eu costumava usar solução proposto por Deragan. Mas aconteceu que criar um único WebView
A instância inicia um thread "WebViewCorethRead", que permanece em segundo plano até que o aplicativo seja encerrado pelo sistema. Talvez não consuma muitos recursos, mas eu não gosto de qualquer maneira. Por isso, uso o método ligeiramente diferente agora, o que tenta evitar a criação do 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);
}
}
Ele cria WebSettings
Instância diretamente usando o construtor visível do pacote e, se isso não estiver disponível por algum motivo (por exemplo, devido a alterações da API nas futuras versões do Android)-volta silenciosamente à solução "tipo Webview".
ATUALIZAR
Como apontado por @Skywalker5446, a partir do Android 4.2/API 17, existe um método estático público para obter o valor do agente do usuário padrão. Atualizei meu código para usar esse método nas plataformas suportadas.
Desde o Android 2.1, você deve usar System.getProperty ("http.agent");
Você também não precisa criar um WebView primeiro e, essa é a vantagem, pode usá-la dentro de um não-Uithread.
Saudações Steve
Graças à resposta de Idolon, meu aplicativo pode processar isso em segundo plano.
Mas, de alguma forma, no HTC Inspire 4G da AT&T que executa 2.3.3, ele vai para a declaração de captura e não pode ser mais executado no encadeamento em segundo plano. Minha solução para isso é a seguinte:
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;
}
}
(Suponha que você tenha McOntext e Muderagent no campo)
Esta é uma solução atualizada com base em respostas anteriores que funcionam quando você compila para o kitkat. Agora o WebSettings
classe é abstrata e o WebSettingsClassic
A classe foi removida.
@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();
}
}
}