743 lines
26 KiB
Kotlin
743 lines
26 KiB
Kotlin
package com.xyzshell.mydev.utils
|
||
|
||
import android.Manifest
|
||
import android.annotation.SuppressLint
|
||
import android.content.Context
|
||
import android.content.Intent
|
||
import android.content.IntentFilter
|
||
import android.content.pm.PackageManager
|
||
import android.content.pm.Signature
|
||
import android.hardware.Sensor
|
||
import android.hardware.SensorManager
|
||
import android.media.AudioManager
|
||
import android.media.MediaCodecInfo
|
||
import android.media.MediaCodecList
|
||
import android.net.ConnectivityManager
|
||
import android.os.Build
|
||
import android.os.SystemClock
|
||
import android.os.ext.SdkExtensions
|
||
import android.provider.Settings
|
||
import android.telephony.TelephonyManager
|
||
import android.webkit.WebSettings
|
||
import androidx.core.app.ActivityCompat
|
||
import com.xyzshell.mydev.InfoItem
|
||
import org.json.JSONObject
|
||
import java.io.ByteArrayInputStream
|
||
import java.io.File
|
||
import java.io.FileInputStream
|
||
import java.io.RandomAccessFile
|
||
import java.security.MessageDigest
|
||
import java.security.cert.Certificate
|
||
import java.security.cert.CertificateFactory
|
||
import java.security.cert.X509Certificate
|
||
import java.util.Locale
|
||
import java.util.TimeZone
|
||
import java.util.concurrent.Executors
|
||
import java.util.concurrent.TimeUnit
|
||
import java.util.regex.Matcher
|
||
import java.util.regex.Pattern
|
||
import javax.security.auth.x500.X500Principal
|
||
|
||
|
||
typealias Callback = () -> Unit
|
||
|
||
class DeviceInfo {
|
||
private var advertisingTrackingId:String = ""
|
||
private var limitedAdTracking:Boolean = false
|
||
private var adInit = false
|
||
private var adCallback: Callback? = null
|
||
private var context:Context? = null
|
||
private var apk_digest_timeout:Long = 0
|
||
private var apk_digest_size:Long = 0
|
||
private var apk_digest:String = ""
|
||
private var apk_digest_init:Boolean = false
|
||
private val DEBUG_CERT = X500Principal("CN=Android Debug,O=Android,C=US")
|
||
|
||
private object SingletonHolder {
|
||
@SuppressLint("StaticFieldLeak")
|
||
val holder = DeviceInfo()
|
||
}
|
||
|
||
companion object {
|
||
@SuppressLint("StaticFieldLeak")
|
||
val instance = SingletonHolder.holder
|
||
}
|
||
|
||
val AdvertisingTrackingId get() = advertisingTrackingId
|
||
val LimitedAdTracking get() = limitedAdTracking
|
||
val ApiLevel get() = Build.VERSION.SDK_INT
|
||
|
||
val ApkDigest get() = apk_digest
|
||
val ApkDigestSize get() = apk_digest_size
|
||
val ApkDigestTimeout get() = apk_digest_timeout
|
||
|
||
fun init(ctx:Context) {
|
||
this.context = ctx
|
||
Executors.newSingleThreadExecutor().execute {
|
||
try {
|
||
AdvertisingId.init(ctx)
|
||
advertisingTrackingId = AdvertisingId.getAdvertisingTrackingId()
|
||
limitedAdTracking = AdvertisingId.getLimitedAdTracking()
|
||
adInit = true
|
||
adCallback?.let { it() }
|
||
} catch (e: Exception) {
|
||
e.printStackTrace()
|
||
}
|
||
}
|
||
}
|
||
|
||
fun onAdInit(callback: Callback) {
|
||
if(adInit) {
|
||
callback()
|
||
}
|
||
this.adCallback = callback
|
||
}
|
||
|
||
fun getApkDigest() {
|
||
if(this.context == null) {
|
||
return
|
||
}
|
||
try {
|
||
val startTime = System.nanoTime()
|
||
val path: String = this.context!!.packageCodePath
|
||
val file = File(path)
|
||
apk_digest_size = file.length()
|
||
val fileInputStream = FileInputStream(file)
|
||
apk_digest = Utilities.sha256(fileInputStream)
|
||
fileInputStream.close()
|
||
val l4 = System.nanoTime() - startTime
|
||
val timeUnit: TimeUnit = TimeUnit.NANOSECONDS
|
||
apk_digest_timeout= timeUnit.toMillis(l4)
|
||
apk_digest_init = true
|
||
} catch (e:Throwable) {
|
||
e.printStackTrace()
|
||
}
|
||
}
|
||
|
||
fun getAuid(): String {
|
||
if(this.context == null) {
|
||
return ""
|
||
}
|
||
val sharedPreferences = this.context!!.getSharedPreferences("supersonic_shared_preferen", Context.MODE_PRIVATE)
|
||
return sharedPreferences.getString("auid", "") ?: ""
|
||
}
|
||
|
||
fun getBatteryStatus():Int {
|
||
val intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||
val intent = context!!.registerReceiver(null, intentFilter)
|
||
if (intent != null) {
|
||
return intent.getIntExtra("status", -1)
|
||
}
|
||
return -1
|
||
}
|
||
|
||
fun getBoard(): String {
|
||
return Build.BOARD
|
||
}
|
||
|
||
fun getBootloader(): String {
|
||
return Build.BOOTLOADER
|
||
}
|
||
|
||
fun getBrand(): String {
|
||
return Build.BRAND
|
||
}
|
||
|
||
fun getBuildId(): String {
|
||
return Build.ID
|
||
}
|
||
|
||
fun getBuildVersionIncremental(): String {
|
||
return Build.VERSION.INCREMENTAL
|
||
}
|
||
|
||
fun getCPUCount(): Long {
|
||
return Runtime.getRuntime().availableProcessors().toLong()
|
||
}
|
||
fun getCertificateFingerprint(): String {
|
||
val packageManager = this.context?.packageManager
|
||
val packageName = this.context?.packageName ?: return ""
|
||
try {
|
||
val packageInfo = packageManager?.getPackageInfo(packageName, 64)
|
||
val arrayOfSignature: Array<Signature>? = packageInfo!!.signatures
|
||
if (!arrayOfSignature.isNullOrEmpty()) {
|
||
val certificateFactory = CertificateFactory.getInstance("X.509")
|
||
val byteArrayInputStream = ByteArrayInputStream(arrayOfSignature[0].toByteArray())
|
||
val certificate = certificateFactory.generateCertificate(byteArrayInputStream)
|
||
val messageDigest = MessageDigest.getInstance("SHA-1")
|
||
var arrayOfByte2 = certificate.encoded
|
||
arrayOfByte2 = messageDigest.digest(arrayOfByte2)
|
||
return Utilities.toHexString(arrayOfByte2)
|
||
}
|
||
} catch (e:Throwable) {
|
||
e.printStackTrace()
|
||
}
|
||
return ""
|
||
}
|
||
|
||
fun getDevice(): String {
|
||
return Build.DEVICE
|
||
}
|
||
fun getFingerprint(): String {
|
||
return Build.FINGERPRINT
|
||
}
|
||
|
||
fun getModel(): String {
|
||
return Build.MODEL
|
||
}
|
||
|
||
fun getOsVersion(): String {
|
||
return Build.VERSION.RELEASE
|
||
}
|
||
fun getAppName() : String{
|
||
return context?.packageName ?: ""
|
||
}
|
||
fun getProduct(): String {
|
||
return Build.PRODUCT
|
||
}
|
||
fun getManufacturer(): String {
|
||
return Build.MANUFACTURER
|
||
}
|
||
|
||
fun getProcessInfo():Map<Any,Any> {
|
||
val map = mutableMapOf<Any,Any>()
|
||
val randomAccessFile1 = RandomAccessFile("/proc/self/stat","r")
|
||
randomAccessFile1.use {
|
||
map.put("stat", randomAccessFile1.readLine())
|
||
}
|
||
return map.toMap()
|
||
}
|
||
|
||
fun getRingerMode():Int {
|
||
if(this.context == null) {
|
||
return -1
|
||
}
|
||
val audioManager = this.context!!.getSystemService(Context.AUDIO_SERVICE) as android.media.AudioManager
|
||
return audioManager.ringerMode
|
||
}
|
||
|
||
fun getScreenBrightness():Int {
|
||
if(this.context == null) {
|
||
return -1
|
||
}
|
||
return Settings.System.getInt(this.context!!.contentResolver, "screen_brightness", -1)
|
||
}
|
||
fun getScreenDensity():Int {
|
||
return context?.resources?.displayMetrics?.densityDpi ?: -1
|
||
}
|
||
fun getScreenHeight():Int {
|
||
return context?.resources?.displayMetrics?.heightPixels ?: -1
|
||
}
|
||
fun getScreenWidth():Int {
|
||
return context?.resources?.displayMetrics?.widthPixels ?: -1
|
||
}
|
||
|
||
fun getScreenLayout():Int {
|
||
return context?.resources?.configuration?.screenLayout ?: -1
|
||
}
|
||
fun getSensorList(): List<Sensor> {
|
||
if(this.context == null) {
|
||
return listOf()
|
||
}
|
||
val sensorManager = this.context!!.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||
return sensorManager.getSensorList(Sensor.TYPE_ALL)
|
||
}
|
||
|
||
fun getStreamMaxVolume(paramInt:Int):Int {
|
||
if(this.context == null) {
|
||
return -1
|
||
}
|
||
val audioManager = this.context!!.getSystemService(Context.AUDIO_SERVICE) as android.media.AudioManager
|
||
return audioManager.getStreamMaxVolume(paramInt)
|
||
}
|
||
fun getStreamVolume(paramInt:Int):Int {
|
||
if(this.context == null) {
|
||
return -1
|
||
}
|
||
val audioManager = this.context!!.getSystemService(Context.AUDIO_SERVICE) as android.media.AudioManager
|
||
return audioManager.getStreamVolume(paramInt)
|
||
}
|
||
fun getSupportedAbis():Array<String> {
|
||
if (ApiLevel < 21) {
|
||
return getOldAbiList()
|
||
}
|
||
return getNewAbiList()
|
||
}
|
||
fun getSystemProperty(paramString1: String, paramString2: String?): String {
|
||
return if ((paramString2 != null)) System.getProperty(
|
||
paramString1,
|
||
paramString2
|
||
) else System.getProperty(paramString1)
|
||
}
|
||
fun getTotalMemory(): Long {
|
||
return getMemoryInfo(MemoryInfoType.TOTAL_MEMORY)
|
||
}
|
||
fun getFreeSpace(paramFile: File?): Long {
|
||
if (paramFile != null) {
|
||
val bool = paramFile.exists()
|
||
if (bool) return Math.round((paramFile.freeSpace / 1024L).toFloat())
|
||
.toLong()
|
||
}
|
||
return -1L
|
||
}
|
||
fun getTotalSpace(file: File):Long {
|
||
if(!file.exists()) {
|
||
return -1
|
||
}
|
||
return Math.round(file.totalSpace / 1024.0)
|
||
}
|
||
fun getUptime():Long {
|
||
return SystemClock.uptimeMillis()
|
||
}
|
||
|
||
fun hasAV1Decoder():Boolean {
|
||
return selectAllDecodeCodecs("video/av01").isNotEmpty()
|
||
}
|
||
fun hasX264Decoder():Boolean {
|
||
return selectAllDecodeCodecs("video/avc").isNotEmpty()
|
||
}
|
||
fun hasX265Decoder():Boolean {
|
||
return selectAllDecodeCodecs("video/hevc").isNotEmpty()
|
||
}
|
||
|
||
fun isAdbEnabled():Boolean {
|
||
if(ApiLevel < 17) {
|
||
return oldAdbStatus()
|
||
}
|
||
return newAdbStatus()
|
||
}
|
||
|
||
fun oldAdbStatus():Boolean {
|
||
val contentResolver = this.context?.contentResolver
|
||
val j = Settings.Secure.getInt(contentResolver, Settings.Global.ADB_ENABLED, 0)
|
||
return j == 1
|
||
}
|
||
|
||
fun newAdbStatus():Boolean {
|
||
val contentResolver = this.context?.contentResolver
|
||
val j = Settings.Global.getInt(contentResolver, Settings.Global.ADB_ENABLED, 0)
|
||
return j == 1
|
||
}
|
||
|
||
|
||
fun selectAllDecodeCodecs(paramString:String):List<MediaCodecInfo> {
|
||
val res = mutableListOf<MediaCodecInfo>()
|
||
val count = MediaCodecList.getCodecCount()
|
||
for (i in 0 until count) {
|
||
val mediaCodecInfo: MediaCodecInfo = MediaCodecList.getCodecInfoAt(i)
|
||
if (!mediaCodecInfo.isEncoder) {
|
||
val arrayOfString: Array<String> = mediaCodecInfo.supportedTypes
|
||
for (j in arrayOfString.indices) {
|
||
if (!arrayOfString[j].equals(paramString, ignoreCase = true)) {
|
||
continue
|
||
}
|
||
if(isHardwareAccelerated(mediaCodecInfo, paramString)) {
|
||
res.add(mediaCodecInfo)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
fun isHardwareAccelerated(paramMediaCodecInfo:MediaCodecInfo, paramString:String):Boolean {
|
||
if (ApiLevel >= 29) {
|
||
return isHardwareAcceleratedV29(paramMediaCodecInfo)
|
||
}
|
||
return isSoftwareOnly(paramMediaCodecInfo, paramString)
|
||
}
|
||
fun isHardwareAcceleratedV29(paramMediaCodecInfo:MediaCodecInfo):Boolean {
|
||
return paramMediaCodecInfo.isHardwareAccelerated
|
||
}
|
||
fun isSoftwareOnly( paramMediaCodecInfo:MediaCodecInfo, paramString:String):Boolean {
|
||
if (ApiLevel >= 29) {
|
||
return isSoftwareOnlyV29(paramMediaCodecInfo)
|
||
}
|
||
|
||
val codecName = paramMediaCodecInfo.name.lowercase()
|
||
var isSoftware = false
|
||
|
||
// 如果以"arc."开头,返回false(不是软件编解码器)
|
||
if (codecName.startsWith("arc.")) {
|
||
return false
|
||
}
|
||
|
||
// 检查是否为已知的软件编解码器
|
||
when {
|
||
codecName.startsWith("omx.google.") -> isSoftware = true
|
||
codecName.startsWith("omx.ffmpeg.") -> isSoftware = true
|
||
codecName.startsWith("omx.sec.") && codecName.contains(".sw.") -> isSoftware = true
|
||
codecName == "omx.qcom.video.decoder.hevcswvdec" -> isSoftware = true
|
||
codecName.startsWith("c2.android.") -> isSoftware = true
|
||
codecName.startsWith("c2.google.") -> isSoftware = true
|
||
// 如果不以"omx."或"c2."开头,也认为是软件编解码器
|
||
!codecName.startsWith("omx.") && !codecName.startsWith("c2.") -> isSoftware = true
|
||
}
|
||
|
||
return isSoftware
|
||
}
|
||
fun isSoftwareOnlyV29(paramMediaCodecInfo:MediaCodecInfo):Boolean {
|
||
return paramMediaCodecInfo.isSoftwareOnly
|
||
}
|
||
|
||
|
||
fun getPackageInfo(paramPackageManager: PackageManager): JSONObject {
|
||
val str1: String = getAppName()
|
||
val packageInfo = paramPackageManager.getPackageInfo(str1, 0)
|
||
val jSONObject = JSONObject()
|
||
var str2 = paramPackageManager.getInstallerPackageName(str1)
|
||
jSONObject.put("installer", str2)
|
||
var l = packageInfo.firstInstallTime
|
||
jSONObject.put("firstInstallTime", l)
|
||
l = packageInfo.lastUpdateTime
|
||
jSONObject.put("lastUpdateTime", l)
|
||
val i = packageInfo.versionCode
|
||
jSONObject.put("versionCode", i)
|
||
str2 = packageInfo.versionName
|
||
jSONObject.put("versionName", str2)
|
||
str2 = packageInfo.packageName
|
||
jSONObject.put("packageName", str2)
|
||
return jSONObject
|
||
}
|
||
|
||
fun getConnectionType():String {
|
||
if (isUsingWifi()) {
|
||
return "wifi"
|
||
}
|
||
if (isActiveNetworkConnected()) {
|
||
return "cellular"
|
||
}
|
||
return "none"
|
||
}
|
||
|
||
fun isUsingWifi():Boolean {
|
||
if (this.context == null) {
|
||
return false
|
||
}
|
||
val connectivityManager =
|
||
this.context!!.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||
if (connectivityManager == null) {
|
||
return false
|
||
}
|
||
val telephonyManager =
|
||
this.context!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||
val networkInfo = connectivityManager.getActiveNetworkInfo()
|
||
if (networkInfo == null) {
|
||
return false
|
||
}
|
||
if (!connectivityManager.backgroundDataSetting) {
|
||
return false
|
||
}
|
||
val networkInfo1 = connectivityManager.activeNetworkInfo
|
||
if (networkInfo1 == null) {
|
||
return false
|
||
}
|
||
if (networkInfo1.isConnected && telephonyManager != null) {
|
||
|
||
if (networkInfo.type == 1) {
|
||
return networkInfo.isConnected
|
||
}
|
||
return false
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
fun isActiveNetworkConnected():Boolean {
|
||
if (this.context == null) {
|
||
return false
|
||
}
|
||
val connectivityManager =
|
||
this.context!!.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||
if (connectivityManager == null) {
|
||
return false
|
||
}
|
||
val networkInfo = connectivityManager.activeNetworkInfo
|
||
return networkInfo != null && networkInfo.isConnected
|
||
}
|
||
|
||
|
||
fun getDisplayMetricDensity() : Float {
|
||
if(this.context == null) {
|
||
return -1.0f
|
||
}
|
||
return this.context!!.resources.displayMetrics.density
|
||
}
|
||
fun getElapsedRealtime() : Long {
|
||
return SystemClock.elapsedRealtime();
|
||
}
|
||
fun getExtensionVersion():Int {
|
||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||
return SdkExtensions.getExtensionVersion(Build.VERSION_CODES.R)
|
||
}
|
||
return -1
|
||
}
|
||
|
||
fun getMemoryInfo(type:MemoryInfoType) : Long {
|
||
try {
|
||
val randomAccessFile = RandomAccessFile("/proc/meminfo","r")
|
||
var i = 1
|
||
|
||
randomAccessFile.use {
|
||
/**
|
||
* 1 total
|
||
* 2 free
|
||
*/
|
||
while (true) {
|
||
val memoryInfo = randomAccessFile.readLine()
|
||
if(memoryInfo.isNullOrEmpty()) {
|
||
break
|
||
}
|
||
if(i == 1 && type == MemoryInfoType.TOTAL_MEMORY) {
|
||
return getMemoryValueFromString(memoryInfo)
|
||
}
|
||
if(i == 2 && type == MemoryInfoType.FREE_MEMORY) {
|
||
return getMemoryValueFromString(memoryInfo)
|
||
}
|
||
if(i > 2) {
|
||
break
|
||
}
|
||
i++
|
||
}
|
||
}
|
||
|
||
} catch (e:Throwable) {
|
||
e.printStackTrace()
|
||
}
|
||
return 0
|
||
}
|
||
|
||
fun getNetworkCountryISO() : String{
|
||
if(context == null) {
|
||
return ""
|
||
}
|
||
val telephonyManager = context!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||
return telephonyManager.networkCountryIso
|
||
}
|
||
fun getNetworkMetered() : Boolean {
|
||
if(context == null) {
|
||
return false
|
||
}
|
||
val connectivityManager = context!!.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||
return connectivityManager.isActiveNetworkMetered
|
||
}
|
||
fun getNetworkOperator():String {
|
||
if(context == null) {
|
||
return ""
|
||
}
|
||
val telephonyManager = context!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||
return telephonyManager.networkOperator ?: ""
|
||
}
|
||
fun getNetworkOperatorName():String {
|
||
if(context == null) {
|
||
return ""
|
||
}
|
||
val telephonyManager = context!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||
return telephonyManager.networkOperatorName ?: ""
|
||
}
|
||
fun getNetworkType(): Int {
|
||
if(context == null) {
|
||
return -1
|
||
}
|
||
val telephonyManager = context!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||
if (ActivityCompat.checkSelfPermission(
|
||
context,
|
||
Manifest.permission.READ_PHONE_STATE
|
||
) != PackageManager.PERMISSION_GRANTED
|
||
) {
|
||
// TODO: Consider calling
|
||
// ActivityCompat#requestPermissions
|
||
// here to request the missing permissions, and then overriding
|
||
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
|
||
// int[] grantResults)
|
||
// to handle the case where the user grants the permission. See the documentation
|
||
// for ActivityCompat#requestPermissions for more details.
|
||
return -1
|
||
}
|
||
return telephonyManager.getNetworkType() ?: -1
|
||
}
|
||
fun getNewAbiList(): Array<String> {
|
||
return Build.SUPPORTED_ABIS
|
||
}
|
||
fun getOldAbiList() : Array<String>{
|
||
val arrayList = mutableListOf<String>()
|
||
arrayList.add(Build.CPU_ABI)
|
||
arrayList.add(Build.CPU_ABI2)
|
||
return arrayList.toTypedArray()
|
||
}
|
||
|
||
fun isRooted():Boolean {
|
||
return searchPathForBinary("su")
|
||
}
|
||
|
||
fun isAppDebuggable():Boolean {
|
||
val packageManager = this.context?.packageManager
|
||
val packageName = this.context?.packageName
|
||
val applicationInfo = packageName?.let { packageManager?.getApplicationInfo(it, 0) }
|
||
val j = applicationInfo!!.flags and 0x2
|
||
if(j==0) {
|
||
return false
|
||
}
|
||
val packageInfo = packageManager?.getPackageInfo(packageName, 64)
|
||
val arrayOfSignature = packageInfo?.signatures
|
||
if (arrayOfSignature == null) {
|
||
return false
|
||
}
|
||
for (signature in arrayOfSignature) {
|
||
val certificateFactory = CertificateFactory.getInstance("X.509")
|
||
val byteArrayInputStream = ByteArrayInputStream(signature.toByteArray())
|
||
val certificate: Certificate = certificateFactory.generateCertificate(byteArrayInputStream)
|
||
if (certificate is X509Certificate) {
|
||
val x500Principal1 = certificate.getSubjectX500Principal()
|
||
if (x500Principal1.equals(DEBUG_CERT)) {
|
||
return true
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
return false
|
||
}
|
||
|
||
fun getLanguage() :String {
|
||
return Locale.getDefault().toString()
|
||
}
|
||
fun getAppVersion(): String? {
|
||
val str: String = this.context?.packageName ?: ""
|
||
val packageManager: PackageManager? = this.context?.packageManager
|
||
try {
|
||
val packageInfo1 = packageManager?.getPackageInfo(str, 0)
|
||
if (packageInfo1 != null) {
|
||
return packageInfo1.versionName
|
||
}
|
||
} catch (e: Throwable) {
|
||
e.printStackTrace()
|
||
}
|
||
return ""
|
||
}
|
||
fun getTimeZone() :String{
|
||
val timeZone1 = TimeZone.getDefault()
|
||
val locale = Locale.US
|
||
return timeZone1.getDisplayName(false, 0, locale)
|
||
}
|
||
fun getTimeOffset() : Int{
|
||
val timeZone = TimeZone.getDefault()
|
||
val l1 = System.currentTimeMillis()
|
||
return timeZone.getOffset(l1) / 1000
|
||
}
|
||
|
||
fun getWebViewUa() : String {
|
||
return WebSettings.getDefaultUserAgent(this.context)
|
||
}
|
||
|
||
fun isWiredHeadsetOn(): Boolean {
|
||
val audioManager = context?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||
return audioManager.isWiredHeadsetOn
|
||
}
|
||
fun isUSBConnected():Boolean {
|
||
val intentFilter = IntentFilter("android.hardware.usb.action.USB_STATE")
|
||
val intent = context?.registerReceiver(null, intentFilter);
|
||
if (intent != null) {
|
||
return intent.getBooleanExtra("connected", false)
|
||
}
|
||
return false
|
||
}
|
||
fun getBatteryLevel(): Float {
|
||
if (context != null) {
|
||
val intentFilter = IntentFilter("android.intent.action.BATTERY_CHANGED")
|
||
var i = 0
|
||
val intent = context!!.registerReceiver(null, intentFilter)
|
||
if (intent != null) {
|
||
i = -1
|
||
val j = intent.getIntExtra("level", i)
|
||
i = intent.getIntExtra("scale", i)
|
||
val f1 = j.toFloat()
|
||
val f2 = i.toFloat()
|
||
return f1 / f2
|
||
}
|
||
}
|
||
return -1.0f
|
||
}
|
||
private fun searchPathForBinary(exe:String):Boolean {
|
||
val str1 = System.getenv("PATH") ?: return false
|
||
val paths = str1.split(":")
|
||
for (path in paths) {
|
||
val file = File(path)
|
||
if(!file.exists()) {
|
||
continue
|
||
}
|
||
if(!file.isDirectory) {
|
||
continue
|
||
}
|
||
val arrayOfFile = file.listFiles()
|
||
if(arrayOfFile == null || arrayOfFile.isNotEmpty()) {
|
||
continue
|
||
}
|
||
for (it in arrayOfFile) {
|
||
if(it.name.equals(exe, ignoreCase = true)) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
private fun getMemoryValueFromString(paramString: String?): Long {
|
||
if (paramString != null) {
|
||
val pattern: Pattern = Pattern.compile("(\\d+)")
|
||
val matcher: Matcher = pattern.matcher(paramString)
|
||
if (!matcher.find()) {
|
||
return -1L
|
||
}
|
||
val value: String = matcher.group(1) ?: return -1L
|
||
try {
|
||
return value.toLong()
|
||
} catch (e: NumberFormatException) {
|
||
e.printStackTrace()
|
||
}
|
||
}
|
||
return -1L
|
||
}
|
||
|
||
|
||
fun getDeviceInfoData():List<InfoItem> {
|
||
val res = mutableListOf<InfoItem>()
|
||
res.add(InfoItem("bundleId", this.getAppName()))
|
||
res.add(InfoItem("encrypted", this.isAppDebuggable().toString()))
|
||
res.add(InfoItem("rooted", "", callback = { this.isRooted().toString() }))
|
||
res.add(InfoItem("osVersion", this.getOsVersion()))
|
||
res.add(InfoItem("deviceModel", this.getModel()))
|
||
res.add(InfoItem("language", this.getLanguage()))
|
||
res.add(InfoItem("connectionType", this.getConnectionType()))
|
||
res.add(InfoItem("screenHeight", this.getScreenHeight().toString()))
|
||
res.add(InfoItem("screenWidth", this.getScreenWidth().toString()))
|
||
res.add(InfoItem("deviceMake", this.getManufacturer()))
|
||
res.add(InfoItem("screenDensity", this.getScreenDensity().toString()))
|
||
res.add(InfoItem("screenSize", this.getScreenLayout().toString()))
|
||
res.add(InfoItem("networkOperator", this.getNetworkOperator()))
|
||
res.add(InfoItem("networkOperatorName", this.getNetworkOperatorName()))
|
||
res.add(InfoItem("wiredHeadset", this.isWiredHeadsetOn().toString()))
|
||
res.add(InfoItem("volume", this.getStreamVolume(1).toString()))
|
||
res.add(InfoItem("deviceFreeSpace", this.getFreeSpace(this.context?.cacheDir).toString()))
|
||
res.add(InfoItem("apiLevel", this.ApiLevel.toString()))
|
||
res.add(InfoItem("networkType", this.getNetworkType().toString()))
|
||
res.add(InfoItem("networkMetered", this.getNetworkMetered().toString()))
|
||
res.add(InfoItem("bundleVersion", this.getAppVersion().toString()))
|
||
res.add(InfoItem("timeZone", this.getTimeZone()))
|
||
res.add(InfoItem("cpuCount", this.getCPUCount().toString()))
|
||
res.add(InfoItem("usbConnected", this.isUSBConnected().toString()))
|
||
res.add(InfoItem("timeZoneOffset", this.getTimeOffset().toString()))
|
||
res.add(InfoItem("webviewUa", this.getWebViewUa()))
|
||
res.add(InfoItem("apkDeveloperSigningCertificateHash", this.getCertificateFingerprint()))
|
||
res.add(InfoItem("deviceUpTime", this.getUptime().toString()))
|
||
res.add(InfoItem("deviceElapsedRealtime", this.getElapsedRealtime().toString()))
|
||
res.add(InfoItem("adbEnabled", this.isAdbEnabled().toString()))
|
||
res.add(InfoItem("androidFingerprint", this.getFingerprint()))
|
||
res.add(InfoItem("batteryStatus", this.getBatteryStatus().toString()))
|
||
res.add(InfoItem("batteryLevel", this.getBatteryLevel().toString()))
|
||
res.add(InfoItem("limitAdTracking","", callback = { this.LimitedAdTracking.toString() }))
|
||
|
||
return res.toList()
|
||
}
|
||
}
|
||
|