系列文章目录
总篇:数据抓取:抓取手机设备各种数据
分篇(一):【数据抓取(一)】手机通讯录数据获取
分篇(二):数据抓取(二)&定位方案:地址信息的获取
分篇(三):数据抓取(三):免权限获取所有安装的应用程序信息(系统和非系统)
前言
在应用中,我们有时候需要获取手机IP需要显示的语言环境,然后调整手机的语言,甚至有时候要获取移动数据的运营商和网络类型来判断是否提供服务等等,本篇文章就来带大家学习如何一步步抓取这些通用数据,当然最后还是有工具类提供给大家。
效果图:
一、通用数据bean类
主要属性如下:
字段名 | 详情 |
---|---|
and_id | 对于应用程序签名密钥、用户和设备的每个组合都是唯一的,ANDROID_ID的取值范围由签名密钥和用户决定,在有多个用户的设备上,每个用户显示为一个完全独立的设备,因此ANDROID_ID值对于每个用户是唯一的 |
currentSystemTime | 设备当前时间 |
elapsedRealtime | 开机时间到现在的毫秒数(包括睡眠时间) |
gaid | google advertising id(google 广告 id) |
imei | 设备号 |
is_usb_debug | 是否开启debug调试 |
is_using_proxy_port | 是否使用代理 |
is_using_vpn | 是否使用vpn |
language | 语言 |
locale_display_language | 此用户显示的语言环境语言的名称 |
locale_iso_3_country | 此地区的国家/地区的缩写 |
locale_country | 此地区的国家 |
locale_iso_3_language | 语言环境的三字母缩写 |
mac | mac 地址 |
network_operator_name | 网络运营商名称 |
network_type | 网络类型 2G、3G、4G、5G、wifi、other、none |
phone_number | 手机号 |
phone_type | 指示设备电话类型的常量。 这表示用于传输语音呼叫的无线电的类型 |
time_zone_id | 时区的 ID |
uptimeMillis | 从开机到现在的毫秒数(不包括睡眠时间) |
uuid | 唯一标识 |
二、获取数据
1.添加权限——选择添加即可
<!-- 获取网络运营商信息-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
2.获取数据
- 获取安卓ANDROID_ID,通过Settings的系统设置获取相关数据,且因为在有多个用户的设备上,每个用户显示为一个完全独立的设备,因此ANDROID_ID值对于每个用户是唯一的。 利用这个性质,对某些用户做VIP处理或是其他特意风味处理:
@SuppressLint("HardwareIds")
private static String getAndroidID(Context context) {
String id = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID
);
if ("9774d56d682e549c".equals(id)) return "";
return id == null ? "" : id;
}
- 获取设备当前时间,开机到现在的毫秒数(包括睡眠时间),以及不包括睡眠时间的开机时长和线程存在时间(主线程:应用程序启动时间)。这块只需调用SystemClock的API就可以简单获取
// 设备当前时间
String currentSystemTime = String.valueOf(System.currentTimeMillis());
// 开机时间到现在的毫秒数(包括睡眠时间)
String elapsedRealtime = String.valueOf(SystemClock.elapsedRealtime());
// 从开机到现在的毫秒数(不包括睡眠时间)
String uptimeMillis = String.valueOf(SystemClock.uptimeMillis());
// 当前线程中运行的毫秒数,在主线程可以说是当前应用程序运行时间
String threadTimeMillis = String.valueOf(SystemClock.currentThreadTimeMillis());
- 是否使用USB调试,以及(特殊)上网状态(审核过不了,奇奇怪怪的),其中is_usb_debug 根据Settings的系统设置获取相关数据,is_using_proxy_port根据 SDK版本有不同获取方法:大于等于安卓4,就使用System自带的getProperty获取;小于安卓4调用getHost()方法获取,最后is_using_vpn
/**
* 是否开启debug调试
* @param context
* @return
*/
private static int isAppDebug(Context context) {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ADB_ENABLED, 0) > 0;
}
/**
* 是否开启代理
* @param context
* @return
*/
private static int getIsWifiProxy(Context context) {
final boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
String proxyAddress;
int proxyPort;
if (IS_ICS_OR_LATER) {
proxyAddress = System.getProperty("http.proxyHost");
String portStr = System.getProperty("http.proxyPort");
proxyPort = Integer.parseInt((portStr != null ? portStr : "-1"));
} else {
proxyAddress = android.net.Proxy.getHost(context);
proxyPort = android.net.Proxy.getPort(context);
}
return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1);
}
/**
* 判断设备是否是开启VPN
*/
private static boolean isVpnConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
Network[] networks = cm.getAllNetworks();
for (Network network : networks) {
NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);
if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
return true;
}
}
return false;
}
- 手机当前系统语言language,以当前用户语言显示的语言名称locale_display_language,还有当前地区的缩写locale_iso_3_country,最后还有以用户语言显示的当前区域国家名称 locale_country,语言环境的三字母缩写等信息locale_iso_3_language这些信息只需要通过
Locale
这个类提供的API就可以简单获取。
String language = Locale.getDefault().getLanguage(); // 语言
String locale_display_language = Locale.getDefault().getDisplayLanguage(); // 此用户显示的语言环境语⾔的名称
String locale_iso_3_country = Locale.getDefault().getCountry(); // 此地区的国家/地区的缩写
String displayCountry = Locale.getDefault().getDisplayCountry();// 返回适合显示给用户的区域设置国家的名称。
String locale_iso_3_language = Locale.getDefault().getISO3Language(); // 语言环境的三字母缩写
- 物理地址mac,根据安卓版本分为不同获取方法。1.安卓8以下:依赖于wifi去获取mac地址(权限:ACCESS_WIFI_STATE),2.安卓8以上:通过读取文件 /sys/class/net/wlan0/address获取
/**
* 获取mac地址
* 当安卓版本小于安卓6时,可以通过普通权限获取
* 大于安卓6后,需要动态权限ACCESS_FINE_LOCATION
*/
private static String getMAC(Context context) {
String macAddress = "";
int sdkInt = Build.VERSION.SDK_INT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
try {
// wifi已经连接,这里可以判断一下
InputStream inputStream = new FileInputStream("/sys/class/net/wlan0/address");
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(reader);
macAddress = br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
}else {
macAddress = wifiInfo.getMacAddress();
}
} else {
try {
// wifi已经连接,这里可以判断一下
InputStream inputStream = new FileInputStream("/sys/class/net/wlan0/address");
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(reader);
macAddress = br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
}
return macAddress;
}
- 网络运营商名称network_operator_name,以及当前的网络类型network_type。通过设备电话管理器TelephonyManager来获取SIM卡提供商的MCC+MNC,并通过解析数值获取对应的网络运营商名称(MCC 和 MNC与China 运营商对照关系),而网络类型我知道的有两种获取方法,所需要的权限不一样,一者为需要相应的权限
ACCESS_NETWORK_STATE
才能获取对应的数值,该信息可以通过ConnectivityManager
获取对应的信息;一者需要动态权限READ_PHONE_STATE
,然后根据设备电话管理器TelephonyManager的api——getDataNetworkType()获取指示设备上当前用于数据传输的无线电技术(网络类型),其中目前方法一较为完善,方法二局限较大,所以我将方法二作为后备方案使用。
/**
* 需要权限ACCESS_NETWORK_STATE
*/
private static String getNetworkType(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {
Log.d("数据抓取:GeneralDataUtil", "通用信息:并未申请相关权限——ACCESS_NETWORK_STATE,采取方法二");
// 方法二
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int networkType = 0;
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
networkType = 0;
}else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// 返回一个常量,指示设备上当前用于数据传输的无线电技术(网络类型)
networkType = tm.getDataNetworkType();
}
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GSM:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return "NETWORK_2G";
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return "NETWORK_3G";
case TelephonyManager.NETWORK_TYPE_IWLAN:
case TelephonyManager.NETWORK_TYPE_LTE:
return "NETWORK_4G";
case TelephonyManager.NETWORK_TYPE_NR:
return "NETWORK_5G";
default:
return "NETWORK_UNKNOWN";
}
}
return "NETWORK_NO";
}
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) {
return null;
}
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
return "NETWORK_WIFI";
} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
switch (info.getSubtype()) {
case TelephonyManager.NETWORK_TYPE_GSM:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return "NETWORK_2G";
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return "NETWORK_3G";
case TelephonyManager.NETWORK_TYPE_IWLAN:
case TelephonyManager.NETWORK_TYPE_LTE:
return "NETWORK_4G";
case TelephonyManager.NETWORK_TYPE_NR:
return "NETWORK_5G";
default:
String subtypeName = info.getSubtypeName();
if (subtypeName.equalsIgnoreCase("TD-SCDMA")
|| subtypeName.equalsIgnoreCase("WCDMA")
|| subtypeName.equalsIgnoreCase("CDMA2000")) {
return "NETWORK_3G";
} else {
return "NETWORK_UNKNOWN";
}
}
} else {
return "NETWORK_UNKNOWN";
}
}
return "NETWORK_NO";
}
/**
* 获取运营商名称
*/
private static String getNetworkName(Context context) {
String networkName = "unknown";
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String operator = tm.getSimOperator();
if (operator.equals("")) {
return networkName;
}
if ("46001".equals(operator) || "46006".equals(operator) || "46009".equals(operator)) {
networkName = "中国联通";
} else if ("46000".equals(operator) || "46002".equals(operator) || "46004".equals(operator) || "46007".equals(operator)) {
networkName = "中国移动";
} else if ("46003".equals(operator) || "46005".equals(operator) || "46011".equals(operator)) {
networkName = "中国电信";
} else {
networkName = "unknown";
}
return networkName;
}
- 获取当前手机的phone_number,指示设备电话类型的常量phone_type,都可以通过TelephonyManager管理器来获取对应数值。(待完善)
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String phone_number = "";
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED) {
phone_number = "";
} else {
phone_number = telephonyManager.getLine1Number();//返回设备的电话号码
}
int phoneType = telephonyManager.getPhoneType(); // 指示设备电话类型的常量。 这表示用于传输语音呼叫的无线电的类型
- 最后是时区time_zone_id,以及当前线程启动后时间,常可以用来计算当前app使用时间,以及uuid唯一标识。
TimeZone timeZone = TimeZone.getDefault();
String time_zone_id = timeZone.getID(); // 时区的 ID
String uptimeMillis = String.valueOf(SystemClock.uptimeMillis()); // 从开机到现在的毫秒数(不包括睡眠时间)
String threadTimeMillis = String.valueOf(SystemClock.currentThreadTimeMillis()); // 当前线程中运行的毫秒数,在主线程可以说是当前应用程序运行时间
String uuid = UUID.randomUUID().toString().toUpperCase(); // 唯一标识
三、工具类
此处附上工具类,方便大家使用
public class GeneralDataUtil {
/**
* 获取设备基本信息
*/
public static GeneralDataBean getGeneralData(Context context) {
String and_id = getAndroidID(context); // android_id
String currentSystemTime = String.valueOf(System.currentTimeMillis()); // 设备当前时间
String elapsedRealtime = String.valueOf(SystemClock.elapsedRealtime()); // 开机时间到现在的毫秒数(包括睡眠时间)
String gaid = getGoogleId(context);
String imei = getIMEI(context); // 设备号
boolean is_usb_debug = isAppDebug(context) == 1; // 是否开启debug调试
boolean is_using_proxy_port = getIsWifiProxy(context) == 1; // 是否使用代理
boolean is_using_vpn = isVpnConnected(context); // 是否使用vpn
String language = Locale.getDefault().getLanguage(); // 语言
String locale_display_language = Locale.getDefault().getDisplayLanguage(); // 此用户显示的语言环境语⾔的名称
String locale_iso_3_country = Locale.getDefault().getCountry(); // 此地区的国家/地区的缩写
String displayCountry = Locale.getDefault().getDisplayCountry();// 返回适合显示给用户的区域设置国家的名称。
String locale_iso_3_language = Locale.getDefault().getISO3Language(); // 语言环境的三字母缩写
String mac = getMAC(context); // mac
String network_operator_name = getNetworkName(context); // 网络运营商名称
String network_type = getNetworkType(context); // 网络类型 2G、3G、4G、5G、wifi、other、none
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String phone_number = "";
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED) {
phone_number = "";
} else {
phone_number = telephonyManager.getLine1Number();//返回设备的电话号码
}
int phoneType = telephonyManager.getPhoneType(); // 指示设备电话类型的常量。 这表示用于传输语音呼叫的无线电的类型
TimeZone timeZone = TimeZone.getDefault();
String time_zone_id = timeZone.getID(); // 时区的 ID
String uptimeMillis = String.valueOf(SystemClock.uptimeMillis()); // 从开机到现在的毫秒数(不包括睡眠时间)
String threadTimeMillis = String.valueOf(SystemClock.currentThreadTimeMillis()); // 当前线程中运行的毫秒数,在主线程可以说是当前应用程序运行时间
String uuid = UUID.randomUUID().toString().toUpperCase(); // 唯一标识
// 传感器信息
return new GeneralDataBean(and_id, currentSystemTime, elapsedRealtime,
gaid, imei, is_usb_debug, is_using_proxy_port, is_using_vpn, language, locale_display_language, locale_iso_3_country, displayCountry,
locale_iso_3_language, mac, network_operator_name, network_type,
phone_number, phoneType, time_zone_id, uptimeMillis, threadTimeMillis, uuid);
}
@SuppressLint("HardwareIds")
private static String getAndroidID(Context context) {
String id = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID
);
if ("9774d56d682e549c".equals(id)) return "";
return id == null ? "" : id;
}
/**
* 获取设备的唯一标识, 需要 “android.permission.READ_Phone_STATE”权限
* 因为权限限制,超过29本来需要另外的权限,甲方要求不加权限,故在此直接获取设备id
*/
private static String getIMEI(Context context) {
String reStr = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
reStr = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
// Android 10及以上版本需要动态请求权限
} else {
// Android 10以下版本可以直接获取IMEI
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
reStr = telephonyManager.getImei();
}
}
return reStr;
}
/**
* 是否开启debug调试
* @param context
* @return
*/
private static int isAppDebug(Context context) {
boolean b = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.ADB_ENABLED, 0) > 0;
if (b) {
return 1;
} else {
return 0;
}
}
/**
* 是否开启代理
* @param context
* @return
*/
private static int getIsWifiProxy(Context context) {
final boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
String proxyAddress;
int proxyPort;
if (IS_ICS_OR_LATER) {
proxyAddress = System.getProperty("http.proxyHost");
String portStr = System.getProperty("http.proxyPort");
proxyPort = Integer.parseInt((portStr != null ? portStr : "-1"));
} else {
proxyAddress = android.net.Proxy.getHost(context);
proxyPort = android.net.Proxy.getPort(context);
}
boolean b = (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1);
if (b) {
return 1;
} else {
return 0;
}
}
/**
* 判断设备是否是开启VPN
*/
private static boolean isVpnConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
Network[] networks = cm.getAllNetworks();
for (Network network : networks) {
NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);
if (capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
return true;
}
}
return false;
}
/**
* 获取google广告id
*/
private static String getGoogleId(Context context) {
AdvertisingIdClient.Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
} catch (Exception e) {
e.printStackTrace();
}
String gaid = null; // 广告id
if (adInfo != null) {
gaid = adInfo.getId();
}
return gaid;
}
/**
* 需要权限ACCESS_NETWORK_STATE
*/
private static String getNetworkType(Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {
Log.d("数据抓取:GeneralDataUtil", "通用信息:并未申请相关权限——ACCESS_NETWORK_STATE,采取方法二");
// 方法二
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int networkType = 0;
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
networkType = 0;
}else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// 返回一个常量,指示设备上当前用于数据传输的无线电技术(网络类型)
networkType = tm.getDataNetworkType();
}
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GSM:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return "NETWORK_2G";
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return "NETWORK_3G";
case TelephonyManager.NETWORK_TYPE_IWLAN:
case TelephonyManager.NETWORK_TYPE_LTE:
return "NETWORK_4G";
case TelephonyManager.NETWORK_TYPE_NR:
return "NETWORK_5G";
default:
return "NETWORK_UNKNOWN";
}
}
return "NETWORK_NO";
}
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) {
return null;
}
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
return "NETWORK_WIFI";
} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
switch (info.getSubtype()) {
case TelephonyManager.NETWORK_TYPE_GSM:
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return "NETWORK_2G";
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return "NETWORK_3G";
case TelephonyManager.NETWORK_TYPE_IWLAN:
case TelephonyManager.NETWORK_TYPE_LTE:
return "NETWORK_4G";
case TelephonyManager.NETWORK_TYPE_NR:
return "NETWORK_5G";
default:
String subtypeName = info.getSubtypeName();
if (subtypeName.equalsIgnoreCase("TD-SCDMA")
|| subtypeName.equalsIgnoreCase("WCDMA")
|| subtypeName.equalsIgnoreCase("CDMA2000")) {
return "NETWORK_3G";
} else {
return "NETWORK_UNKNOWN";
}
}
} else {
return "NETWORK_UNKNOWN";
}
}
return "NETWORK_NO";
}
/**
* 获取运营商名称
*/
private static String getNetworkName(Context context) {
String networkName = "unknown";
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String operator = tm.getSimOperator();
if (operator.equals("")) {
return networkName;
}
if ("46001".equals(operator) || "46006".equals(operator) || "46009".equals(operator)) {
networkName = "中国联通";
} else if ("46000".equals(operator) || "46002".equals(operator) || "46004".equals(operator) || "46007".equals(operator)) {
networkName = "中国移动";
} else if ("46003".equals(operator) || "46005".equals(operator) || "46011".equals(operator)) {
networkName = "中国电信";
} else {
networkName = "unknown";
}
return networkName;
}
/**
* 获取mac地址
* 当安卓版本小于安卓6时,可以通过普通权限获取
* 大于安卓6后,需要动态权限ACCESS_FINE_LOCATION
*/
private static String getMAC(Context context) {
String macAddress = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
try {
// wifi已经连接,这里可以判断一下
InputStream inputStream = new FileInputStream("/sys/class/net/wlan0/address");
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(reader);
macAddress = br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
}else {
macAddress = wifiInfo.getMacAddress();
}
} else {
try {
// wifi已经连接,这里可以判断一下
InputStream inputStream = new FileInputStream("/sys/class/net/wlan0/address");
InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(reader);
macAddress = br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
}
return macAddress;
}
}
最后附上相关源码以及我手搓的开源库:
数据抓取:https://github.com/Android5730/DataCapture
如果有帮助到各位,可以给个star,给我一点信心去完善这个开源库
总结
其中有些数据因为安卓版本获取不全,这也是我想要完善的地方,后续会持续优化,如果大家有遇到问题也欢迎在github的issue或者评论区里提出。