All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.github.apkcloud.devicedetector.ClientHints Maven / Gradle / Ivy
Go to download
通用设备检测库将解析任何UserAgent并检测浏览器、操作系统、使用的设备(桌面、平板、移动、电视、车载、游戏机等等)、品牌和型号。
package io.github.apkcloud.devicedetector;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ClientHints {
/**
* 代表 `Sec-CH-UA-Arch` 头字段:底层架构的指令集
*/
protected String architecture = "";
/**
* 代表 `Sec-CH-UA-Bitness` 头字段:底层架构的位数
*/
protected String bitness = "";
/**
* 代表 `Sec-CH-UA-Mobile` 头字段:UserAgent 是否应该接收特定的 "mobile(移动)" UX(用户体验)
*/
protected boolean mobile = false;
/**
* 代表 `Sec-CH-UA-Model` 头字段:UserAgent 的底层设备型号
*/
protected String model = "";
/**
* 代表 `Sec-CH-UA-Platform` 头字段:平台的品牌
*/
protected String platform = "";
/**
* 代表 `Sec-CH-UA-Platform-Version` 头字段:平台的主要版本
*/
protected String platformVersion = "";
/**
* 代表 `Sec-CH-UA-Full-Version` 头字段:平台的主要版本
*/
protected String uaFullVersion = "";
/**
* 代表 `Sec-CH-UA-Full-Version-List` 头字段:品牌列表中每个品牌的完整版本
*/
protected List> fullVersionList = new ArrayList<>();
/**
* 代表 `x-requested-with` 头字段:Android app id
*/
protected String app = "";
/**
* Constructor
*
* @param model `Sec-CH-UA-Model` 头字段
* @param platform `Sec-CH-UA-Platform` 头字段
* @param platformVersion `Sec-CH-UA-Platform-Version` 头字段
* @param uaFullVersion `Sec-CH-UA-Full-Version` 头字段
* @param fullVersionList `Sec-CH-UA-Full-Version-List` 头字段
* @param mobile `Sec-CH-UA-Mobile` 头字段
* @param architecture `Sec-CH-UA-Arch` 头字段
* @param bitness `Sec-CH-UA-Bitness`
* @param app `HTTP_X-REQUESTED-WITH`
*/
public ClientHints(String model, String platform, String platformVersion, String uaFullVersion, List> fullVersionList, boolean mobile, String architecture, String bitness, String app) // phpcs:ignore Generic.Files.LineLength
{
this.model = model;
this.platform = platform;
this.platformVersion = platformVersion;
this.uaFullVersion = uaFullVersion;
this.fullVersionList = fullVersionList;
this.mobile = mobile;
this.architecture = architecture;
this.bitness = bitness;
this.app = app;
}
/**
* 直接允许访问受保护的属性的魔术方法
*
* @param variable
* @return mixed
* @throws \Exception
*/
/*public function __get(string variable) {
if (\property_exists(this, variable)){
return this.variable;
}
throw new \Exception('Invalid ClientHint property requested.');
}*/
/**
* 返回ClientHints是否存在
*
* @return boolean
*/
public boolean isMobile() {
return this.mobile;
}
/**
* 返回架构
*
* @return String
*/
public String getArchitecture(){
return this.architecture;
}
/**
* 返回位数
*
* @return String
*/
public String getBitness(){
return this.bitness;
}
/**
* 返回设备型号
*
* @return String
*/
public String getModel(){
return this.model;
}
/**
* 返回操作系统
*
* @return String
*/
public String getOperatingSystem(){
return this.platform;
}
/**
* 返回操作系统版本
*
* @return String
*/
public String getOperatingSystemVersion(){
return this.platformVersion;
}
/**
* 返回浏览器名称
*
* @return {@code Map | null}
*/
public Map getBrandList() {
Map brandMap = null;
if (this.fullVersionList != null && this.fullVersionList.size() > 0) {
List brands = fullVersionList.stream()
.map(map -> map.get("brand"))
.collect(Collectors.toList());
List versions = fullVersionList.stream()
.map(map -> map.get("version"))
.collect(Collectors.toList());
/*if (brands.size() == versions.size()) {
for (int i = 0; i < brands.size(); i++) {
brandMap.put(brands.get(i), versions.get(i));
}
return brandMap;
}*/
brandMap = IntStream.range(0, Math.min(brands.size(), versions.size()))
.boxed()
.collect(Collectors.toMap(brands::get, versions::get));
}
return brandMap;
}
/**
* 返回浏览器版本
*
* @return String
*/
public String getBrandVersion() {
if (uaFullVersion != null && !uaFullVersion.isEmpty()) {
return uaFullVersion;
}
return "";
}
/**
* 返回 Android 应用程序 ID
*
* @return String
*/
public String getApp() {
return app;
}
/**
* 工厂方法,使用包含所有可用(客户端提示)标头的数组轻松实例化此类
*
* @param headers 包含所有标头信息的数组
*
* @return ClientHints
*/
public static ClientHints factory(Map headers) {
String model = "";
String platform = "";
String platformVersion = "";
String uaFullVersion = "";
String architecture = "";
String bitness = "";
String app = "";
boolean mobile = false;
List> fullVersionList = new ArrayList<>();
for (Map.Entry entry : headers.entrySet()) {
String name = entry.getKey();
String value = entry.getValue();
String regex;
List> list;
switch (name.toLowerCase().replace("_", "-")) {
case "sec-ch-ua-arch": // CPU底层架构,例如ARM或x86等。Sec-CH-UA-Arch: "x86"
architecture = value.replace("\"","").trim();
break;
case "sec-ch-ua-bitness": //CPU底层架构的位数,通常为64位或32位。Sec-CH-UA-Bitness: "64"
bitness = value.replace("\"","").trim();
break;
case "sec-ch-ua-mobile": // 设备是否为移动设备 ?1 (true) ?0 (false)
mobile = value.contains("1");
break;
case "sec-ch-ua-model": // 设备型号。Sec-CH-UA-Model: "Pixel 3 XL"
model = value.replace("\"","").trim();
break;
case "sec-ch-ua-full-version": // 浏览器的完整版本号。Sec-CH-UA-Full-Version: "96.0.4664.110"
uaFullVersion = value.replace("\"","").trim();
break;
case "sec-ch-ua-platform": // 所运行的平台或操作系统。Sec-CH-UA-Platform: "macOS"
platform = value.replace("\"","").trim();
break;
case "sec-ch-ua-platform-version": // 操作系统的版本。Sec-CH-UA-Platform-Version: "10.0.0"
platformVersion = value.replace("\"","").trim();
break;
case "sec-ch-ua": // 与浏览器相关的品牌和重要版本。Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96"
if (!fullVersionList.isEmpty()) {
break;
}
// 仅当没有其他请求头时才使用此选项设置列表
list = parseFullVersionList(value);
if (!list.isEmpty()) {
fullVersionList = list;
}
break;
case "sec-ch-ua-full-version-list": // 与浏览器相关的品牌和完整版本。Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96"
list = parseFullVersionList(value);
if (!list.isEmpty()) {
fullVersionList = list;
}
break;
case "x-requested-with":
if (!"xmlhttprequest".equalsIgnoreCase(value)) {
app = value;
}
break;
}
}
return new ClientHints(model, platform, platformVersion, uaFullVersion, fullVersionList, mobile, architecture, bitness, app);
}
private static List> parseFullVersionList(String value) {
String regex = "^\"([^\"]+)\"; ?v=\"([^\"]+)\"(?:, )?";
List> list = new ArrayList<>();
Matcher matcher = Pattern.compile(regex).matcher(value);
while (matcher.find()) {
Matcher finalMatcher = matcher;
list.add(new HashMap<>() {
{
put("brand", finalMatcher.group(1).trim());
put("version", finalMatcher.group(2).trim());
}
});
value = value.substring(matcher.group(0).length());
matcher = Pattern.compile(regex).matcher(value);
}
return list;
}
}