删减代码
6
.idea/compiler.xml
generated
@ -1,6 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="1.8" />
|
<bytecodeTargetLevel target="21">
|
||||||
|
<module name="MyAndriodInfo.app" target="21" />
|
||||||
|
<module name="MyAndriodInfo.mydev" target="21" />
|
||||||
|
<module name="MyAndriodInfo.myinfohook" target="21" />
|
||||||
|
</bytecodeTargetLevel>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.ask.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AskMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.edit.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="EditMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/gradle.xml
generated
@ -10,12 +10,6 @@
|
|||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
|
||||||
<option value="$PROJECT_DIR$/app/myphoneinfo" />
|
|
||||||
<option value="$PROJECT_DIR$/ksp-annotations" />
|
|
||||||
<option value="$PROJECT_DIR$/ksp-processor" />
|
|
||||||
<option value="$PROJECT_DIR$/mydev" />
|
|
||||||
<option value="$PROJECT_DIR$/myinfohook" />
|
|
||||||
<option value="$PROJECT_DIR$/myphoneinfo" />
|
<option value="$PROJECT_DIR$/myphoneinfo" />
|
||||||
<option value="$PROJECT_DIR$/myphoneinfo/andinfo" />
|
<option value="$PROJECT_DIR$/myphoneinfo/andinfo" />
|
||||||
</set>
|
</set>
|
||||||
|
|||||||
3
.idea/misc.xml
generated
@ -1,6 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit 877328f188a3c7d1fa855871a278eb48d530c4c0
|
|
||||||
1
app/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
plugins {
|
|
||||||
alias(libs.plugins.android.application)
|
|
||||||
alias(libs.plugins.kotlin.android)
|
|
||||||
id("com.google.devtools.ksp") version "2.0.0-1.0.24"
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
namespace = "com.xyzshell.myandriodinfo"
|
|
||||||
compileSdk = 35
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
applicationId = "com.xyzshell.myandriodinfo"
|
|
||||||
minSdk = 29
|
|
||||||
targetSdk = 35
|
|
||||||
versionCode = 1
|
|
||||||
versionName = "1.0"
|
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
||||||
ndk {
|
|
||||||
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
isMinifyEnabled = false
|
|
||||||
proguardFiles(
|
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
buildFeatures {
|
|
||||||
viewBinding = true
|
|
||||||
prefab = true
|
|
||||||
aidl = true
|
|
||||||
}
|
|
||||||
|
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
path = file("src/main/cpp/CMakeLists.txt")
|
|
||||||
version = "3.22.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ndkVersion = "25.2.9519653"
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
|
|
||||||
implementation(libs.androidx.core.ktx)
|
|
||||||
implementation(libs.androidx.appcompat)
|
|
||||||
implementation(libs.material)
|
|
||||||
implementation(libs.androidx.constraintlayout)
|
|
||||||
implementation(libs.androidx.lifecycle.livedata.ktx)
|
|
||||||
implementation(libs.androidx.lifecycle.viewmodel.ktx)
|
|
||||||
implementation(libs.androidx.navigation.fragment.ktx)
|
|
||||||
implementation(libs.androidx.navigation.ui.ktx)
|
|
||||||
implementation(libs.kotlinx.serialization.json)
|
|
||||||
// implementation(com.bytedance.android.shadowhook)
|
|
||||||
// implementation("org.nanohttpd:nanohttpd:2.3.1")
|
|
||||||
implementation(libs.json.json)
|
|
||||||
implementation(libs.androidx.webkit)
|
|
||||||
implementation(libs.play.services.appset)
|
|
||||||
implementation(libs.play.services.ads.identifier)
|
|
||||||
implementation(libs.squareup.okhttp)
|
|
||||||
// 引入注解
|
|
||||||
implementation(project(":ksp-annotations"))
|
|
||||||
// 引入KSP处理器
|
|
||||||
ksp(project(":ksp-processor"))
|
|
||||||
|
|
||||||
testImplementation(libs.junit)
|
|
||||||
androidTestImplementation(libs.androidx.junit)
|
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
|
||||||
}
|
|
||||||
21
app/proguard-rules.pro
vendored
@ -1,21 +0,0 @@
|
|||||||
# Add project specific ProGuard rules here.
|
|
||||||
# You can control the set of applied configuration files using the
|
|
||||||
# proguardFiles setting in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
|
||||||
# debugging stack traces.
|
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
|
||||||
# hide the original source file name.
|
|
||||||
#-renamesourcefileattribute SourceFile
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo
|
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
fun useAppContext() {
|
|
||||||
// Context of the app under test.
|
|
||||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
|
||||||
assertEquals("com.xyzshell.myandriodinfo", appContext.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
|
|
||||||
tools:ignore="ProtectedPermissions" />
|
|
||||||
<!-- AndroidManifest.xml -->
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
|
||||||
<application
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/Theme.MyAndriodInfo"
|
|
||||||
android:usesCleartextTraffic="true"
|
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
|
||||||
tools:targetApi="31">
|
|
||||||
<activity
|
|
||||||
android:name=".MainActivity"
|
|
||||||
android:exported="true"
|
|
||||||
>
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
|
|
||||||
# For more information about using CMake with Android Studio, read the
|
|
||||||
# documentation: https://d.android.com/studio/projects/add-native-code.html.
|
|
||||||
# For more examples on how to use CMake, see https://github.com/android/ndk-samples.
|
|
||||||
|
|
||||||
# Sets the minimum CMake version required for this project.
|
|
||||||
cmake_minimum_required(VERSION 3.22.1)
|
|
||||||
|
|
||||||
# Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
|
|
||||||
# Since this is the top level CMakeLists.txt, the project name is also accessible
|
|
||||||
# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
|
|
||||||
# build script scope).
|
|
||||||
project("myandriodinfo")
|
|
||||||
|
|
||||||
# Creates and names a library, sets it as either STATIC
|
|
||||||
# or SHARED, and provides the relative paths to its source code.
|
|
||||||
# You can define multiple libraries, and CMake builds them for you.
|
|
||||||
# Gradle automatically packages shared libraries with your APK.
|
|
||||||
#
|
|
||||||
# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define
|
|
||||||
# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME}
|
|
||||||
# is preferred for the same purpose.
|
|
||||||
#
|
|
||||||
# In order to load a library into your app from Java/Kotlin, you must call
|
|
||||||
# System.loadLibrary() and pass the name of the library defined here;
|
|
||||||
# for GameActivity/NativeActivity derived applications, the same library name must be
|
|
||||||
# used in the AndroidManifest.xml file.
|
|
||||||
add_library(${CMAKE_PROJECT_NAME} SHARED
|
|
||||||
# List C/C++ source files with relative paths to this CMakeLists.txt.
|
|
||||||
myandriodinfo.cpp)
|
|
||||||
|
|
||||||
# Specifies libraries CMake should link to your target library. You
|
|
||||||
# can link libraries from various origins, such as libraries defined in this
|
|
||||||
# build script, prebuilt third-party libraries, or Android system libraries.
|
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
|
||||||
# List libraries link to the target library
|
|
||||||
android
|
|
||||||
log)
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
// Write C++ code here.
|
|
||||||
//
|
|
||||||
// Do not forget to dynamically load the C++ library into your application.
|
|
||||||
//
|
|
||||||
// For instance,
|
|
||||||
//
|
|
||||||
// In MainActivity.java:
|
|
||||||
// static {
|
|
||||||
// System.loadLibrary("myandriodinfo");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Or, in MainActivity.kt:
|
|
||||||
// companion object {
|
|
||||||
// init {
|
|
||||||
// System.loadLibrary("myandriodinfo")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo
|
|
||||||
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.navigation.findNavController
|
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
|
||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
|
||||||
import androidx.navigation.ui.setupWithNavController
|
|
||||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
|
||||||
|
|
||||||
import com.xyzshell.myandriodinfo.databinding.ActivityMainBinding
|
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
private lateinit var binding: ActivityMainBinding
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
|
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
val navView: BottomNavigationView = binding.navView
|
|
||||||
|
|
||||||
val navController = findNavController(R.id.nav_host_fragment_activity_main)
|
|
||||||
// Passing each menu ID as a set of Ids because each
|
|
||||||
// menu should be considered as top level destinations.
|
|
||||||
val appBarConfiguration = AppBarConfiguration(
|
|
||||||
setOf(
|
|
||||||
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
|
|
||||||
)
|
|
||||||
)
|
|
||||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
|
||||||
navView.setupWithNavController(navController)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.service
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import okhttp3.Call
|
|
||||||
import okhttp3.Callback
|
|
||||||
import okhttp3.MediaType.Companion.toMediaType
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.RequestBody
|
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
|
||||||
import okhttp3.Response
|
|
||||||
import okio.IOException
|
|
||||||
import org.json.JSONObject
|
|
||||||
import org.json.JSONStringer
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HttpSender {
|
|
||||||
private val mediaType = "application/json".toMediaType()
|
|
||||||
private val client = OkHttpClient()
|
|
||||||
|
|
||||||
fun post(url:String, obj:JSONObject){
|
|
||||||
val jsonString = obj.toString()
|
|
||||||
val body = jsonString.toRequestBody(mediaType)
|
|
||||||
val request = Request.Builder()
|
|
||||||
.url(url)
|
|
||||||
.post(body)
|
|
||||||
.build()
|
|
||||||
client.newCall(request).enqueue(object : Callback {
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
|
||||||
Log.e("NetworkManager", "POST request failed", e)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
val body = response.body?.string()
|
|
||||||
println(body)
|
|
||||||
if (response.isSuccessful) {
|
|
||||||
Log.d("NetworkManager", "POST request successful: $body")
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Log.e("NetworkManager", "POST request failed with code: ${response.code}")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.service
|
|
||||||
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
|
|
||||||
|
|
||||||
class JsonSerializer {
|
|
||||||
companion object {
|
|
||||||
val json = Json {
|
|
||||||
prettyPrint = true
|
|
||||||
ignoreUnknownKeys = true
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T> toJson(obj: T): String {
|
|
||||||
return json.encodeToString(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T> fromJson(jsonString: String): T {
|
|
||||||
return json.decodeFromString(jsonString)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.service
|
|
||||||
|
|
||||||
import com.xyzshell.ksp_annotations.AutoBuilder
|
|
||||||
|
|
||||||
@AutoBuilder
|
|
||||||
data class TestData(val name: String, val age: Int) {
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.dashboard
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import com.xyzshell.myandriodinfo.databinding.FragmentDashboardBinding
|
|
||||||
|
|
||||||
class DashboardFragment : Fragment() {
|
|
||||||
|
|
||||||
private var _binding: FragmentDashboardBinding? = null
|
|
||||||
|
|
||||||
// This property is only valid between onCreateView and
|
|
||||||
// onDestroyView.
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
val dashboardViewModel =
|
|
||||||
ViewModelProvider(this).get(DashboardViewModel::class.java)
|
|
||||||
|
|
||||||
_binding = FragmentDashboardBinding.inflate(inflater, container, false)
|
|
||||||
val root: View = binding.root
|
|
||||||
|
|
||||||
val textView: TextView = binding.textDashboard
|
|
||||||
dashboardViewModel.text.observe(viewLifecycleOwner) {
|
|
||||||
textView.text = it
|
|
||||||
}
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.dashboard
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
|
|
||||||
class DashboardViewModel : ViewModel() {
|
|
||||||
|
|
||||||
private val _text = MutableLiveData<String>().apply {
|
|
||||||
value = "This is dashboard Fragment"
|
|
||||||
}
|
|
||||||
val text: LiveData<String> = _text
|
|
||||||
}
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
//package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
//
|
|
||||||
//import android.content.ComponentName
|
|
||||||
//import android.content.Context
|
|
||||||
//import android.content.Intent
|
|
||||||
//import android.content.ServiceConnection
|
|
||||||
//import android.os.IBinder
|
|
||||||
//import android.os.IInterface
|
|
||||||
//import android.os.Looper
|
|
||||||
//import android.os.Parcel
|
|
||||||
//import android.os.RemoteException
|
|
||||||
//import java.util.concurrent.LinkedBlockingQueue
|
|
||||||
//
|
|
||||||
// class AdvertisingIdClient {
|
|
||||||
// @Throws(Exception::class)
|
|
||||||
// fun GetGoogleAdId(context: Context): String? {
|
|
||||||
// if (Looper.getMainLooper() == Looper.myLooper()) {
|
|
||||||
// return "Cannot call in the main thread, You must call in the other thread"
|
|
||||||
// }
|
|
||||||
// val pm = context.packageManager
|
|
||||||
// pm.getPackageInfo("com.android.vending", 0)
|
|
||||||
// val connection: AdvertisingConnection = AdvertisingConnection()
|
|
||||||
// val intent = Intent(
|
|
||||||
// "com.google.android.gms.ads.identifier.service.START"
|
|
||||||
// )
|
|
||||||
// intent.setPackage("com.google.android.gms")
|
|
||||||
// if (context.bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
|
|
||||||
// try {
|
|
||||||
// val adInterface: AdvertisingInterface = AdvertisingInterface(
|
|
||||||
// connection.binder
|
|
||||||
// )
|
|
||||||
// return adInterface.id
|
|
||||||
// } finally {
|
|
||||||
// context.unbindService(connection)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// class AdvertisingConnection : ServiceConnection {
|
|
||||||
// var retrieved: Boolean = false
|
|
||||||
// private val queue = LinkedBlockingQueue<IBinder>(1)
|
|
||||||
//
|
|
||||||
// override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
|
||||||
// try {
|
|
||||||
// queue.put(service)
|
|
||||||
// } catch (localInterruptedException: InterruptedException) {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// override fun onServiceDisconnected(name: ComponentName) {
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @get:Throws(InterruptedException::class)
|
|
||||||
// val binder: IBinder
|
|
||||||
// get() {
|
|
||||||
// check(!this.retrieved)
|
|
||||||
// this.retrieved = true
|
|
||||||
// return queue.take()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// class AdvertisingInterface(private val binder: IBinder) : IInterface {
|
|
||||||
// override fun asBinder(): IBinder {
|
|
||||||
// return binder
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @get:Throws(RemoteException::class)
|
|
||||||
// val id: String?
|
|
||||||
// get() {
|
|
||||||
// val data = Parcel.obtain()
|
|
||||||
// val reply = Parcel.obtain()
|
|
||||||
// val id: String?
|
|
||||||
// try {
|
|
||||||
// data.writeInterfaceToken("com.google.android.gms.ads.identifier.internal.IAdvertisingIdService")
|
|
||||||
// binder.transact(1, data, reply, 0)
|
|
||||||
// reply.readException()
|
|
||||||
// id = reply.readString()
|
|
||||||
// } finally {
|
|
||||||
// reply.recycle()
|
|
||||||
// data.recycle()
|
|
||||||
// }
|
|
||||||
// return id
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Throws(RemoteException::class)
|
|
||||||
// fun isLimitAdTrackingEnabled(paramBoolean: Boolean): Boolean {
|
|
||||||
// val data = Parcel.obtain()
|
|
||||||
// val reply = Parcel.obtain()
|
|
||||||
// val limitAdTracking: Boolean
|
|
||||||
// try {
|
|
||||||
// data.writeInterfaceToken("com.google.android.gms.ads.identifier.internal.IAdvertisingIdService")
|
|
||||||
// data.writeInt(if (paramBoolean) 1 else 0)
|
|
||||||
// binder.transact(2, data, reply, 0)
|
|
||||||
// reply.readException()
|
|
||||||
// limitAdTracking = 0 != reply.readInt()
|
|
||||||
// } finally {
|
|
||||||
// reply.recycle()
|
|
||||||
// data.recycle()
|
|
||||||
// }
|
|
||||||
// return limitAdTracking
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
@ -1,412 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import android.adservices.AdServicesState
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.ActivityManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.content.pm.ApplicationInfo
|
|
||||||
import android.content.pm.ConfigurationInfo
|
|
||||||
import android.content.pm.PackageInfo
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.hardware.Sensor
|
|
||||||
import android.hardware.SensorManager
|
|
||||||
import android.media.AudioManager
|
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.net.wifi.WifiManager
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Environment
|
|
||||||
import android.os.PowerManager
|
|
||||||
import android.os.Process
|
|
||||||
import android.os.SystemClock
|
|
||||||
import android.os.ext.SdkExtensions
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.telephony.TelephonyManager
|
|
||||||
import android.util.DisplayMetrics
|
|
||||||
import android.view.RoundedCorner
|
|
||||||
import android.view.WindowManager
|
|
||||||
import android.widget.ExpandableListView
|
|
||||||
import android.widget.ListView
|
|
||||||
import androidx.annotation.RequiresExtension
|
|
||||||
import com.google.android.gms.ads.identifier.AdvertisingIdClient
|
|
||||||
import com.google.android.gms.appset.AppSet
|
|
||||||
import com.google.android.gms.appset.AppSetIdClient
|
|
||||||
import com.google.android.gms.appset.AppSetIdInfo
|
|
||||||
import com.google.android.gms.tasks.Task
|
|
||||||
import java.io.File
|
|
||||||
import java.net.NetworkInterface
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
import java.util.TimeZone
|
|
||||||
import java.util.concurrent.Executors
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AppInfo(private val context:Context, private val listView: ExpandableListView) {
|
|
||||||
|
|
||||||
private val mkv: MutableMap<String, AppInfoItem> = mutableMapOf()
|
|
||||||
|
|
||||||
private lateinit var adapter: MyListViewAdapter
|
|
||||||
private val activityManager: ActivityManager = this.context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
|
||||||
private val connectivityManager = this.context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
||||||
private val packageManager: PackageManager = this.context.packageManager
|
|
||||||
private val applicationInfo: ApplicationInfo = this.context.applicationInfo
|
|
||||||
private val audioManager:AudioManager = this.context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
||||||
private val windowManager = this.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
|
||||||
private val telephonyManager = this.context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
|
||||||
private val packageInfo:PackageInfo =
|
|
||||||
this.packageManager.getPackageInfo(this.context.packageName,0)
|
|
||||||
private val powerManager = this.context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
|
||||||
private val wifiManager = this.context.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
|
||||||
fun initList() {
|
|
||||||
val groups = GroupInfo()
|
|
||||||
mkv.forEach {
|
|
||||||
groups.set("信息", it.key, it.value.name, it.value.desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
val sp = SystemProp().getInfo()
|
|
||||||
sp.kv.forEach {
|
|
||||||
groups.set("SystemProperties", it.key, it.key, it.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildProp().getInfo().kv.forEach {
|
|
||||||
groups.set("BUILD", it.key, it.key, it.value)
|
|
||||||
}
|
|
||||||
GpuInfo().getInfo()
|
|
||||||
adapter = MyListViewAdapter(this.context, groups)
|
|
||||||
this.listView.setAdapter(this.adapter)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setMkv(k: String, name: String, value: Any) {
|
|
||||||
mkv[k] = AppInfoItem(name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setAppInfo() {
|
|
||||||
val v = packageManager.getApplicationLabel(applicationInfo)
|
|
||||||
var install_name = packageManager.getInstallerPackageName(applicationInfo.packageName)
|
|
||||||
if(install_name == null) {
|
|
||||||
install_name = ""
|
|
||||||
}
|
|
||||||
setMkv("app_name", "App Name", v)
|
|
||||||
setMkv("install_name", "install name", install_name)
|
|
||||||
this.packageInfo.versionName?.let { setMkv("app_version", "Version Name", it) }
|
|
||||||
setMkv("app_version_code", "Version Code", this.packageInfo.versionCode)
|
|
||||||
setMkv("firstInstallTime", "安装时间", this.packageInfo.firstInstallTime)
|
|
||||||
setMkv("package_name", "Package Name", applicationInfo.packageName)
|
|
||||||
setMkv("target_sdk", "Target SDK", applicationInfo.targetSdkVersion)
|
|
||||||
setMkv("idfv", "idfv", "")
|
|
||||||
setMkv("idfv_scope", "idfv scope", -1)
|
|
||||||
val client = AppSet.getClient(this.context) as AppSetIdClient
|
|
||||||
val task: Task<AppSetIdInfo> = client.appSetIdInfo as Task<AppSetIdInfo>
|
|
||||||
task.addOnSuccessListener {
|
|
||||||
// Determine current scope of app set ID.
|
|
||||||
val scope: Int = it.scope
|
|
||||||
|
|
||||||
// Read app set ID value, which uses version 4 of the
|
|
||||||
// universally unique identifier (UUID) format.
|
|
||||||
val id: String = it.id
|
|
||||||
|
|
||||||
setMkv("idfv", "idfv", id)
|
|
||||||
setMkv("idfv_scope", "idfv scope", scope)
|
|
||||||
initList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setFsLm() {
|
|
||||||
val v = File(applicationInfo.sourceDir).lastModified()
|
|
||||||
setMkv("fslm", "app安装文件时间", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setPermissionInfo() {
|
|
||||||
val ps_tpg = checkPermission("android.permission.ACCESS_ADSERVICES_TOPICS")
|
|
||||||
setMkv("ps_tpg","允许应用访问用户的兴趣话题信息", ps_tpg)
|
|
||||||
val ps_apg = checkPermission("android.permission.ACCESS_ADSERVICES_ATTRIBUTION")
|
|
||||||
setMkv("ps_apg", "广告归因追踪", ps_apg)
|
|
||||||
var ps_aipg = checkPermission("android.permission.ACCESS_ADSERVICES_AD_ID")
|
|
||||||
setMkv("ps_aipg", "广告ID访问", ps_aipg)
|
|
||||||
val ps_capg = checkPermission("android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE")
|
|
||||||
setMkv("ps_capg", "允许应用创建和管理自定义广告受众群体",ps_capg)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNetworkInfo() {
|
|
||||||
setMkv("connectivity", "网络状态",
|
|
||||||
connectivityManager.restrictBackgroundStatus != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
val interfaces = NetworkInterface.getNetworkInterfaces()
|
|
||||||
if (interfaces != null) {
|
|
||||||
for (intf in interfaces) {
|
|
||||||
try {
|
|
||||||
if (!intf.isUp || intf.isLoopback) continue
|
|
||||||
sb.append("name: ${intf.name}, displayName: ${intf.displayName},")
|
|
||||||
val addresses = intf.inetAddresses
|
|
||||||
for (addr in addresses) {
|
|
||||||
sb.append("address: ${addr.hostAddress}\n")
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setMkv("NetworkInterface", "网络状态", sb.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setBuildInfo() {
|
|
||||||
setMkv("VERSION.SDK_INT","Build.VERSION.SDK_INT", Build.VERSION.SDK_INT)
|
|
||||||
setMkv("TAGS","Build.TAGS", Build.TAGS)
|
|
||||||
setMkv("SUPPORTED_ABIS","Build.SUPPORTED_ABIS", Build.SUPPORTED_ABIS)
|
|
||||||
setMkv("CPU_ABI","Build.CPU_ABI", Build.CPU_ABI)
|
|
||||||
setMkv("CPU_ABI2","Build.CPU_ABI2", Build.CPU_ABI2)
|
|
||||||
setMkv("MANUFACTURER","Build.MANUFACTURER",Build.MANUFACTURER)
|
|
||||||
setMkv("BRAND","Build.BRAND",Build.BRAND)
|
|
||||||
setMkv("HARDWARE","Build.HARDWARE",Build.HARDWARE)
|
|
||||||
setMkv("MODEL","Build.MODEL",Build.MODEL)
|
|
||||||
setMkv("DEVICE","Build.DEVICE",Build.DEVICE)
|
|
||||||
setMkv("Build.VERSION", "os version", Build.VERSION.RELEASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setFont() {
|
|
||||||
setMkv("font_scale", "Font Scale", Settings.System.getFloat(this.context.contentResolver,"font_scale"))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setLocal() {
|
|
||||||
setMkv("tz", "TimeZone",
|
|
||||||
Math.round(TimeZone.getDefault().getOffset(Date().time) * 10.0 / 3600000.0) / 10.0)
|
|
||||||
setMkv("tz_offset", "tz_offset",Math.round(
|
|
||||||
TimeZone.getDefault().getOffset(
|
|
||||||
Date().time
|
|
||||||
) * 10.0 / 3600000.0
|
|
||||||
) / 10.0)
|
|
||||||
setMkv("local","local",Locale.getDefault().toString())
|
|
||||||
val localeList = this.context.resources.configuration.locales
|
|
||||||
val stringBuilder = StringBuilder()
|
|
||||||
for (i in 0 until localeList.size()) {
|
|
||||||
val locale = localeList.get(i)
|
|
||||||
stringBuilder.append("Locale: ${locale.toString()}, Language: ${locale.language}, Country: ${locale.country}\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
setMkv("local_list", "Locale List", stringBuilder.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setScreen() {
|
|
||||||
val screen_brightness = Settings.System.getInt(this.context.contentResolver, Settings.System.SCREEN_BRIGHTNESS) / 255.0F * 100.0F
|
|
||||||
setMkv("screen_brightness","屏幕亮度", screen_brightness)
|
|
||||||
setMkv("screen_orientation", "屏幕方向", this.context.resources.configuration.orientation)
|
|
||||||
|
|
||||||
val rect = Rect()
|
|
||||||
windowManager.defaultDisplay.getRectSize(rect)
|
|
||||||
val displayMetrics = DisplayMetrics()
|
|
||||||
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
sb.append("w:${rect.width()},h:${rect.height()}\n")
|
|
||||||
sb.append("W:${displayMetrics.widthPixels},H: ${displayMetrics.heightPixels}\n")
|
|
||||||
sb.append("density:${displayMetrics.density}\n")
|
|
||||||
sb.append("densityDpi:${displayMetrics.densityDpi}\n")
|
|
||||||
sb.append("xdpi:${displayMetrics.xdpi},ydpi:${displayMetrics.ydpi}\n")
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
sb.append("tl${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT)}\n")
|
|
||||||
sb.append("tr${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT)}\n")
|
|
||||||
sb.append("bl${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT)}\n")
|
|
||||||
sb.append("br${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT)}\n")
|
|
||||||
}
|
|
||||||
setMkv("screen", "屏幕", sb.toString())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setDisk() {
|
|
||||||
setMkv("disk_free","磁盘剩余", Environment.getDataDirectory().freeSpace)
|
|
||||||
setMkv("disk_total", "磁盘", Environment.getDataDirectory().totalSpace)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun getProcessName():String {
|
|
||||||
try {
|
|
||||||
val packageManager = context.packageManager
|
|
||||||
val applicationInfo = packageManager.getApplicationInfo(
|
|
||||||
context.packageName,
|
|
||||||
PackageManager.GET_META_DATA // 0x80
|
|
||||||
)
|
|
||||||
val metaData = applicationInfo.metaData
|
|
||||||
|
|
||||||
try {
|
|
||||||
val processName = applicationInfo.processName
|
|
||||||
return processName
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
fun getProcessName1():String {
|
|
||||||
val pid = Process.myPid()
|
|
||||||
val activityManager = this.context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
|
||||||
val runningManager = activityManager.runningAppProcesses
|
|
||||||
runningManager?.forEach {
|
|
||||||
if(it.pid == pid) {
|
|
||||||
return it.processName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSystem() {
|
|
||||||
setMkv("pc", "Processors", Runtime.getRuntime().availableProcessors())
|
|
||||||
setMkv("boot_ms","bt_ms", System.currentTimeMillis() - SystemClock.elapsedRealtime())
|
|
||||||
setMkv("processName1", "Process Name", getProcessName())
|
|
||||||
setMkv("processName2", "Process Name 1", getProcessName1())
|
|
||||||
val b1 = packageManager.hasSystemFeature("com.google.android.play.feature.HPE_EXPERIENCE")
|
|
||||||
val b2 = packageManager.hasSystemFeature(PackageManager.FEATURE_PC)
|
|
||||||
val kb = this.context.resources.configuration.keyboard
|
|
||||||
var is_pc = true
|
|
||||||
if(kb != Configuration.KEYBOARD_QWERTY || (!b1 && !b2)) {
|
|
||||||
is_pc = false
|
|
||||||
}
|
|
||||||
setMkv("is_pc", "is pc", is_pc)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setMem() {
|
|
||||||
val memoryInfo = ActivityManager.MemoryInfo()
|
|
||||||
activityManager.getMemoryInfo(memoryInfo)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
setMkv("availMem", "可用内存", memoryInfo.availMem)
|
|
||||||
setMkv("totalMem", "总内存", memoryInfo.totalMem)
|
|
||||||
setMkv("threshold", "threshold", memoryInfo.threshold)
|
|
||||||
setMkv("lowMemory", "lowMemory", memoryInfo.lowMemory)
|
|
||||||
setMkv("GlEsVersion", "GlEsVersion", activityManager.deviceConfigurationInfo.glEsVersion)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSensor() {
|
|
||||||
val sensorManager = this.context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
|
||||||
val isGYROSCOPE = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null
|
|
||||||
setMkv("isGYROSCOPE","陀螺仪", isGYROSCOPE)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun setBatteryInfo() {
|
|
||||||
val intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
|
||||||
val intent = this.context.registerReceiver(null, intentFilter)
|
|
||||||
var level = -1
|
|
||||||
var scale = -1
|
|
||||||
var adn = -1
|
|
||||||
var status = -1
|
|
||||||
if(intent!=null) {
|
|
||||||
level = intent.getIntExtra("level", -1)
|
|
||||||
setMkv("battery_level", "电池Level", level)
|
|
||||||
scale = intent.getIntExtra("scale", -1)
|
|
||||||
setMkv("battery_scale", "电池scale", level)
|
|
||||||
if(level > 0 && scale > 0) {
|
|
||||||
adn = ((level / scale * 100.0F).toInt())
|
|
||||||
setMkv("battery_adn", "电池adn", adn)
|
|
||||||
}
|
|
||||||
status = intent.getIntExtra("status", -1)
|
|
||||||
setMkv("battery_status", "电池状态", status)
|
|
||||||
}
|
|
||||||
var plugged = false
|
|
||||||
if(intent != null) {
|
|
||||||
// stay_on_while_plugged_in
|
|
||||||
val plugged1:Int = intent.getIntExtra("plugged", -1)
|
|
||||||
if(plugged1 > 0) {
|
|
||||||
plugged = true
|
|
||||||
}
|
|
||||||
setMkv("battery_plugged", "电池充电", plugged)
|
|
||||||
}
|
|
||||||
setMkv("isPowerSaveMode", "Power Save Mode", powerManager.isPowerSaveMode)
|
|
||||||
// setMkv("sowpie","插电模式:sowpie", Settings.Global.getInt(this.context.contentResolver, "stay_on_while_plugged_in", -1) > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun setAudio() {
|
|
||||||
setMkv("MusicActive", "MusicActive", audioManager.isMusicActive)
|
|
||||||
setMkv("volume", "volume", audioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
|
|
||||||
setMkv("SpeakerphoneOn","SpeakerphoneOn", audioManager.isSpeakerphoneOn)
|
|
||||||
setMkv("ringerMode", "ringerMode", audioManager.ringerMode)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
val arrayOfAudioDeviceInfo = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
||||||
for (i in arrayOfAudioDeviceInfo.indices) {
|
|
||||||
val audioDeviceInfo = arrayOfAudioDeviceInfo[i]
|
|
||||||
if (audioDeviceInfo != null) {
|
|
||||||
// 3,7,8
|
|
||||||
// public static final int TYPE_BLUETOOTH_A2DP = 8;
|
|
||||||
// public static final int TYPE_BLUETOOTH_SCO = 7;
|
|
||||||
// public static final int TYPE_WIRED_HEADSET = 3;
|
|
||||||
sb.append("name: " + audioDeviceInfo.productName + ", type: " + audioDeviceInfo.type + "\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append("isWiredHeadsetOn:${audioManager.isWiredHeadsetOn()}\n")
|
|
||||||
sb.append("isBluetoothScoOn:${audioManager.isBluetoothScoOn()}\n")
|
|
||||||
sb.append("isBluetoothA2dpOn:${audioManager.isBluetoothA2dpOn()}\n")
|
|
||||||
setMkv("AudioDeviceInfo", "AudioDeviceInfo", sb.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("HardwareIds")
|
|
||||||
fun setPhoneInfo() {
|
|
||||||
setMkv("simCountryIso","Country Iso",telephonyManager.simCountryIso.toUpperCase(Locale.ENGLISH))
|
|
||||||
setMkv("NetworkOperatorName","NetworkOperatorName",telephonyManager.networkOperatorName)
|
|
||||||
setMkv("NetworkOperator","NetworkOperator",telephonyManager.networkOperator)
|
|
||||||
var manufacturerCode = ""
|
|
||||||
if (!telephonyManager.manufacturerCode.isNullOrEmpty()) {
|
|
||||||
manufacturerCode = telephonyManager.manufacturerCode.toString()
|
|
||||||
}
|
|
||||||
setMkv("ManufacturerCode","ManufacturerCode",manufacturerCode)
|
|
||||||
try {
|
|
||||||
setMkv("tel_deviceId","Telephony DeviceId",telephonyManager.getDeviceId())
|
|
||||||
}catch (e:Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkPermission(key:String):Boolean {
|
|
||||||
return this.context.packageManager.checkPermission(key,this.context.packageName) == PackageManager.PERMISSION_GRANTED
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GetAppInfo() : AppInfo {
|
|
||||||
setAppInfo()
|
|
||||||
setFsLm()
|
|
||||||
setPermissionInfo()
|
|
||||||
setSystem()
|
|
||||||
setMem()
|
|
||||||
setNetworkInfo()
|
|
||||||
setBuildInfo()
|
|
||||||
setFont()
|
|
||||||
setLocal()
|
|
||||||
setScreen()
|
|
||||||
setDisk()
|
|
||||||
setPhoneInfo()
|
|
||||||
setAudio()
|
|
||||||
setBatteryInfo()
|
|
||||||
setSensor()
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && SdkExtensions.getExtensionVersion(SdkExtensions.AD_SERVICES) >= 4) {
|
|
||||||
setAD_SERVICES()
|
|
||||||
}
|
|
||||||
initAdid()
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 4)
|
|
||||||
fun setAD_SERVICES() {
|
|
||||||
val v = AdServicesState.isAdServicesStateEnabled()
|
|
||||||
setMkv("isAdServicesStateEnabled", "Android Ad Services",v )
|
|
||||||
}
|
|
||||||
|
|
||||||
fun initAdid() {
|
|
||||||
setMkv("adid", "Ad Id", "")
|
|
||||||
Executors.newSingleThreadExecutor().execute {
|
|
||||||
try {
|
|
||||||
val adid = AdvertisingIdClient(this.context).info
|
|
||||||
setMkv("adid", "Ad Id", adid.id?:"")
|
|
||||||
initList()
|
|
||||||
|
|
||||||
} catch (e: java.lang.Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
class AppInfoItem(val name:String, val v: Any) {
|
|
||||||
var desc: String = "属性值:${v}"
|
|
||||||
}
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import android.util.ArraySet
|
|
||||||
import com.xyzshell.myandriodinfo.service.HttpSender
|
|
||||||
|
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
class BuildProp {
|
|
||||||
|
|
||||||
val kv = mutableMapOf<String, String>()
|
|
||||||
val js_build = JSONObject()
|
|
||||||
val js_ver = JSONObject()
|
|
||||||
val js_verc = JSONObject()
|
|
||||||
|
|
||||||
private fun call(name:String, obj: Any, js: JSONObject) {
|
|
||||||
if (obj is Array<*>) {
|
|
||||||
val jarr = JSONArray()
|
|
||||||
for (item in obj) {
|
|
||||||
if (item != null) {
|
|
||||||
jarr.put(item)
|
|
||||||
} else {
|
|
||||||
jarr.put("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kv[name] = jarr.toString()
|
|
||||||
js.put(name, jarr)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
var v = ""
|
|
||||||
v = obj.toString()
|
|
||||||
kv[name] = v
|
|
||||||
|
|
||||||
if(obj is ArraySet<*>) {
|
|
||||||
val tjs = JSONObject()
|
|
||||||
tjs.put("type", obj.javaClass.name)
|
|
||||||
val jarr = JSONArray()
|
|
||||||
for (item in obj) {
|
|
||||||
if (item != null) {
|
|
||||||
jarr.put(item)
|
|
||||||
} else {
|
|
||||||
jarr.put("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tjs.put("val", jarr)
|
|
||||||
js.put(name, tjs)
|
|
||||||
} else {
|
|
||||||
js.put(name, obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getInfo() : BuildProp {
|
|
||||||
val buildCls = Build::class.java
|
|
||||||
val fi = buildCls.declaredFields
|
|
||||||
for (it in fi) {
|
|
||||||
val obj = it.get(null)
|
|
||||||
call(it.name, obj, js_build)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildVerCLs = Build.VERSION::class.java
|
|
||||||
val vfi = buildVerCLs.declaredFields
|
|
||||||
for (it in vfi) {
|
|
||||||
val obj =it.get(null)
|
|
||||||
call(it.name, obj, js_ver)
|
|
||||||
}
|
|
||||||
|
|
||||||
val buildVerCode = Build.VERSION_CODES::class.java
|
|
||||||
val vcfi = buildVerCode.declaredFields
|
|
||||||
for (it in vcfi) {
|
|
||||||
val obj =it.get(null)
|
|
||||||
call(it.name, obj, js_verc)
|
|
||||||
}
|
|
||||||
val js = JSONObject()
|
|
||||||
js.put("BUILD", js_build)
|
|
||||||
js.put("BUILD.VERSION", js_ver)
|
|
||||||
js.put("BUILD.VERSION_CODES", js_ver)
|
|
||||||
try {
|
|
||||||
HttpSender().post("http://192.168.1.100:9999/devices/android", js)
|
|
||||||
}catch (e:Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun runOnUiThread(any: Any) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import android.opengl.GLES10
|
|
||||||
import android.opengl.GLES10Ext
|
|
||||||
import android.opengl.GLES20
|
|
||||||
import android.opengl.GLES30
|
|
||||||
import android.opengl.GLES32
|
|
||||||
import com.xyzshell.myandriodinfo.service.HttpSender
|
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
class GpuInfo {
|
|
||||||
fun getInfo() {
|
|
||||||
//GLES10.glGetString(GLES10.GL_VENDOR)
|
|
||||||
val gl_vendor = GLES20.glGetString(GLES20.GL_VENDOR)
|
|
||||||
val gl_version = GLES20.glGetString(GLES20.GL_VERSION)
|
|
||||||
val gl_renderer = GLES20.glGetString(GLES20.GL_RENDERER)
|
|
||||||
val gl_extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS)
|
|
||||||
|
|
||||||
val js = JSONObject()
|
|
||||||
js.put("GL_VENDOR", gl_vendor)
|
|
||||||
js.put("GL_VERSION", gl_version)
|
|
||||||
js.put("GL_RENDERER", gl_renderer)
|
|
||||||
js.put("GL_EXTENSIONS", gl_extensions)
|
|
||||||
HttpSender().post("http://192.168.1.100:9999/devices/android", js)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
class GroupInfo {
|
|
||||||
private val groups: MutableMap<String,Group> = mutableMapOf()
|
|
||||||
|
|
||||||
private val groupKeys get() = groups.keys.toList()
|
|
||||||
private var nextId = 1L
|
|
||||||
|
|
||||||
val size get() = groups.size
|
|
||||||
|
|
||||||
fun getGroup(position: Int) : Group {
|
|
||||||
val key = groupKeys[position]
|
|
||||||
return groups[key]!!
|
|
||||||
}
|
|
||||||
|
|
||||||
fun set(groupName: String, key:String, name: String, value: Any) {
|
|
||||||
var group = groups[groupName]
|
|
||||||
if (group == null) {
|
|
||||||
group = Group(nextId++, groupName, "")
|
|
||||||
groups[groupName] = group
|
|
||||||
}
|
|
||||||
group.addItem(key, AppInfoItem(name, value))
|
|
||||||
}
|
|
||||||
|
|
||||||
class Group(val id: Long, var name: String, var desc: String) {
|
|
||||||
private val items: MutableMap<String, AppInfoItem> = mutableMapOf()
|
|
||||||
private val keys get() = items.keys.toList()
|
|
||||||
|
|
||||||
val size get() = items.size
|
|
||||||
|
|
||||||
fun get(position: Int) : AppInfoItem {
|
|
||||||
val key = keys[position]
|
|
||||||
return items[key] ?: AppInfoItem("", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addItem(key: String, item: AppInfoItem) {
|
|
||||||
items[key] = item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ExpandableListView
|
|
||||||
import android.widget.ListView
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.xyzshell.myandriodinfo.databinding.FragmentHomeBinding
|
|
||||||
|
|
||||||
class HomeFragment : Fragment() {
|
|
||||||
|
|
||||||
private var _binding: FragmentHomeBinding? = null
|
|
||||||
|
|
||||||
// This property is only valid between onCreateView and
|
|
||||||
// onDestroyView.
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
|
|
||||||
|
|
||||||
_binding = FragmentHomeBinding.inflate(inflater, container, false)
|
|
||||||
val root: View = binding.root
|
|
||||||
|
|
||||||
val listView: ExpandableListView = binding.infoList
|
|
||||||
|
|
||||||
context?.let { it1 -> AppInfo(it1, listView).GetAppInfo() }?.initList()
|
|
||||||
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
|
|
||||||
class HomeViewModel : ViewModel() {
|
|
||||||
|
|
||||||
private val _text = MutableLiveData<String>().apply {
|
|
||||||
value = "This is home Fragment"
|
|
||||||
}
|
|
||||||
val text: LiveData<String> = _text
|
|
||||||
}
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.BaseExpandableListAdapter
|
|
||||||
import android.widget.TextView
|
|
||||||
import com.xyzshell.myandriodinfo.R
|
|
||||||
|
|
||||||
class MyListViewAdapter(context: Context, private val data: GroupInfo) : BaseExpandableListAdapter() {
|
|
||||||
private val inflater:LayoutInflater = LayoutInflater.from(context)
|
|
||||||
|
|
||||||
|
|
||||||
class ViewHolder() {
|
|
||||||
lateinit var titleTextView: TextView
|
|
||||||
lateinit var descriptionTextView: TextView
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getGroupCount(): Int {
|
|
||||||
return data.size
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getChildrenCount(groupPosition: Int): Int {
|
|
||||||
return data.getGroup(groupPosition).size
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getGroup(groupPosition: Int): Any {
|
|
||||||
return data.getGroup(groupPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getChild(groupPosition: Int, childPosition: Int): Any {
|
|
||||||
return data.getGroup(groupPosition).get(childPosition)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getGroupId(groupPosition: Int): Long {
|
|
||||||
return groupPosition.toLong()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getChildId(groupPosition: Int, childPosition: Int): Long {
|
|
||||||
return groupPosition * 1000 + childPosition.toLong()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hasStableIds(): Boolean {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getGroupView(
|
|
||||||
groupPosition: Int,
|
|
||||||
isExpanded: Boolean,
|
|
||||||
convertView: View?,
|
|
||||||
parent: ViewGroup?
|
|
||||||
): View {
|
|
||||||
//1.item view
|
|
||||||
|
|
||||||
val v = inflater.inflate(
|
|
||||||
android.R.layout.simple_expandable_list_item_1, parent, false) as TextView
|
|
||||||
|
|
||||||
//2.item data
|
|
||||||
|
|
||||||
val group = this.getGroup(groupPosition) as GroupInfo.Group
|
|
||||||
|
|
||||||
//3.set item data add to item view
|
|
||||||
|
|
||||||
v.text = group.name;
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getChildView(
|
|
||||||
groupPosition: Int,
|
|
||||||
childPosition: Int,
|
|
||||||
isLastChild: Boolean,
|
|
||||||
convertView: View?,
|
|
||||||
parent: ViewGroup?
|
|
||||||
): View? {
|
|
||||||
val holder: ViewHolder
|
|
||||||
var ctv: View? = convertView
|
|
||||||
if (ctv == null) {
|
|
||||||
ctv = inflater.inflate(R.layout.list_view_item, parent, false);
|
|
||||||
holder = ViewHolder()
|
|
||||||
holder.titleTextView = ctv.findViewById(R.id.titleTextView);
|
|
||||||
holder.descriptionTextView = ctv.findViewById(R.id.descriptionTextView);
|
|
||||||
ctv.tag = holder
|
|
||||||
} else {
|
|
||||||
holder = ctv.tag as ViewHolder
|
|
||||||
}
|
|
||||||
val item: AppInfoItem = this.getChild(groupPosition, childPosition) as AppInfoItem
|
|
||||||
holder.titleTextView.text = item.name
|
|
||||||
holder.descriptionTextView.text = item.desc
|
|
||||||
|
|
||||||
return ctv;
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import android.hardware.Sensor
|
|
||||||
import android.hardware.SensorEvent
|
|
||||||
import android.hardware.SensorEventListener
|
|
||||||
|
|
||||||
class SensorEventData: SensorEventListener {
|
|
||||||
override fun onSensorChanged(p0: SensorEvent?) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,154 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.home
|
|
||||||
|
|
||||||
import android.util.ArraySet
|
|
||||||
import com.xyzshell.myandriodinfo.service.HttpSender
|
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
|
|
||||||
class SystemProp {
|
|
||||||
private fun call(name:String, obj: Any, js: JSONObject) {
|
|
||||||
if (obj is Array<*>) {
|
|
||||||
val jarr = JSONArray()
|
|
||||||
for (item in obj) {
|
|
||||||
if (item != null) {
|
|
||||||
jarr.put(item)
|
|
||||||
} else {
|
|
||||||
jarr.put("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kv[name] = jarr.toString()
|
|
||||||
js.put(name, jarr)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
var v = ""
|
|
||||||
v = obj.toString()
|
|
||||||
kv[name] = v
|
|
||||||
|
|
||||||
if(obj is ArraySet<*>) {
|
|
||||||
val tjs = JSONObject()
|
|
||||||
tjs.put("type", obj.javaClass.name)
|
|
||||||
val jarr = JSONArray()
|
|
||||||
for (item in obj) {
|
|
||||||
if (item != null) {
|
|
||||||
jarr.put(item)
|
|
||||||
} else {
|
|
||||||
jarr.put("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tjs.put("val", jarr)
|
|
||||||
js.put(name, tjs)
|
|
||||||
} else {
|
|
||||||
js.put(name, obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private val keys = listOf(
|
|
||||||
"ro.product.model",
|
|
||||||
"ro.product.name",
|
|
||||||
"ro.product.device",
|
|
||||||
"ro.product.board",
|
|
||||||
"ro.product.manufacturer",
|
|
||||||
"ro.bootloader",
|
|
||||||
"ro.build.product",
|
|
||||||
"ro.product.brand",
|
|
||||||
"ro.build.fingerprint",
|
|
||||||
"ro.build.description",
|
|
||||||
"gsm.version.baseband",
|
|
||||||
"ro.csc.active",
|
|
||||||
"ro.knox.warranty",
|
|
||||||
"ro.product.mfg_date",
|
|
||||||
"ro.product.code",
|
|
||||||
"drm.service.enabled",
|
|
||||||
"ro.vendor.mtk_widevine_drm_l1_support",
|
|
||||||
"ro.vendor.mtk_widevine_drm_l3_support",
|
|
||||||
"ro.serialno",
|
|
||||||
"ro.boot.serialno",
|
|
||||||
"gsf.id",
|
|
||||||
"ro.gms.version",
|
|
||||||
"ro.build.id",
|
|
||||||
"ro.build.version.release",
|
|
||||||
"ro.build.version.sdk",
|
|
||||||
"ro.build.version.security_patch",
|
|
||||||
"ro.kernel.version",
|
|
||||||
"ro.csc.country_code",
|
|
||||||
"ro.csc.sales_code",
|
|
||||||
"ro.csc.countryiso_code",
|
|
||||||
"ro.product.model.full",
|
|
||||||
"ro.product.model_code",
|
|
||||||
"ro.product.full_name",
|
|
||||||
"ril.product_code",
|
|
||||||
"ril.official_cscver",
|
|
||||||
"ro.csc.omcnw_code",
|
|
||||||
"ro.csc.omcnw_code2",
|
|
||||||
"ro.hardware",
|
|
||||||
"ro.product.cpu.abi",
|
|
||||||
"ro.product.cpu.abilist",
|
|
||||||
"ro.product.cpu.abilist64",
|
|
||||||
"ro.product.cpu.abilist32",
|
|
||||||
"ro.treble.enabled",
|
|
||||||
"ro.debuggable",
|
|
||||||
"ro.secure",
|
|
||||||
"ro.build.type",
|
|
||||||
"ro.build.tags",
|
|
||||||
"ro.build.date.utc",
|
|
||||||
"ro.sf.lcd_density",
|
|
||||||
"ro.sf.physical_density",
|
|
||||||
"vendor.display.lcd_density",
|
|
||||||
"qemu.sf.lcd_density",
|
|
||||||
"ro.display.max_brightness",
|
|
||||||
"vendor.display.brightness_max",
|
|
||||||
"ro.vendor.display.brightness_max",
|
|
||||||
"vendor.display.hdr_support",
|
|
||||||
"ro.vendor.display.hdr10_support",
|
|
||||||
"vendor.display.hdr10plus_support",
|
|
||||||
"vendor.display.hlg_support",
|
|
||||||
"vendor.display.dolby_vision_support",
|
|
||||||
"ro.surface_flinger.refresh_rate_switching",
|
|
||||||
"vendor.display.refresh_rate_switching",
|
|
||||||
"ro.vendor.display.refresh_rates",
|
|
||||||
"vendor.display.supported_refresh_rates",
|
|
||||||
"vendor.display.wide_color_support",
|
|
||||||
"ro.vendor.display.wcg_support",
|
|
||||||
"vendor.display.color_gamut",
|
|
||||||
"vendor.display.p3_support",
|
|
||||||
"ro.vendor.display.p3_support",
|
|
||||||
"ro.surface_flinger.has_wide_color_display",
|
|
||||||
"ro.surface_flinger.wcg_composition_dataspace",
|
|
||||||
"ro.surface_flinger.use_color_management",
|
|
||||||
"ro.vendor.display.peak_brightness",
|
|
||||||
"ro.product.cpu.abi",
|
|
||||||
"ro.product.cpu.abilist",
|
|
||||||
"ro.product.cpu.abilist64",
|
|
||||||
"ro.product.cpu.abilist32",
|
|
||||||
"ro.chipname",
|
|
||||||
"ro.board.platform",
|
|
||||||
"ro.hardware",
|
|
||||||
"ro.boot.ddr_type"
|
|
||||||
)
|
|
||||||
|
|
||||||
private val mkv = mutableMapOf<String, String>()
|
|
||||||
|
|
||||||
val kv get() = mkv
|
|
||||||
|
|
||||||
fun getInfo(): SystemProp {
|
|
||||||
val cls = Class.forName("android.os.SystemProperties")
|
|
||||||
val method = cls.getMethod("get", String::class.java)
|
|
||||||
val js = JSONObject()
|
|
||||||
keys.forEach { k ->
|
|
||||||
method.invoke(null, k)?.let {
|
|
||||||
call(k, it, js)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
HttpSender().post("http://192.168.1.100:9999/devices/android", js)
|
|
||||||
}catch (e:Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.notifications
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import com.xyzshell.myandriodinfo.databinding.FragmentNotificationsBinding
|
|
||||||
|
|
||||||
class NotificationsFragment : Fragment() {
|
|
||||||
|
|
||||||
private var _binding: FragmentNotificationsBinding? = null
|
|
||||||
|
|
||||||
// This property is only valid between onCreateView and
|
|
||||||
// onDestroyView.
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
val notificationsViewModel =
|
|
||||||
ViewModelProvider(this).get(NotificationsViewModel::class.java)
|
|
||||||
|
|
||||||
_binding = FragmentNotificationsBinding.inflate(inflater, container, false)
|
|
||||||
val root: View = binding.root
|
|
||||||
|
|
||||||
val textView: TextView = binding.textNotifications
|
|
||||||
notificationsViewModel.text.observe(viewLifecycleOwner) {
|
|
||||||
textView.text = it
|
|
||||||
}
|
|
||||||
return root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo.ui.notifications
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
|
|
||||||
class NotificationsViewModel : ViewModel() {
|
|
||||||
|
|
||||||
private val _text = MutableLiveData<String>().apply {
|
|
||||||
value = "This is notifications Fragment"
|
|
||||||
}
|
|
||||||
val text: LiveData<String> = _text
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24.0"
|
|
||||||
android:viewportHeight="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
|
|
||||||
</vector>
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24.0"
|
|
||||||
android:viewportHeight="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
|
|
||||||
</vector>
|
|
||||||
@ -1,170 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path
|
|
||||||
android:fillColor="#3DDC84"
|
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M9,0L9,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,0L19,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,0L29,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,0L39,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,0L49,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,0L59,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,0L69,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,0L79,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M89,0L89,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M99,0L99,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,9L108,9"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,19L108,19"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,29L108,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,39L108,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,49L108,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,59L108,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,69L108,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,79L108,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,89L108,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,99L108,99"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,29L89,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,39L89,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,49L89,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,59L89,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,69L89,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,79L89,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,19L29,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,19L39,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,19L49,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,19L59,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,19L69,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,19L79,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
</vector>
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:strokeColor="#00000000" />
|
|
||||||
</vector>
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24.0"
|
|
||||||
android:viewportHeight="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
|
|
||||||
</vector>
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<com.google.android.material.bottomnavigation.BottomNavigationView
|
|
||||||
android:id="@+id/nav_view"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="0dp"
|
|
||||||
android:layout_marginEnd="0dp"
|
|
||||||
android:background="?android:attr/windowBackground"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:menu="@menu/bottom_nav_menu" />
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/nav_host_fragment_activity_main"
|
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginLeft="1dp"
|
|
||||||
android:layout_marginTop="1dp"
|
|
||||||
android:layout_marginRight="1dp"
|
|
||||||
android:layout_marginBottom="66dp"
|
|
||||||
app:defaultNavHost="true"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/nav_view"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:navGraph="@navigation/mobile_navigation" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.dashboard.DashboardFragment">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_dashboard"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textSize="20sp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.home.HomeFragment">
|
|
||||||
<ExpandableListView
|
|
||||||
android:id="@+id/info_list"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:divider="#E0E0E0"
|
|
||||||
android:dividerHeight="1dp"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
android:scrollbarStyle="outsideOverlay"
|
|
||||||
android:scrollbarSize="8dp"
|
|
||||||
android:fadeScrollbars="true"
|
|
||||||
android:scrollbarFadeDuration="1000"
|
|
||||||
android:layout_weight="1"
|
|
||||||
tools:ignore="MissingConstraints"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
/>
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.notifications.NotificationsFragment">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_notifications"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="8dp"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textSize="20sp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:baselineAligned="false"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:ignore="UselessParent">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/titleTextView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:textColor="#333333"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/descriptionTextView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="14sp"
|
|
||||||
android:textColor="#666666"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:maxLines="10"
|
|
||||||
android:ellipsize="end" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/navigation_home"
|
|
||||||
android:icon="@drawable/ic_home_black_24dp"
|
|
||||||
android:title="@string/title_home" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/navigation_dashboard"
|
|
||||||
android:icon="@drawable/ic_dashboard_black_24dp"
|
|
||||||
android:title="@string/title_dashboard" />
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/navigation_notifications"
|
|
||||||
android:icon="@drawable/ic_notifications_black_24dp"
|
|
||||||
android:title="@string/title_notifications" />
|
|
||||||
|
|
||||||
</menu>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 982 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/mobile_navigation"
|
|
||||||
app:startDestination="@+id/navigation_home">
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/navigation_home"
|
|
||||||
android:name="com.xyzshell.myandriodinfo.ui.home.HomeFragment"
|
|
||||||
android:label="@string/title_home"
|
|
||||||
tools:layout="@layout/fragment_home" />
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/navigation_dashboard"
|
|
||||||
android:name="com.xyzshell.myandriodinfo.ui.dashboard.DashboardFragment"
|
|
||||||
android:label="@string/title_dashboard"
|
|
||||||
tools:layout="@layout/fragment_dashboard" />
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/navigation_notifications"
|
|
||||||
android:name="com.xyzshell.myandriodinfo.ui.notifications.NotificationsFragment"
|
|
||||||
android:label="@string/title_notifications"
|
|
||||||
tools:layout="@layout/fragment_notifications" />
|
|
||||||
</navigation>
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="Theme.MyAndriodInfo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
|
||||||
<!-- Primary brand color. -->
|
|
||||||
<item name="colorPrimary">@color/purple_200</item>
|
|
||||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
|
||||||
<item name="colorOnPrimary">@color/black</item>
|
|
||||||
<!-- Secondary brand color. -->
|
|
||||||
<item name="colorSecondary">@color/teal_200</item>
|
|
||||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
|
||||||
<item name="colorOnSecondary">@color/black</item>
|
|
||||||
<!-- Status bar color. -->
|
|
||||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="purple_200">#FFBB86FC</color>
|
|
||||||
<color name="purple_500">#FF6200EE</color>
|
|
||||||
<color name="purple_700">#FF3700B3</color>
|
|
||||||
<color name="teal_200">#FF03DAC5</color>
|
|
||||||
<color name="teal_700">#FF018786</color>
|
|
||||||
<color name="black">#FF000000</color>
|
|
||||||
<color name="white">#FFFFFFFF</color>
|
|
||||||
</resources>
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
|
||||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
|
||||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
|
||||||
</resources>
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<string name="app_name">MyAndriodInfo</string>
|
|
||||||
<string name="title_home">信息列表</string>
|
|
||||||
<string name="title_dashboard">Dashboard</string>
|
|
||||||
<string name="title_notifications">Notifications</string>
|
|
||||||
</resources>
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="Theme.MyAndriodInfo" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
|
||||||
<!-- Primary brand color. -->
|
|
||||||
<item name="colorPrimary">@color/purple_500</item>
|
|
||||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
|
||||||
<item name="colorOnPrimary">@color/white</item>
|
|
||||||
<!-- Secondary brand color. -->
|
|
||||||
<item name="colorSecondary">@color/teal_200</item>
|
|
||||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
|
||||||
<item name="colorOnSecondary">@color/black</item>
|
|
||||||
<!-- Status bar color. -->
|
|
||||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
|
||||||
Sample backup rules file; uncomment and customize as necessary.
|
|
||||||
See https://developer.android.com/guide/topics/data/autobackup
|
|
||||||
for details.
|
|
||||||
Note: This file is ignored for devices older that API 31
|
|
||||||
See https://developer.android.com/about/versions/12/backup-restore
|
|
||||||
-->
|
|
||||||
<full-backup-content>
|
|
||||||
<!--
|
|
||||||
<include domain="sharedpref" path="."/>
|
|
||||||
<exclude domain="sharedpref" path="device.xml"/>
|
|
||||||
-->
|
|
||||||
</full-backup-content>
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
|
||||||
Sample data extraction rules file; uncomment and customize as necessary.
|
|
||||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
|
||||||
for details.
|
|
||||||
-->
|
|
||||||
<data-extraction-rules>
|
|
||||||
<cloud-backup>
|
|
||||||
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
|
||||||
<include .../>
|
|
||||||
<exclude .../>
|
|
||||||
-->
|
|
||||||
</cloud-backup>
|
|
||||||
<!--
|
|
||||||
<device-transfer>
|
|
||||||
<include .../>
|
|
||||||
<exclude .../>
|
|
||||||
</device-transfer>
|
|
||||||
-->
|
|
||||||
</data-extraction-rules>
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<network-security-config>
|
|
||||||
<domain-config cleartextTrafficPermitted="true">
|
|
||||||
<domain includeSubdomains="true">192.168.1.100</domain>
|
|
||||||
<domain includeSubdomains="true">10.0.2.2</domain> <!-- Android模拟器localhost -->
|
|
||||||
<domain includeSubdomains="true">localhost</domain>
|
|
||||||
</domain-config>
|
|
||||||
</network-security-config>
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package com.xyzshell.myandriodinfo
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
class ExampleUnitTest {
|
|
||||||
@Test
|
|
||||||
fun addition_isCorrect() {
|
|
||||||
assertEquals(4, 2 + 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
ksp-annotations/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.xyzshell.ksp_annotations
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
annotation class AutoBuilder
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'org.jetbrains.kotlin.jvm'
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
|
|
||||||
compileKotlin {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.xyzshell.ksp_annotations
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
annotation class AutoBuilder
|
|
||||||
1
ksp-processor/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
||||||
@ -1 +0,0 @@
|
|||||||
com.xyzshell.ksp_processor.AutoBuilderProcessorProvider
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
package com.xyzshell.ksp_processor
|
|
||||||
|
|
||||||
import com.google.devtools.ksp.processing.*
|
|
||||||
import com.google.devtools.ksp.symbol.*
|
|
||||||
import com.google.devtools.ksp.validate
|
|
||||||
import com.squareup.kotlinpoet.*
|
|
||||||
import com.squareup.kotlinpoet.ksp.toClassName
|
|
||||||
import com.squareup.kotlinpoet.ksp.writeTo
|
|
||||||
import com.xyzshell.ksp_annotations.AutoBuilder
|
|
||||||
|
|
||||||
class AutoBuilderProcessor(
|
|
||||||
private val codeGenerator: CodeGenerator,
|
|
||||||
private val logger: KSPLogger
|
|
||||||
) : SymbolProcessor {
|
|
||||||
|
|
||||||
override fun process(resolver: Resolver): List<KSAnnotated> {
|
|
||||||
val symbols = resolver.getSymbolsWithAnnotation(AutoBuilder::class.qualifiedName!!)
|
|
||||||
val ret = symbols.filter { !it.validate() }.toList()
|
|
||||||
|
|
||||||
symbols
|
|
||||||
.filter { it is KSClassDeclaration && it.validate() }
|
|
||||||
.forEach { it ->
|
|
||||||
generateBuilderClass(it as KSClassDeclaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateBuilderClass(classDeclaration: KSClassDeclaration) {
|
|
||||||
val packageName = classDeclaration.containingFile!!.packageName.asString()
|
|
||||||
val className = classDeclaration.simpleName.asString()
|
|
||||||
val builderClassName = "${className}Builder"
|
|
||||||
|
|
||||||
logger.info("Generating builder for $className")
|
|
||||||
|
|
||||||
// 获取类的构造函数参数
|
|
||||||
val constructor = classDeclaration.primaryConstructor
|
|
||||||
if (constructor == null) {
|
|
||||||
logger.error("Class $className must have a primary constructor", classDeclaration)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val properties = constructor.parameters
|
|
||||||
|
|
||||||
// 创建Builder类
|
|
||||||
val builderClass = TypeSpec.classBuilder(builderClassName)
|
|
||||||
.addKdoc("Auto-generated builder for %L", className)
|
|
||||||
|
|
||||||
// 添加属性字段
|
|
||||||
properties.forEach { param ->
|
|
||||||
val paramName = param.name!!.asString()
|
|
||||||
val paramType = param.type.resolve()
|
|
||||||
val typeName = paramType.toClassName()
|
|
||||||
|
|
||||||
builderClass.addProperty(
|
|
||||||
PropertySpec.builder(paramName, typeName.copy(nullable = true))
|
|
||||||
.mutable()
|
|
||||||
.initializer("null")
|
|
||||||
.addModifiers(KModifier.PRIVATE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加setter方法
|
|
||||||
properties.forEach { param ->
|
|
||||||
val paramName = param.name!!.asString()
|
|
||||||
val paramType = param.type.resolve()
|
|
||||||
val typeName = paramType.toClassName()
|
|
||||||
|
|
||||||
val setterMethod = FunSpec.builder(paramName)
|
|
||||||
.addParameter(paramName, typeName)
|
|
||||||
.returns(ClassName(packageName, builderClassName))
|
|
||||||
.addStatement("this.%L = %L", paramName, paramName)
|
|
||||||
.addStatement("return this")
|
|
||||||
.build()
|
|
||||||
|
|
||||||
builderClass.addFunction(setterMethod)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加build方法
|
|
||||||
val buildMethod = FunSpec.builder("build")
|
|
||||||
.returns(ClassName(packageName, className))
|
|
||||||
.apply {
|
|
||||||
val paramNames = properties.map { it.name!!.asString() }
|
|
||||||
val paramChecks = paramNames.map { paramName ->
|
|
||||||
"checkNotNull($paramName) { \"$paramName must be set\" }"
|
|
||||||
}
|
|
||||||
|
|
||||||
addStatement(
|
|
||||||
"return %T(%L)",
|
|
||||||
ClassName(packageName, className),
|
|
||||||
paramChecks.joinToString(", ")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.build()
|
|
||||||
|
|
||||||
builderClass.addFunction(buildMethod)
|
|
||||||
|
|
||||||
// 添加静态工厂方法
|
|
||||||
val companionObject = TypeSpec.companionObjectBuilder()
|
|
||||||
.addFunction(
|
|
||||||
FunSpec.builder("builder")
|
|
||||||
.returns(ClassName(packageName, builderClassName))
|
|
||||||
.addStatement("return %T()", ClassName(packageName, builderClassName))
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
builderClass.addType(companionObject)
|
|
||||||
|
|
||||||
// 生成文件
|
|
||||||
val file = FileSpec.builder(packageName, builderClassName)
|
|
||||||
.addType(builderClass.build())
|
|
||||||
.build()
|
|
||||||
|
|
||||||
file.writeTo(codeGenerator, Dependencies(true, classDeclaration.containingFile!!))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package com.xyzshell.ksp_processor
|
|
||||||
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessor
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessorProvider
|
|
||||||
|
|
||||||
class AutoBuilderProcessorProvider : SymbolProcessorProvider {
|
|
||||||
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
|
|
||||||
return AutoBuilderProcessor(
|
|
||||||
codeGenerator = environment.codeGenerator,
|
|
||||||
logger = environment.logger
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'org.jetbrains.kotlin.jvm'
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
|
|
||||||
compileKotlin {
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation project(':ksp-annotations')
|
|
||||||
implementation libs.google.symbol.processing.api
|
|
||||||
implementation libs.kotlinpoet
|
|
||||||
implementation libs.kotlinpoet.ksp
|
|
||||||
}
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
package com.xyzshell.ksp_processor
|
|
||||||
|
|
||||||
import com.google.devtools.ksp.processing.*
|
|
||||||
import com.google.devtools.ksp.symbol.*
|
|
||||||
import com.google.devtools.ksp.validate
|
|
||||||
import com.squareup.kotlinpoet.*
|
|
||||||
import com.squareup.kotlinpoet.ksp.toClassName
|
|
||||||
import com.squareup.kotlinpoet.ksp.writeTo
|
|
||||||
import com.xyzshell.ksp_annotations.AutoBuilder
|
|
||||||
|
|
||||||
class AutoBuilderProcessor(
|
|
||||||
private val codeGenerator: CodeGenerator,
|
|
||||||
private val logger: KSPLogger
|
|
||||||
) : SymbolProcessor {
|
|
||||||
|
|
||||||
override fun process(resolver: Resolver): List<KSAnnotated> {
|
|
||||||
val symbols = resolver.getSymbolsWithAnnotation(AutoBuilder::class.qualifiedName!!)
|
|
||||||
val ret = symbols.filter { !it.validate() }.toList()
|
|
||||||
|
|
||||||
symbols
|
|
||||||
.filter { it is KSClassDeclaration && it.validate() }
|
|
||||||
.forEach { it ->
|
|
||||||
generateBuilderClass(it as KSClassDeclaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateBuilderClass(classDeclaration: KSClassDeclaration) {
|
|
||||||
val packageName = classDeclaration.containingFile!!.packageName.asString()
|
|
||||||
val className = classDeclaration.simpleName.asString()
|
|
||||||
val builderClassName = "${className}Builder"
|
|
||||||
|
|
||||||
logger.info("Generating builder for $className")
|
|
||||||
|
|
||||||
// 获取类的构造函数参数
|
|
||||||
val constructor = classDeclaration.primaryConstructor
|
|
||||||
if (constructor == null) {
|
|
||||||
logger.error("Class $className must have a primary constructor", classDeclaration)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val properties = constructor.parameters
|
|
||||||
|
|
||||||
// 创建Builder类
|
|
||||||
val builderClass = TypeSpec.classBuilder(builderClassName)
|
|
||||||
.addKdoc("Auto-generated builder for %L", className)
|
|
||||||
|
|
||||||
// 添加属性字段
|
|
||||||
properties.forEach { param ->
|
|
||||||
val paramName = param.name!!.asString()
|
|
||||||
val paramType = param.type.resolve()
|
|
||||||
val typeName = paramType.toClassName()
|
|
||||||
|
|
||||||
builderClass.addProperty(
|
|
||||||
PropertySpec.builder(paramName, typeName.copy(nullable = true))
|
|
||||||
.mutable()
|
|
||||||
.initializer("null")
|
|
||||||
.addModifiers(KModifier.PRIVATE)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加setter方法
|
|
||||||
properties.forEach { param ->
|
|
||||||
val paramName = param.name!!.asString()
|
|
||||||
val paramType = param.type.resolve()
|
|
||||||
val typeName = paramType.toClassName()
|
|
||||||
|
|
||||||
val setterMethod = FunSpec.builder(paramName)
|
|
||||||
.addParameter(paramName, typeName)
|
|
||||||
.returns(ClassName(packageName, builderClassName))
|
|
||||||
.addStatement("this.%L = %L", paramName, paramName)
|
|
||||||
.addStatement("return this")
|
|
||||||
.build()
|
|
||||||
|
|
||||||
builderClass.addFunction(setterMethod)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加build方法
|
|
||||||
val buildMethod = FunSpec.builder("build")
|
|
||||||
.returns(ClassName(packageName, className))
|
|
||||||
.apply {
|
|
||||||
val paramNames = properties.map { it.name!!.asString() }
|
|
||||||
val paramChecks = paramNames.map { paramName ->
|
|
||||||
"checkNotNull($paramName) { \"$paramName must be set\" }"
|
|
||||||
}
|
|
||||||
|
|
||||||
addStatement(
|
|
||||||
"return %T(%L)",
|
|
||||||
ClassName(packageName, className),
|
|
||||||
paramChecks.joinToString(", ")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.build()
|
|
||||||
|
|
||||||
builderClass.addFunction(buildMethod)
|
|
||||||
|
|
||||||
// 添加静态工厂方法
|
|
||||||
val companionObject = TypeSpec.companionObjectBuilder()
|
|
||||||
.addFunction(
|
|
||||||
FunSpec.builder("builder")
|
|
||||||
.returns(ClassName(packageName, builderClassName))
|
|
||||||
.addStatement("return %T()", ClassName(packageName, builderClassName))
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
builderClass.addType(companionObject)
|
|
||||||
|
|
||||||
// 生成文件
|
|
||||||
val file = FileSpec.builder(packageName, builderClassName)
|
|
||||||
.addType(builderClass.build())
|
|
||||||
.build()
|
|
||||||
|
|
||||||
file.writeTo(codeGenerator, Dependencies(true, classDeclaration.containingFile!!))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package com.xyzshell.ksp_processor
|
|
||||||
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessor
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
|
|
||||||
import com.google.devtools.ksp.processing.SymbolProcessorProvider
|
|
||||||
|
|
||||||
class AutoBuilderProcessorProvider : SymbolProcessorProvider {
|
|
||||||
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
|
|
||||||
return AutoBuilderProcessor(
|
|
||||||
codeGenerator = environment.codeGenerator,
|
|
||||||
logger = environment.logger
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
com.xyzshell.ksp_processor.AutoBuilderProcessorProvider
|
|
||||||
1
mydev/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/build
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
plugins {
|
|
||||||
alias(libs.plugins.android.application)
|
|
||||||
alias(libs.plugins.kotlin.android)
|
|
||||||
alias(libs.plugins.compose.compiler)
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
namespace = "com.xyzshell.mydev"
|
|
||||||
compileSdk = 35
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
applicationId = "com.xyzshell.mydev"
|
|
||||||
minSdk = 29
|
|
||||||
//noinspection OldTargetApi
|
|
||||||
targetSdk = 35
|
|
||||||
versionCode = 1
|
|
||||||
versionName = "1.0"
|
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
isMinifyEnabled = false
|
|
||||||
proguardFiles(
|
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
buildFeatures {
|
|
||||||
compose = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
|
|
||||||
implementation(libs.androidx.core.ktx)
|
|
||||||
implementation(libs.androidx.appcompat)
|
|
||||||
implementation(libs.material)
|
|
||||||
implementation(libs.androidx.runtime.android)
|
|
||||||
implementation(libs.androidx.ui.tooling.preview.android)
|
|
||||||
implementation(libs.androidx.ui)
|
|
||||||
implementation(libs.androidx.foundation)
|
|
||||||
implementation(libs.androidx.ui.tooling.preview)
|
|
||||||
implementation(libs.androidx.material3.android)
|
|
||||||
implementation(libs.adaptive)
|
|
||||||
implementation(libs.androidx.adaptive.layout)
|
|
||||||
implementation(libs.androidx.adaptive.navigation)
|
|
||||||
implementation(libs.play.services.ads.identifier)
|
|
||||||
implementation(libs.play.services.appset)
|
|
||||||
implementation(libs.kotlinx.serialization.json)
|
|
||||||
implementation(libs.accompanist.systemuicontroller)
|
|
||||||
implementation(libs.protobuf.java)
|
|
||||||
debugImplementation(libs.androidx.ui.tooling)
|
|
||||||
testImplementation(libs.junit)
|
|
||||||
|
|
||||||
implementation(libs.androidx.material.icons.core)
|
|
||||||
// Optional - Add full set of material icons
|
|
||||||
implementation(libs.androidx.material.icons.extended)
|
|
||||||
// Optional - Add window size utils
|
|
||||||
implementation(libs.androidx.adaptive)
|
|
||||||
|
|
||||||
// Optional - Integration with activities
|
|
||||||
implementation(libs.androidx.activity.compose)
|
|
||||||
// Optional - Integration with ViewModels
|
|
||||||
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
|
||||||
// Optional - Integration with LiveData
|
|
||||||
implementation(libs.androidx.runtime.livedata)
|
|
||||||
// Optional - Integration with RxJava
|
|
||||||
implementation(libs.androidx.runtime.rxjava2)
|
|
||||||
|
|
||||||
androidTestImplementation(libs.androidx.junit)
|
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
|
||||||
}
|
|
||||||
21
mydev/proguard-rules.pro
vendored
@ -1,21 +0,0 @@
|
|||||||
# Add project specific ProGuard rules here.
|
|
||||||
# You can control the set of applied configuration files using the
|
|
||||||
# proguardFiles setting in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
|
||||||
# debugging stack traces.
|
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
|
||||||
# hide the original source file name.
|
|
||||||
#-renamesourcefileattribute SourceFile
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package com.xyzshell.mydev
|
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
fun useAppContext() {
|
|
||||||
// Context of the app under test.
|
|
||||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
|
||||||
assertEquals("com.xyzshell.mydev", appContext.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
|
|
||||||
tools:ignore="ProtectedPermissions" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
|
||||||
<application
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/Theme.MyAndriodInfo">
|
|
||||||
<activity
|
|
||||||
android:name=".MainActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity android:name=".ViewBrowseActivity"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
<data android:scheme="javascript" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package com.xyzshell.mydev
|
|
||||||
|
|
||||||
// 数据类
|
|
||||||
typealias Callback = () -> String
|
|
||||||
data class InfoItem(
|
|
||||||
val propertyName: String,
|
|
||||||
val propertyValue: String,
|
|
||||||
val callback: Callback? = null
|
|
||||||
)
|
|
||||||
@ -1,450 +0,0 @@
|
|||||||
package com.xyzshell.mydev
|
|
||||||
|
|
||||||
import android.adservices.AdServicesState
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.ActivityManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.IntentFilter
|
|
||||||
import android.content.pm.ApplicationInfo
|
|
||||||
import android.content.pm.PackageInfo
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.graphics.Rect
|
|
||||||
import android.hardware.Sensor
|
|
||||||
import android.hardware.SensorManager
|
|
||||||
import android.media.AudioManager
|
|
||||||
import android.net.ConnectivityManager
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Environment
|
|
||||||
import android.os.PowerManager
|
|
||||||
import android.os.Process
|
|
||||||
import android.os.SystemClock
|
|
||||||
import android.os.ext.SdkExtensions
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.telephony.TelephonyManager
|
|
||||||
import android.util.DisplayMetrics
|
|
||||||
import android.view.RoundedCorner
|
|
||||||
import android.view.WindowManager
|
|
||||||
import androidx.annotation.RequiresExtension
|
|
||||||
import com.google.android.gms.ads.identifier.AdvertisingIdClient
|
|
||||||
import com.google.android.gms.appset.AppSet
|
|
||||||
import com.google.android.gms.appset.AppSetIdClient
|
|
||||||
import com.google.android.gms.appset.AppSetIdInfo
|
|
||||||
import com.google.android.gms.tasks.Task
|
|
||||||
import com.xyzshell.mydev.data.SystemPropKeys
|
|
||||||
import com.xyzshell.mydev.utils.DeviceInfo
|
|
||||||
import com.xyzshell.mydev.utils.MemoryInfoType
|
|
||||||
import java.io.BufferedReader
|
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
import java.io.InputStreamReader
|
|
||||||
import java.net.NetworkInterface
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
import java.util.TimeZone
|
|
||||||
import java.util.concurrent.Executors
|
|
||||||
|
|
||||||
|
|
||||||
class InfoData(private val context:Context) {
|
|
||||||
|
|
||||||
private val activityManager: ActivityManager = this.context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
|
||||||
private val connectivityManager = this.context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
|
||||||
private val packageManager: PackageManager = this.context.packageManager
|
|
||||||
private val applicationInfo: ApplicationInfo = this.context.applicationInfo
|
|
||||||
private val audioManager: AudioManager = this.context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
||||||
|
|
||||||
private val windowManager = this.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
|
||||||
private val telephonyManager = this.context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
|
||||||
private val packageInfo: PackageInfo =
|
|
||||||
this.packageManager.getPackageInfo(this.context.packageName,0)
|
|
||||||
private val powerManager = this.context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
|
||||||
|
|
||||||
private fun getStr(obj: Any) : String {
|
|
||||||
var info = ""
|
|
||||||
if(obj!=null) {
|
|
||||||
info = if (obj is Array<*>) {
|
|
||||||
obj.joinToString(",")
|
|
||||||
} else {
|
|
||||||
obj.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
fun getInfo(): List<InfoItem> {
|
|
||||||
val cls = Class.forName("android.os.SystemProperties")
|
|
||||||
val method = cls.getMethod("get", String::class.java)
|
|
||||||
val infos = mutableListOf<InfoItem>()
|
|
||||||
SystemPropKeys.forEach { k ->
|
|
||||||
method.invoke(null, k)?.let {
|
|
||||||
infos.add(InfoItem(k, getStr(it)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return infos
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getPropInfo(): List<InfoItem> {
|
|
||||||
val reg = Regex("^\\[(.+)].+\\[(.+)]$")
|
|
||||||
val res = mutableListOf<InfoItem>()
|
|
||||||
try {
|
|
||||||
val process: java.lang.Process? = Runtime.getRuntime().exec("getprop")
|
|
||||||
if(process!=null) {
|
|
||||||
val reader = BufferedReader(InputStreamReader(process.inputStream))
|
|
||||||
var line: String?
|
|
||||||
while ((reader.readLine().also { line = it }) != null) {
|
|
||||||
val a = reg.find(line!!)?.groupValues
|
|
||||||
if(a!=null && a.size == 3) {
|
|
||||||
res.add(InfoItem(a[1], a[2]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
private val allInfos = mutableMapOf<String,InfoItem>()
|
|
||||||
private fun setMkv(k: String, name: String, value: Any) {
|
|
||||||
allInfos[k] = InfoItem(name, value.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setAppInfo() {
|
|
||||||
val v = packageManager.getApplicationLabel(applicationInfo)
|
|
||||||
var install_name = packageManager.getInstallerPackageName(applicationInfo.packageName)
|
|
||||||
if(install_name == null) {
|
|
||||||
install_name = ""
|
|
||||||
}
|
|
||||||
setMkv("app_name", "App Name", v)
|
|
||||||
setMkv("install_name", "install name", install_name)
|
|
||||||
this.packageInfo.versionName?.let { setMkv("app_version", "Version Name", it) }
|
|
||||||
setMkv("app_version_code", "Version Code", this.packageInfo.versionCode)
|
|
||||||
setMkv("firstInstallTime", "安装时间", this.packageInfo.firstInstallTime)
|
|
||||||
setMkv("package_name", "Package Name", applicationInfo.packageName)
|
|
||||||
setMkv("target_sdk", "Target SDK", applicationInfo.targetSdkVersion)
|
|
||||||
setMkv("idfv", "idfv", "")
|
|
||||||
setMkv("idfv_scope", "idfv scope", -1)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setFsLm() {
|
|
||||||
val v = File(applicationInfo.sourceDir).lastModified()
|
|
||||||
setMkv("fslm", "app安装文件时间", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setPermissionInfo() {
|
|
||||||
val ps_tpg = checkPermission("android.permission.ACCESS_ADSERVICES_TOPICS")
|
|
||||||
setMkv("ps_tpg","允许应用访问用户的兴趣话题信息", ps_tpg)
|
|
||||||
val ps_apg = checkPermission("android.permission.ACCESS_ADSERVICES_ATTRIBUTION")
|
|
||||||
setMkv("ps_apg", "广告归因追踪", ps_apg)
|
|
||||||
var ps_aipg = checkPermission("android.permission.ACCESS_ADSERVICES_AD_ID")
|
|
||||||
setMkv("ps_aipg", "广告ID访问", ps_aipg)
|
|
||||||
val ps_capg = checkPermission("android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE")
|
|
||||||
setMkv("ps_capg", "允许应用创建和管理自定义广告受众群体",ps_capg)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNetworkInfo() {
|
|
||||||
setMkv("connectivity", "网络状态",
|
|
||||||
connectivityManager.restrictBackgroundStatus != ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
val interfaces = NetworkInterface.getNetworkInterfaces()
|
|
||||||
if (interfaces != null) {
|
|
||||||
for (intf in interfaces) {
|
|
||||||
try {
|
|
||||||
if (!intf.isUp || intf.isLoopback) continue
|
|
||||||
sb.append("name: ${intf.name}, displayName: ${intf.displayName},")
|
|
||||||
val addresses = intf.inetAddresses
|
|
||||||
for (addr in addresses) {
|
|
||||||
sb.append("address: ${addr.hostAddress}\n")
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setMkv("NetworkInterface", "网络状态", sb.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun setFont() {
|
|
||||||
setMkv("font_scale", "Font Scale", Settings.System.getFloat(this.context.contentResolver,"font_scale"))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setLocal() {
|
|
||||||
setMkv("tz", "TimeZone",
|
|
||||||
Math.round(TimeZone.getDefault().getOffset(Date().time) * 10.0 / 3600000.0) / 10.0)
|
|
||||||
setMkv("tz_offset", "tz_offset",Math.round(
|
|
||||||
TimeZone.getDefault().getOffset(
|
|
||||||
Date().time
|
|
||||||
) * 10.0 / 3600000.0
|
|
||||||
) / 10.0)
|
|
||||||
setMkv("local","local", Locale.getDefault().toString())
|
|
||||||
val localeList = this.context.resources.configuration.locales
|
|
||||||
val stringBuilder = StringBuilder()
|
|
||||||
for (i in 0 until localeList.size()) {
|
|
||||||
val locale = localeList.get(i)
|
|
||||||
stringBuilder.append("Locale: ${locale.toString()}, Language: ${locale.language}, Country: ${locale.country}\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
setMkv("local_list", "Locale List", stringBuilder.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setScreen() {
|
|
||||||
val screen_brightness = Settings.System.getInt(this.context.contentResolver, Settings.System.SCREEN_BRIGHTNESS) / 255.0F * 100.0F
|
|
||||||
setMkv("screen_brightness","屏幕亮度", screen_brightness)
|
|
||||||
setMkv("screen_orientation", "屏幕方向", this.context.resources.configuration.orientation)
|
|
||||||
|
|
||||||
val rect = Rect()
|
|
||||||
windowManager.defaultDisplay.getRectSize(rect)
|
|
||||||
val displayMetrics = DisplayMetrics()
|
|
||||||
windowManager.defaultDisplay.getMetrics(displayMetrics)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
sb.append("w:${rect.width()},h:${rect.height()}\n")
|
|
||||||
sb.append("W:${displayMetrics.widthPixels},H: ${displayMetrics.heightPixels}\n")
|
|
||||||
sb.append("density:${displayMetrics.density}\n")
|
|
||||||
sb.append("densityDpi:${displayMetrics.densityDpi}\n")
|
|
||||||
sb.append("xdpi:${displayMetrics.xdpi},ydpi:${displayMetrics.ydpi}\n")
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
||||||
sb.append("tl${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT)}\n")
|
|
||||||
sb.append("tr${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT)}\n")
|
|
||||||
sb.append("bl${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT)}\n")
|
|
||||||
sb.append("br${windowManager.defaultDisplay.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT)}\n")
|
|
||||||
}
|
|
||||||
setMkv("screen", "屏幕", sb.toString())
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setDisk() {
|
|
||||||
setMkv("disk_free","磁盘剩余", Environment.getDataDirectory().freeSpace)
|
|
||||||
setMkv("disk_total", "磁盘", Environment.getDataDirectory().totalSpace)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun getProcessName():String {
|
|
||||||
try {
|
|
||||||
val packageManager = context.packageManager
|
|
||||||
val applicationInfo = packageManager.getApplicationInfo(
|
|
||||||
context.packageName,
|
|
||||||
PackageManager.GET_META_DATA // 0x80
|
|
||||||
)
|
|
||||||
val metaData = applicationInfo.metaData
|
|
||||||
|
|
||||||
try {
|
|
||||||
val processName = applicationInfo.processName
|
|
||||||
return processName
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
fun getProcessName1():String {
|
|
||||||
val pid = Process.myPid()
|
|
||||||
val activityManager = this.context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
|
||||||
val runningManager = activityManager.runningAppProcesses
|
|
||||||
runningManager?.forEach {
|
|
||||||
if(it.pid == pid) {
|
|
||||||
return it.processName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSystem() {
|
|
||||||
setMkv("pc", "Processors", Runtime.getRuntime().availableProcessors())
|
|
||||||
setMkv("boot_ms","bt_ms", System.currentTimeMillis() - SystemClock.elapsedRealtime())
|
|
||||||
setMkv("processName1", "Process Name", getProcessName())
|
|
||||||
setMkv("processName2", "Process Name 1", getProcessName1())
|
|
||||||
val b1 = packageManager.hasSystemFeature("com.google.android.play.feature.HPE_EXPERIENCE")
|
|
||||||
val b2 = packageManager.hasSystemFeature(PackageManager.FEATURE_PC)
|
|
||||||
val kb = this.context.resources.configuration.keyboard
|
|
||||||
var is_pc = true
|
|
||||||
if(kb != Configuration.KEYBOARD_QWERTY || (!b1 && !b2)) {
|
|
||||||
is_pc = false
|
|
||||||
}
|
|
||||||
setMkv("is_pc", "is pc", is_pc)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setMem() {
|
|
||||||
val memoryInfo = ActivityManager.MemoryInfo()
|
|
||||||
activityManager.getMemoryInfo(memoryInfo)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
setMkv("availMem", "可用内存", memoryInfo.availMem)
|
|
||||||
setMkv("totalMem", "总内存", memoryInfo.totalMem)
|
|
||||||
setMkv("threshold", "threshold", memoryInfo.threshold)
|
|
||||||
setMkv("lowMemory", "lowMemory", memoryInfo.lowMemory)
|
|
||||||
setMkv("GlEsVersion", "GlEsVersion", activityManager.deviceConfigurationInfo.glEsVersion)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSensor() {
|
|
||||||
val sensorManager = this.context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
|
||||||
val isGYROSCOPE = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) != null
|
|
||||||
setMkv("isGYROSCOPE","陀螺仪", isGYROSCOPE)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun setBatteryInfo() {
|
|
||||||
val intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
|
||||||
val intent = this.context.registerReceiver(null, intentFilter)
|
|
||||||
var level = -1
|
|
||||||
var scale = -1
|
|
||||||
var adn = -1
|
|
||||||
var status = -1
|
|
||||||
if(intent!=null) {
|
|
||||||
level = intent.getIntExtra("level", -1)
|
|
||||||
setMkv("battery_level", "电池Level", level)
|
|
||||||
scale = intent.getIntExtra("scale", -1)
|
|
||||||
setMkv("battery_scale", "电池scale", scale)
|
|
||||||
if(level > 0 && scale > 0) {
|
|
||||||
adn = (((level.toFloat() / scale.toFloat()) * 100.0F).toInt())
|
|
||||||
setMkv("battery_adn", "电池adn", adn)
|
|
||||||
}
|
|
||||||
status = intent.getIntExtra("status", -1)
|
|
||||||
setMkv("battery_status", "电池状态", status)
|
|
||||||
}
|
|
||||||
var plugged = false
|
|
||||||
if(intent != null) {
|
|
||||||
// stay_on_while_plugged_in
|
|
||||||
val plugged1:Int = intent.getIntExtra("plugged", -1)
|
|
||||||
if(plugged1 > 0) {
|
|
||||||
plugged = true
|
|
||||||
}
|
|
||||||
setMkv("battery_plugged", "电池充电", plugged)
|
|
||||||
}
|
|
||||||
setMkv("isPowerSaveMode", "Power Save Mode", powerManager.isPowerSaveMode)
|
|
||||||
// setMkv("sowpie","插电模式:sowpie", Settings.Global.getInt(this.context.contentResolver, "stay_on_while_plugged_in", -1) > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun setAudio() {
|
|
||||||
setMkv("MusicActive", "MusicActive", audioManager.isMusicActive)
|
|
||||||
setMkv("volume", "volume", audioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
|
|
||||||
setMkv("SpeakerphoneOn","SpeakerphoneOn", audioManager.isSpeakerphoneOn)
|
|
||||||
setMkv("ringerMode", "ringerMode", audioManager.ringerMode)
|
|
||||||
val sb = StringBuilder()
|
|
||||||
val arrayOfAudioDeviceInfo = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
||||||
for (i in arrayOfAudioDeviceInfo.indices) {
|
|
||||||
val audioDeviceInfo = arrayOfAudioDeviceInfo[i]
|
|
||||||
if (audioDeviceInfo != null) {
|
|
||||||
// 3,7,8
|
|
||||||
// public static final int TYPE_BLUETOOTH_A2DP = 8;
|
|
||||||
// public static final int TYPE_BLUETOOTH_SCO = 7;
|
|
||||||
// public static final int TYPE_WIRED_HEADSET = 3;
|
|
||||||
sb.append("name: " + audioDeviceInfo.productName + ", type: " + audioDeviceInfo.type + "\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append("isWiredHeadsetOn:${audioManager.isWiredHeadsetOn()}\n")
|
|
||||||
sb.append("isBluetoothScoOn:${audioManager.isBluetoothScoOn()}\n")
|
|
||||||
sb.append("isBluetoothA2dpOn:${audioManager.isBluetoothA2dpOn()}\n")
|
|
||||||
setMkv("AudioDeviceInfo", "AudioDeviceInfo", sb.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("HardwareIds")
|
|
||||||
fun setPhoneInfo() {
|
|
||||||
setMkv("simCountryIso","Country Iso",telephonyManager.simCountryIso.toUpperCase(Locale.ENGLISH))
|
|
||||||
setMkv("NetworkOperatorName","NetworkOperatorName",telephonyManager.networkOperatorName)
|
|
||||||
setMkv("NetworkOperator","NetworkOperator",telephonyManager.networkOperator)
|
|
||||||
var manufacturerCode = ""
|
|
||||||
if (!telephonyManager.manufacturerCode.isNullOrEmpty()) {
|
|
||||||
manufacturerCode = telephonyManager.manufacturerCode.toString()
|
|
||||||
}
|
|
||||||
setMkv("ManufacturerCode","ManufacturerCode",manufacturerCode)
|
|
||||||
try {
|
|
||||||
// setMkv("tel_deviceId","Telephony DeviceId",telephonyManager.getDeviceId())
|
|
||||||
}catch (e:Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun checkPermission(key:String):Boolean {
|
|
||||||
return this.context.packageManager.checkPermission(key,this.context.packageName) == PackageManager.PERMISSION_GRANTED
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GetAppInfo() {
|
|
||||||
setAppInfo()
|
|
||||||
setFsLm()
|
|
||||||
setPermissionInfo()
|
|
||||||
setSystem()
|
|
||||||
setMem()
|
|
||||||
setNetworkInfo()
|
|
||||||
setFont()
|
|
||||||
setLocal()
|
|
||||||
setScreen()
|
|
||||||
setDisk()
|
|
||||||
setPhoneInfo()
|
|
||||||
setAudio()
|
|
||||||
setBatteryInfo()
|
|
||||||
setSensor()
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && SdkExtensions.getExtensionVersion(
|
|
||||||
SdkExtensions.AD_SERVICES) >= 4) {
|
|
||||||
setAD_SERVICES()
|
|
||||||
}
|
|
||||||
initAdid()
|
|
||||||
}
|
|
||||||
|
|
||||||
val AllInfos get() = allInfos.values.toList()
|
|
||||||
|
|
||||||
@RequiresExtension(extension = SdkExtensions.AD_SERVICES, version = 4)
|
|
||||||
fun setAD_SERVICES() {
|
|
||||||
val v = AdServicesState.isAdServicesStateEnabled()
|
|
||||||
setMkv("isAdServicesStateEnabled", "Android Ad Services",v )
|
|
||||||
}
|
|
||||||
|
|
||||||
fun initAdid() {
|
|
||||||
setMkv("adid", "Ad Id", "")
|
|
||||||
setMkv("ApiLevel", "ApiLevel", DeviceInfo.instance.ApiLevel)
|
|
||||||
setMkv("ApkDigest", "ApkDigest", DeviceInfo.instance.ApkDigest)
|
|
||||||
setMkv("ApkDigestSize", "ApkDigestSize", DeviceInfo.instance.ApkDigestSize)
|
|
||||||
setMkv("ApkDigestTimeout", "ApkDigestTimeout", DeviceInfo.instance.ApkDigestTimeout)
|
|
||||||
setMkv("TimeZone1", "TimeZone", TimeZone.getDefault().id)
|
|
||||||
DeviceInfo.instance.getMemoryInfo(MemoryInfoType.FREE_MEMORY)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun loadAsyncData(onUpdate: (List<InfoItem>) -> Unit) {
|
|
||||||
DeviceInfo.instance.onAdInit {
|
|
||||||
allInfos["GAID"] = InfoItem("GAID",DeviceInfo.instance.AdvertisingTrackingId)
|
|
||||||
allInfos["LimitedAdTracking"] = InfoItem("LimitedAdTracking",DeviceInfo.instance.LimitedAdTracking.toString())
|
|
||||||
onUpdate(allInfos.values.toList())
|
|
||||||
}
|
|
||||||
Executors.newSingleThreadExecutor().execute {
|
|
||||||
try {
|
|
||||||
val adid = AdvertisingIdClient(this.context).info
|
|
||||||
if (adid.id != null) {
|
|
||||||
allInfos["adid"] = InfoItem("Ad Id", adid.id!!)
|
|
||||||
}
|
|
||||||
DeviceInfo.instance.getApkDigest()
|
|
||||||
setMkv("ApkDigest", "ApkDigest", DeviceInfo.instance.ApkDigest)
|
|
||||||
setMkv("ApkDigestSize", "ApkDigestSize", DeviceInfo.instance.ApkDigestSize)
|
|
||||||
setMkv("ApkDigestTimeout", "ApkDigestTimeout", DeviceInfo.instance.ApkDigestTimeout)
|
|
||||||
setMkv( "CertificateFingerprint", "CertificateFingerprint", DeviceInfo.instance.getCertificateFingerprint())
|
|
||||||
setMkv( "connectionType", "connectionType", DeviceInfo.instance.getConnectionType())
|
|
||||||
onUpdate(allInfos.values.toList())
|
|
||||||
|
|
||||||
} catch (e: java.lang.Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val client = AppSet.getClient(this.context) as AppSetIdClient
|
|
||||||
val task: Task<AppSetIdInfo> = client.appSetIdInfo as Task<AppSetIdInfo>
|
|
||||||
task.addOnSuccessListener {
|
|
||||||
// Determine current scope of app set ID.
|
|
||||||
val scope: Int = it.scope
|
|
||||||
|
|
||||||
// Read app set ID value, which uses version 4 of the
|
|
||||||
// universally unique identifier (UUID) format.
|
|
||||||
val id: String = it.id
|
|
||||||
allInfos["idfv"] = InfoItem("idfv", it.id)
|
|
||||||
allInfos["idfv_scope"] = InfoItem("idfv_scope", it.scope.toString())
|
|
||||||
onUpdate(allInfos.values.toList())
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,294 +0,0 @@
|
|||||||
package com.xyzshell.mydev
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.setContent
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.HorizontalDivider
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.compose.ui.unit.times
|
|
||||||
import com.xyzshell.mydev.utils.DeviceInfo
|
|
||||||
import com.xyzshell.mydev.utils.ProtobufExtensionsKt
|
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
|
||||||
private lateinit var infos:InfoData
|
|
||||||
@SuppressLint("QueryPermissionsNeeded")
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
val isAndroid15 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM //VANILLA_ICE_CREAM是35
|
|
||||||
DeviceInfo.instance.init(this.applicationContext)
|
|
||||||
infos = InfoData(this.applicationContext)
|
|
||||||
val t = ProtobufExtensionsKt().fromBase64("EpoDEpcDfMK7VlzA4rkFO61o03LOZRMV3qg-q6xuwRLaqgLASA0AHNCtUXZcIPszSRkfJ2lql3TMcvAd4ug3C1Q_TsDU5R3jV_d4ms0pCu2e9xao_zX8StWgFqGpM2v_k7hWK3tmN8r3T9tPW0qgX4yPA6dsssCyaS8IggHTaijlVJZ4afGfgh9tcASLnmBoQY5ivNpkAUyLCEvMk4ZdQa7j4MqukZi82g6WmIqPLVaS-UEZXSVLuymI8cyT9aIHZQjeQVH8xqE_LbtGw5kl_jK7oo7W7abwh8qWvyubA1x0IILG1ArfMjdTc9jZDiLl0cTFy8PkiKhnyaE9sO8_vmyMWl4h6aW2ZwoTnPnwn24WROcqktXcCIk2X1ToLTOGxnL8cDD6AH7V25dLYt41GgttM-9DcQchxJ_fRJaDOJ0UtHXSAFnlQbEVs5yWD8CNbR2SzFW7AJnmrf4bRfLzThn4m_c28T3qUuBHkCKrXxOvE1K2fLWcaQ41i4OR8xrwEZr-iSgNrVqr2obs54cb7g0blXiIZIDRoAhD5sU=",true)
|
|
||||||
val t1 = ProtobufExtensionsKt().toUUID(t)
|
|
||||||
setContent {
|
|
||||||
MaterialTheme {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.verticalScroll(rememberScrollState())
|
|
||||||
.fillMaxWidth().statusBarsPadding().navigationBarsPadding(),
|
|
||||||
) {
|
|
||||||
Spacer(modifier = Modifier.height(36.dp))
|
|
||||||
Button({
|
|
||||||
val uri = Uri.parse("https://uutool.cn/ua/")
|
|
||||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
|
||||||
//intent.setClass(this@MainActivity, ViewBrowseActivity::class.java)
|
|
||||||
//intent.setData(uri)
|
|
||||||
//intent.addCategory(Intent.CATEGORY_BROWSABLE)
|
|
||||||
//startActivity(intent)
|
|
||||||
//intent.setPackage("com.android.chrome")
|
|
||||||
//startActivity(intent)
|
|
||||||
startActivity(Intent.createChooser(intent, "选择浏览器"))
|
|
||||||
if (intent.resolveActivity(packageManager) != null) {
|
|
||||||
startActivity(intent)
|
|
||||||
} else {
|
|
||||||
// 如果没有浏览器应用可用,显示一个提示
|
|
||||||
Log.i("App Info","没有可用的浏览器应用")
|
|
||||||
}
|
|
||||||
}) { Text("查看浏览器UserAgent") }
|
|
||||||
Row(Modifier.padding(10.dp)) {
|
|
||||||
TextField("", onValueChange = {
|
|
||||||
|
|
||||||
}, Modifier.fillMaxWidth().padding(1.dp), placeholder = {Text("输入名称")})
|
|
||||||
}
|
|
||||||
BaseInfo(infos)
|
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
|
||||||
BuildInfo()
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
BuildVerInfo()
|
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
|
||||||
BuildVerCodiInfo()
|
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
|
||||||
SystemPropInfo(infos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BaseInfo(infoData: InfoData) {
|
|
||||||
infoData.GetAppInfo()
|
|
||||||
var stateData by remember { mutableStateOf(infoData.AllInfos) }
|
|
||||||
// 模拟异步数据加载
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
infoData.loadAsyncData { updatedItems ->
|
|
||||||
stateData = updatedItems
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InfoBox("基本信息", stateData)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SystemPropInfo(infoData: InfoData) {
|
|
||||||
val infos = infoData.getPropInfo()
|
|
||||||
InfoBox("System Properties", infos)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BuildInfo() {
|
|
||||||
val buildCls = Build::class.java
|
|
||||||
val fi = buildCls.declaredFields
|
|
||||||
val infos = mutableListOf<InfoItem>()
|
|
||||||
for (it in fi) {
|
|
||||||
val obj = it.get(null)
|
|
||||||
val info = getStr(obj)
|
|
||||||
infos.add(InfoItem(it.name, info))
|
|
||||||
}
|
|
||||||
InfoBox("Build Info", infos)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BuildVerInfo() {
|
|
||||||
val buildVerCLs = Build.VERSION::class.java
|
|
||||||
val vfi = buildVerCLs.declaredFields
|
|
||||||
val infos = mutableListOf<InfoItem>()
|
|
||||||
for (it in vfi) {
|
|
||||||
val obj =it.get(null)
|
|
||||||
val info = getStr(obj)
|
|
||||||
infos.add(InfoItem(it.name, info))
|
|
||||||
}
|
|
||||||
InfoBox("Build Ver Info", infos)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BuildVerCodiInfo() {
|
|
||||||
val buildVerCode = Build.VERSION_CODES::class.java
|
|
||||||
val vcfi = buildVerCode.declaredFields
|
|
||||||
val infos = mutableListOf<InfoItem>()
|
|
||||||
for (it in vcfi) {
|
|
||||||
val obj =it.get(null)
|
|
||||||
val info = getStr(obj)
|
|
||||||
infos.add(InfoItem(it.name, info))
|
|
||||||
}
|
|
||||||
InfoBox("Build Ver Code Info", infos)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getStr(obj: Any) : String {
|
|
||||||
var info = ""
|
|
||||||
if(obj!=null) {
|
|
||||||
info = if (obj is Array<*>) {
|
|
||||||
obj.joinToString(",")
|
|
||||||
} else {
|
|
||||||
obj.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
@Composable
|
|
||||||
fun InfoBox(title:String,infoItems: List<InfoItem>) {
|
|
||||||
Column {
|
|
||||||
Text(title, modifier = Modifier.padding(16.dp))
|
|
||||||
HorizontalDivider(thickness = 2.dp)
|
|
||||||
InfoListScreen(infoItems)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun InfoListScreen(infoItems: List<InfoItem>) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(16.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
infoItems.forEach { item ->
|
|
||||||
BoxItem(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun BoxItem(item: InfoItem) {
|
|
||||||
Card() {
|
|
||||||
AdaptiveInfoLayoutWithMeasure(item = item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果你需要更精确的测量,可以使用这个版本
|
|
||||||
@SuppressLint("UnusedBoxWithConstraintsScope")
|
|
||||||
@Composable
|
|
||||||
fun AdaptiveInfoLayoutWithMeasure(item: InfoItem) {
|
|
||||||
var useVerticalLayout by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
BoxWithConstraints {
|
|
||||||
val maxWidth = maxWidth
|
|
||||||
val density = LocalDensity.current
|
|
||||||
|
|
||||||
// 简单的启发式判断:如果文本长度超过屏幕宽度的一半,使用垂直布局
|
|
||||||
val textWidth = with(density) {
|
|
||||||
item.propertyValue.length * 8.dp // 大概估算每个字符8dp宽度
|
|
||||||
}
|
|
||||||
|
|
||||||
useVerticalLayout = textWidth > maxWidth * 0.6f || item.propertyValue.length > 20
|
|
||||||
|
|
||||||
if (useVerticalLayout) {
|
|
||||||
// 垂直布局
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(16.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = item.propertyName,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
color = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = item.propertyValue,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
|
||||||
lineHeight = 20.sp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 水平布局
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(16.dp),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = item.propertyName,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
color = MaterialTheme.colorScheme.primary,
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = item.propertyValue,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
|
||||||
modifier = Modifier.weight(2f),
|
|
||||||
textAlign = TextAlign.End,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 预览
|
|
||||||
@Preview(showBackground = true)
|
|
||||||
@Composable
|
|
||||||
fun InfoListPreview() {
|
|
||||||
MaterialTheme {
|
|
||||||
// InfoListScreen()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package com.xyzshell.mydev
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
|
|
||||||
class ViewBrowseActivity: ComponentActivity() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package com.xyzshell.mydev
|
|
||||||
|
|
||||||
class ViewDataItem {
|
|
||||||
val name: String = ""
|
|
||||||
val value: String = ""
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package com.xyzshell.mydev.biz
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
|
|
||||||
|
|
||||||
class CollectData {
|
|
||||||
private val buildId: String get() = Build.ID
|
|
||||||
private val model: String get() = Build.MODEL
|
|
||||||
private val device: String get() = Build.DEVICE
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,184 +0,0 @@
|
|||||||
package com.xyzshell.mydev.data
|
|
||||||
|
|
||||||
data class AndroidInfo(
|
|
||||||
val id: String,
|
|
||||||
val device:DeviceInfo,
|
|
||||||
val system: SystemInfo
|
|
||||||
)
|
|
||||||
|
|
||||||
class DeviceInfo {
|
|
||||||
/**
|
|
||||||
* 设备型号
|
|
||||||
*/
|
|
||||||
val model: String = ""
|
|
||||||
|
|
||||||
// '产品名称'")
|
|
||||||
val product: String = ""
|
|
||||||
|
|
||||||
// '设备代号'")
|
|
||||||
val device: String = ""
|
|
||||||
|
|
||||||
// '主板名称'")
|
|
||||||
val board: String = ""
|
|
||||||
|
|
||||||
// '制造商'")
|
|
||||||
val manufacturer: String = ""
|
|
||||||
|
|
||||||
// '品牌'")
|
|
||||||
val brand: String = ""
|
|
||||||
|
|
||||||
// '硬件标识'")
|
|
||||||
val hardware: String = ""
|
|
||||||
|
|
||||||
// '认证用制造商'")
|
|
||||||
val manufacturerForAttestation: String = ""
|
|
||||||
|
|
||||||
// '产品代码'")
|
|
||||||
val productCode: String = ""
|
|
||||||
|
|
||||||
// '产品全名'")
|
|
||||||
val productFullName: String = ""
|
|
||||||
|
|
||||||
// '产品制造日期'")
|
|
||||||
val productMfgDate: String = ""
|
|
||||||
|
|
||||||
// CPU相关
|
|
||||||
// 'CPU架构'")
|
|
||||||
val cpuAbi: String = ""
|
|
||||||
|
|
||||||
// 'CPU核心数'")
|
|
||||||
val cpuCores: Int = 0
|
|
||||||
|
|
||||||
// '芯片名称'")
|
|
||||||
val chipName: String = ""
|
|
||||||
|
|
||||||
// 'SoC制造商'")
|
|
||||||
val socManufacturer: String = ""
|
|
||||||
|
|
||||||
// 'SoC型号'")
|
|
||||||
val socModel: String = ""
|
|
||||||
|
|
||||||
// '主板平台'")
|
|
||||||
val boardPlatform: String = ""
|
|
||||||
|
|
||||||
// GPU相关
|
|
||||||
// 'GPU厂商'")
|
|
||||||
val gpuVendor: String = ""
|
|
||||||
|
|
||||||
// 'GPU型号'")
|
|
||||||
val gpuModel: String = ""
|
|
||||||
|
|
||||||
// 'GPU渲染器'")
|
|
||||||
val gpuRenderer: String = ""
|
|
||||||
|
|
||||||
// 'OpenGL版本'")
|
|
||||||
val openglVersion: String = ""
|
|
||||||
|
|
||||||
// 'OpenGL扩展'")
|
|
||||||
val openglExtensions: String = ""
|
|
||||||
|
|
||||||
// 'Vulkan版本'")
|
|
||||||
val vulkanVersion: String = ""
|
|
||||||
|
|
||||||
// 屏幕相关
|
|
||||||
// '屏幕宽度像素'")
|
|
||||||
val widthPixels: Int = 0
|
|
||||||
|
|
||||||
// '屏幕高度像素'")
|
|
||||||
val heightPixels: Int = 0
|
|
||||||
|
|
||||||
// '密度DPI'")
|
|
||||||
val densityDpi: Int = 0
|
|
||||||
|
|
||||||
// '物理DPI'")
|
|
||||||
val dpi: Int = 0
|
|
||||||
|
|
||||||
// 存储内存
|
|
||||||
// '总存储空间'")
|
|
||||||
val totalSpace: Long = 0
|
|
||||||
|
|
||||||
// '总内存'")
|
|
||||||
val totalMemory: Long = 0
|
|
||||||
|
|
||||||
// 基带相关
|
|
||||||
// '基带版本'")
|
|
||||||
val radio: String = ""
|
|
||||||
|
|
||||||
// 'RIL产品代码'")
|
|
||||||
val rilProductCode: String = ""
|
|
||||||
|
|
||||||
// 'RIL官方CSC版本'")
|
|
||||||
val rilOfficialCscver: String = ""
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class SystemInfo {
|
|
||||||
// 系统版本信息
|
|
||||||
// '发布版本,如Android 13, 14等'")
|
|
||||||
val orRelease: String = ""
|
|
||||||
|
|
||||||
// 'SDK版本整数'")
|
|
||||||
val sdkInt: Int= 0
|
|
||||||
|
|
||||||
// '代号,如TIRAMISU, UPSIDE_DOWN_CAKE等'")
|
|
||||||
val codename: String = ""
|
|
||||||
|
|
||||||
// '基础OS版本'")
|
|
||||||
val baseOs: String = ""
|
|
||||||
|
|
||||||
// '增量版本'")
|
|
||||||
val incremental: String = ""
|
|
||||||
|
|
||||||
// '安全补丁日期'")
|
|
||||||
val securityPatch: String = ""
|
|
||||||
|
|
||||||
// 构建信息
|
|
||||||
// '构建ID'")
|
|
||||||
val buildId: String = ""
|
|
||||||
|
|
||||||
// '系统指纹'")
|
|
||||||
val fingerprint: String = ""
|
|
||||||
|
|
||||||
// '显示版本'")
|
|
||||||
val display: String = ""
|
|
||||||
|
|
||||||
// '构建主机'")
|
|
||||||
val host: String = ""
|
|
||||||
|
|
||||||
// '构建标签'")
|
|
||||||
val tags: String = ""
|
|
||||||
|
|
||||||
// '构建类型,如user, userdebug等'")
|
|
||||||
val type: String = ""
|
|
||||||
|
|
||||||
// '构建用户'")
|
|
||||||
val user: String = ""
|
|
||||||
|
|
||||||
// '构建时间戳'")
|
|
||||||
val time: Long = 0
|
|
||||||
|
|
||||||
// 系统组件
|
|
||||||
// '引导程序版本'")
|
|
||||||
val bootloader: String = ""
|
|
||||||
|
|
||||||
// '内核版本'")
|
|
||||||
val kernelVersion: String = ""
|
|
||||||
|
|
||||||
// '厂商API版本'")
|
|
||||||
val vendorApi: Int = 0
|
|
||||||
|
|
||||||
// Google服务
|
|
||||||
// 'GSF ID'")
|
|
||||||
val gsfId: String = ""
|
|
||||||
|
|
||||||
// 'GMS版本'")
|
|
||||||
val gmsVersion: String = ""
|
|
||||||
|
|
||||||
// 系统标识
|
|
||||||
// 'Android ID'")
|
|
||||||
val androidId: String = ""
|
|
||||||
|
|
||||||
// '用户代理字符串'")
|
|
||||||
val userAgent: String = ""
|
|
||||||
}
|
|
||||||
@ -1,851 +0,0 @@
|
|||||||
package com.xyzshell.mydev.data
|
|
||||||
|
|
||||||
val SystemPropKeys = setOf(
|
|
||||||
"ro.product.system.brand",
|
|
||||||
"ro.product.system.device",
|
|
||||||
"ro.product.system.manufacturer",
|
|
||||||
"ro.product.system.model",
|
|
||||||
"ro.product.system.name",
|
|
||||||
"ro.system.product.cpu.abilist",
|
|
||||||
"ro.system.product.cpu.abilist32",
|
|
||||||
"ro.system.product.cpu.abilist64",
|
|
||||||
"ro.system.build.date",
|
|
||||||
"ro.system.build.date.utc",
|
|
||||||
"ro.system.build.fingerprint",
|
|
||||||
"ro.system.build.id",
|
|
||||||
"ro.system.build.tags",
|
|
||||||
"ro.system.build.type",
|
|
||||||
"ro.system.build.version.incremental",
|
|
||||||
"ro.system.build.version.release",
|
|
||||||
"ro.system.build.version.release_or_codename",
|
|
||||||
"ro.system.build.version.sdk",
|
|
||||||
"ro.system.build.version.sdk_minor",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.build.fingerprint",
|
|
||||||
"ro.build.id",
|
|
||||||
"ro.build.display.id",
|
|
||||||
"ro.build.version.incremental",
|
|
||||||
"ro.build.version.sdk",
|
|
||||||
"ro.build.version.sdk_minor",
|
|
||||||
"ro.build.version.preview_sdk",
|
|
||||||
"ro.build.version.preview_sdk_fingerprint",
|
|
||||||
"ro.build.version.codename",
|
|
||||||
"ro.build.version.all_codenames",
|
|
||||||
"ro.build.version.known_codenames",
|
|
||||||
"ro.build.version.release",
|
|
||||||
"ro.build.version.release_or_codename",
|
|
||||||
"ro.build.version.release_or_preview_display",
|
|
||||||
"ro.build.version.security_patch",
|
|
||||||
"ro.build.version.base_os",
|
|
||||||
"ro.build.version.min_supported_target_sdk",
|
|
||||||
"ro.build.date",
|
|
||||||
"ro.build.date.utc",
|
|
||||||
"ro.build.type",
|
|
||||||
"ro.build.user",
|
|
||||||
"ro.build.host",
|
|
||||||
"ro.build.tags",
|
|
||||||
"ro.build.flavor",
|
|
||||||
"ro.lineage.device",
|
|
||||||
|
|
||||||
|
|
||||||
"ro.product.cpu.abi",
|
|
||||||
"ro.product.locale",
|
|
||||||
"ro.wifi.channels",
|
|
||||||
|
|
||||||
"ro.build.product",
|
|
||||||
|
|
||||||
"ro.build.description",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.treble.enabled",
|
|
||||||
"ro.llndk.api_level",
|
|
||||||
"ro.actionable_compatible_property.enabled",
|
|
||||||
"persist.debug.dalvik.vm.core_platform_api_policy",
|
|
||||||
"ro.postinstall.fstab.prefix",
|
|
||||||
"ro.secure",
|
|
||||||
"security.perf_harden",
|
|
||||||
"ro.allow.mock.location",
|
|
||||||
"dalvik.vm.lockprof.threshold",
|
|
||||||
"ro.debuggable",
|
|
||||||
"net.bt.name",
|
|
||||||
"ro.force.debuggable",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"debug.atrace.tags.enableflags",
|
|
||||||
"persist.traced.enable",
|
|
||||||
"dalvik.vm.image-dex2oat-Xms",
|
|
||||||
"dalvik.vm.image-dex2oat-Xmx",
|
|
||||||
"dalvik.vm.dex2oat-Xms",
|
|
||||||
"dalvik.vm.dex2oat-Xmx",
|
|
||||||
"dalvik.vm.usejit",
|
|
||||||
"dalvik.vm.dexopt.secondary",
|
|
||||||
"dalvik.vm.dexopt.thermal-cutoff",
|
|
||||||
"dalvik.vm.appimageformat",
|
|
||||||
"ro.dalvik.vm.native.bridge",
|
|
||||||
"pm.dexopt.post-boot",
|
|
||||||
"pm.dexopt.first-boot",
|
|
||||||
"pm.dexopt.boot-after-ota",
|
|
||||||
"pm.dexopt.boot-after-mainline-update",
|
|
||||||
"pm.dexopt.install",
|
|
||||||
"pm.dexopt.install-fast",
|
|
||||||
"pm.dexopt.install-bulk",
|
|
||||||
"pm.dexopt.install-bulk-secondary",
|
|
||||||
"pm.dexopt.install-bulk-downgraded",
|
|
||||||
"pm.dexopt.install-bulk-secondary-downgraded",
|
|
||||||
"pm.dexopt.bg-dexopt",
|
|
||||||
"pm.dexopt.ab-ota",
|
|
||||||
"pm.dexopt.inactive",
|
|
||||||
"pm.dexopt.cmdline",
|
|
||||||
"pm.dexopt.shared",
|
|
||||||
"dalvik.vm.dex2oat-resolve-startup-strings",
|
|
||||||
"dalvik.vm.dex2oat-max-image-block-size",
|
|
||||||
"dalvik.vm.minidebuginfo",
|
|
||||||
"dalvik.vm.dex2oat-minidebuginfo",
|
|
||||||
"dalvik.vm.madvise.vdexfile.size",
|
|
||||||
"dalvik.vm.madvise.odexfile.size",
|
|
||||||
"dalvik.vm.madvise.artfile.size",
|
|
||||||
"dalvik.vm.usap_pool_enabled",
|
|
||||||
"dalvik.vm.usap_refill_threshold",
|
|
||||||
"dalvik.vm.usap_pool_size_max",
|
|
||||||
"dalvik.vm.usap_pool_size_min",
|
|
||||||
"dalvik.vm.usap_pool_refill_delay_ms",
|
|
||||||
"dalvik.vm.useartservice",
|
|
||||||
"dalvik.vm.enable_pr_dexopt",
|
|
||||||
"ro.cp_system_other_odex",
|
|
||||||
"ro.apex.updatable",
|
|
||||||
"ro.lineage.version",
|
|
||||||
"ro.lineage.display.version",
|
|
||||||
"ro.lineage.build.version",
|
|
||||||
"ro.lineage.releasetype",
|
|
||||||
"ro.lineagelegal.url",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.com.google.clientidbase",
|
|
||||||
"ro.adb.secure",
|
|
||||||
"persist.sys.strictmode.disable",
|
|
||||||
"ro.ota.allow_downgrade",
|
|
||||||
"ro.control_privapp_permissions",
|
|
||||||
"ro.storage_manager.enabled",
|
|
||||||
"dalvik.vm.systemuicompilerfilter",
|
|
||||||
"debug.sf.enable_transaction_tracing",
|
|
||||||
"media.recorder.show_manufacturer_and_model",
|
|
||||||
"net.tethering.noprovisioning",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.build.backported_fixes.alias_bitset.long_list",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.product.system.brand",
|
|
||||||
"ro.product.system.device",
|
|
||||||
"ro.product.system.manufacturer",
|
|
||||||
"ro.product.system.model",
|
|
||||||
"ro.product.system.name",
|
|
||||||
"ro.system.product.cpu.abilist",
|
|
||||||
"ro.system.product.cpu.abilist32",
|
|
||||||
"ro.system.product.cpu.abilist64",
|
|
||||||
"ro.system.build.date",
|
|
||||||
"ro.system.build.date.utc",
|
|
||||||
"ro.system.build.fingerprint",
|
|
||||||
"ro.system.build.id",
|
|
||||||
"ro.system.build.tags",
|
|
||||||
"ro.system.build.type",
|
|
||||||
"ro.system.build.version.incremental",
|
|
||||||
"ro.system.build.version.release",
|
|
||||||
"ro.system.build.version.release_or_codename",
|
|
||||||
"ro.system.build.version.sdk",
|
|
||||||
"ro.system.build.version.sdk_minor",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.build.fingerprint",
|
|
||||||
"ro.build.id",
|
|
||||||
"ro.build.display.id",
|
|
||||||
"ro.build.version.incremental",
|
|
||||||
"ro.build.version.sdk",
|
|
||||||
"ro.build.version.sdk_minor",
|
|
||||||
"ro.build.version.preview_sdk",
|
|
||||||
"ro.build.version.preview_sdk_fingerprint",
|
|
||||||
"ro.build.version.codename",
|
|
||||||
"ro.build.version.all_codenames",
|
|
||||||
"ro.build.version.known_codenames",
|
|
||||||
"ro.build.version.release",
|
|
||||||
"ro.build.version.release_or_codename",
|
|
||||||
"ro.build.version.release_or_preview_display",
|
|
||||||
"ro.build.version.security_patch",
|
|
||||||
"ro.build.version.base_os",
|
|
||||||
"ro.build.version.min_supported_target_sdk",
|
|
||||||
"ro.build.date",
|
|
||||||
"ro.build.date.utc",
|
|
||||||
"ro.build.type",
|
|
||||||
"ro.build.user",
|
|
||||||
"ro.build.host",
|
|
||||||
"ro.build.tags",
|
|
||||||
"ro.build.flavor",
|
|
||||||
"ro.lineage.device",
|
|
||||||
|
|
||||||
|
|
||||||
"ro.product.cpu.abi",
|
|
||||||
"ro.product.locale",
|
|
||||||
"ro.wifi.channels",
|
|
||||||
|
|
||||||
"ro.build.product",
|
|
||||||
|
|
||||||
"ro.build.description",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.treble.enabled",
|
|
||||||
"ro.llndk.api_level",
|
|
||||||
"ro.actionable_compatible_property.enabled",
|
|
||||||
"persist.debug.dalvik.vm.core_platform_api_policy",
|
|
||||||
"ro.postinstall.fstab.prefix",
|
|
||||||
"ro.secure",
|
|
||||||
"security.perf_harden",
|
|
||||||
"ro.allow.mock.location",
|
|
||||||
"dalvik.vm.lockprof.threshold",
|
|
||||||
"ro.debuggable",
|
|
||||||
"net.bt.name",
|
|
||||||
"ro.force.debuggable",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"debug.atrace.tags.enableflags",
|
|
||||||
"persist.traced.enable",
|
|
||||||
"dalvik.vm.image-dex2oat-Xms",
|
|
||||||
"dalvik.vm.image-dex2oat-Xmx",
|
|
||||||
"dalvik.vm.dex2oat-Xms",
|
|
||||||
"dalvik.vm.dex2oat-Xmx",
|
|
||||||
"dalvik.vm.usejit",
|
|
||||||
"dalvik.vm.dexopt.secondary",
|
|
||||||
"dalvik.vm.dexopt.thermal-cutoff",
|
|
||||||
"dalvik.vm.appimageformat",
|
|
||||||
"ro.dalvik.vm.native.bridge",
|
|
||||||
"pm.dexopt.post-boot",
|
|
||||||
"pm.dexopt.first-boot",
|
|
||||||
"pm.dexopt.boot-after-ota",
|
|
||||||
"pm.dexopt.boot-after-mainline-update",
|
|
||||||
"pm.dexopt.install",
|
|
||||||
"pm.dexopt.install-fast",
|
|
||||||
"pm.dexopt.install-bulk",
|
|
||||||
"pm.dexopt.install-bulk-secondary",
|
|
||||||
"pm.dexopt.install-bulk-downgraded",
|
|
||||||
"pm.dexopt.install-bulk-secondary-downgraded",
|
|
||||||
"pm.dexopt.bg-dexopt",
|
|
||||||
"pm.dexopt.ab-ota",
|
|
||||||
"pm.dexopt.inactive",
|
|
||||||
"pm.dexopt.cmdline",
|
|
||||||
"pm.dexopt.shared",
|
|
||||||
"dalvik.vm.dex2oat-resolve-startup-strings",
|
|
||||||
"dalvik.vm.dex2oat-max-image-block-size",
|
|
||||||
"dalvik.vm.minidebuginfo",
|
|
||||||
"dalvik.vm.dex2oat-minidebuginfo",
|
|
||||||
"dalvik.vm.madvise.vdexfile.size",
|
|
||||||
"dalvik.vm.madvise.odexfile.size",
|
|
||||||
"dalvik.vm.madvise.artfile.size",
|
|
||||||
"dalvik.vm.usap_pool_enabled",
|
|
||||||
"dalvik.vm.usap_refill_threshold",
|
|
||||||
"dalvik.vm.usap_pool_size_max",
|
|
||||||
"dalvik.vm.usap_pool_size_min",
|
|
||||||
"dalvik.vm.usap_pool_refill_delay_ms",
|
|
||||||
"dalvik.vm.useartservice",
|
|
||||||
"dalvik.vm.enable_pr_dexopt",
|
|
||||||
"ro.cp_system_other_odex",
|
|
||||||
"ro.apex.updatable",
|
|
||||||
"ro.lineage.version",
|
|
||||||
"ro.lineage.display.version",
|
|
||||||
"ro.lineage.build.version",
|
|
||||||
"ro.lineage.releasetype",
|
|
||||||
"ro.lineagelegal.url",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.com.google.clientidbase",
|
|
||||||
"ro.adb.secure",
|
|
||||||
"persist.sys.strictmode.disable",
|
|
||||||
"ro.ota.allow_downgrade",
|
|
||||||
"ro.control_privapp_permissions",
|
|
||||||
"ro.storage_manager.enabled",
|
|
||||||
"dalvik.vm.systemuicompilerfilter",
|
|
||||||
"debug.sf.enable_transaction_tracing",
|
|
||||||
"media.recorder.show_manufacturer_and_model",
|
|
||||||
"net.tethering.noprovisioning",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.build.backported_fixes.alias_bitset.long_list",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.product.vendor.brand",
|
|
||||||
"ro.product.vendor.device",
|
|
||||||
"ro.product.vendor.manufacturer",
|
|
||||||
"ro.product.vendor.model",
|
|
||||||
"ro.product.vendor.name",
|
|
||||||
"ro.vendor.product.cpu.abilist",
|
|
||||||
"ro.vendor.product.cpu.abilist32",
|
|
||||||
"ro.vendor.product.cpu.abilist64",
|
|
||||||
"ro.vendor.build.date",
|
|
||||||
"ro.vendor.build.date.utc",
|
|
||||||
"ro.vendor.build.fingerprint",
|
|
||||||
"ro.vendor.build.id",
|
|
||||||
"ro.vendor.build.tags",
|
|
||||||
"ro.vendor.build.type",
|
|
||||||
"ro.vendor.build.version.incremental",
|
|
||||||
"ro.vendor.build.version.release",
|
|
||||||
"ro.vendor.build.version.release_or_codename",
|
|
||||||
"ro.vendor.build.version.sdk",
|
|
||||||
"ro.vendor.build.version.sdk_minor",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"aaudio.hw_burst_min_usec",
|
|
||||||
"aaudio.mmap_exclusive_policy",
|
|
||||||
"aaudio.mmap_policy",
|
|
||||||
"audio.deep_buffer.media",
|
|
||||||
"audio.offload.video",
|
|
||||||
"audio.sys.offload.pstimeout.secs",
|
|
||||||
"audio.sys.noisy.broadcast.delay",
|
|
||||||
"persist.vendor.audio.spf_restart",
|
|
||||||
"ro.af.client_heap_size_kbyte",
|
|
||||||
"ro.audio.flinger_standbytime_ms",
|
|
||||||
"vendor.audio_hal.period_size",
|
|
||||||
"vendor.audio.adm.buffering.ms",
|
|
||||||
"vendor.audio.c2.preferred",
|
|
||||||
"vendor.audio.flac.sw.decoder.24bit",
|
|
||||||
"vendor.audio.enable.mirrorlink",
|
|
||||||
"vendor.audio.feature.a2dp_offload.enable",
|
|
||||||
"vendor.audio.feature.afe_proxy.enable",
|
|
||||||
"vendor.audio.feature.battery_listener.enable",
|
|
||||||
"vendor.audio.feature.dmabuf.cma.memory.enable",
|
|
||||||
"vendor.audio.feature.handset.profile.disable",
|
|
||||||
"vendor.audio.feature.hfp.enable",
|
|
||||||
"vendor.audio.feature.kpi_optimize.enable",
|
|
||||||
"vendor.audio.hdr.record.enable",
|
|
||||||
"vendor.audio.hw.aac.encoder",
|
|
||||||
"vendor.audio.offload.buffer.size.kb",
|
|
||||||
"vendor.audio.offload.multiple.enabled",
|
|
||||||
"vendor.audio.offload.track.enable",
|
|
||||||
"vendor.audio.safx.pbe.enabled",
|
|
||||||
"vendor.audio.ull_record_period_multiplier",
|
|
||||||
"vendor.audio.use.sw.alac.decoder",
|
|
||||||
"vendor.audio.use.sw.ape.decoder",
|
|
||||||
"vendor.audio.use.sw.mpegh.decoder",
|
|
||||||
"vendor.audio.volume.headset.gain.depcal",
|
|
||||||
"vendor.qc2audio.suspend.enabled",
|
|
||||||
"vendor.qc2audio.per_frame.flac.dec.enabled",
|
|
||||||
|
|
||||||
"bluetooth.device.class_of_device",
|
|
||||||
"bluetooth.hardware.power.idle_cur_ma",
|
|
||||||
"bluetooth.hardware.power.operating_voltage_mv",
|
|
||||||
"bluetooth.hardware.power.rx_cur_ma",
|
|
||||||
"bluetooth.hardware.power.tx_cur_ma",
|
|
||||||
"bluetooth.profile.a2dp.source.enabled",
|
|
||||||
"bluetooth.profile.asha.central.enabled",
|
|
||||||
"bluetooth.profile.avrcp.target.enabled",
|
|
||||||
"bluetooth.profile.bas.client.enabled",
|
|
||||||
"bluetooth.profile.gatt.enabled",
|
|
||||||
"bluetooth.profile.hfp.ag.enabled",
|
|
||||||
"bluetooth.profile.hid.device.enabled",
|
|
||||||
"bluetooth.profile.hid.host.enabled",
|
|
||||||
"bluetooth.profile.map.server.enabled",
|
|
||||||
"bluetooth.profile.opp.enabled",
|
|
||||||
"bluetooth.profile.pan.nap.enabled",
|
|
||||||
"bluetooth.profile.pan.panu.enabled",
|
|
||||||
"bluetooth.profile.pbap.server.enabled",
|
|
||||||
"bluetooth.profile.sap.server.enabled",
|
|
||||||
"persist.bluetooth.a2dp_offload.disabled",
|
|
||||||
"persist.vendor.bt.aac_frm_ctl.enabled",
|
|
||||||
"persist.vendor.bt.aac_vbr_frm_ctl.enabled",
|
|
||||||
"persist.vendor.qcom.bluetooth.a2dp_offload_cap",
|
|
||||||
"persist.vendor.qcom.bluetooth.aac_frm_ctl.enabled",
|
|
||||||
"persist.vendor.qcom.bluetooth.aptxadaptiver2_1_support",
|
|
||||||
"ro.bluetooth.a2dp_offload.supported",
|
|
||||||
|
|
||||||
"vendor.camera.aux.packageexcludelist",
|
|
||||||
|
|
||||||
"ro.soc.manufacturer",
|
|
||||||
|
|
||||||
"persist.vendor.dpm.vndr.idletimer.mode",
|
|
||||||
"persist.vendor.dpm.vndr.halservice.enable",
|
|
||||||
"persist.vendor.dpm.vndr.feature",
|
|
||||||
|
|
||||||
"persist.sys.sf.color_mode",
|
|
||||||
"persist.sys.sf.color_saturation",
|
|
||||||
"vendor.display.comp_mask",
|
|
||||||
"vendor.display.disable_3d_adaptive_tm",
|
|
||||||
"vendor.display.disable_excl_rect",
|
|
||||||
"vendor.display.disable_excl_rect_partial_fb",
|
|
||||||
"vendor.display.disable_hw_recovery_dump",
|
|
||||||
"vendor.display.disable_offline_rotator",
|
|
||||||
"vendor.display.disable_scaler",
|
|
||||||
"vendor.display.disable_sdr_dimming",
|
|
||||||
"vendor.display.disable_sdr_histogram",
|
|
||||||
"vendor.display.disable_stc_dimming",
|
|
||||||
"vendor.display.enable_async_powermode",
|
|
||||||
"vendor.display.enable_async_vds_creation",
|
|
||||||
"vendor.display.enable_dpps_dynamic_fps",
|
|
||||||
"vendor.display.enable_early_wakeup",
|
|
||||||
"vendor.display.enable_hdr10_gpu_target",
|
|
||||||
"vendor.display.enable_optimize_refresh",
|
|
||||||
"vendor.display.use_smooth_motion",
|
|
||||||
"vendor.display.vds_allow_hwc",
|
|
||||||
|
|
||||||
"drm.service.enabled",
|
|
||||||
|
|
||||||
"ro.frp.pst",
|
|
||||||
|
|
||||||
"persist.sys.fuse.passthrough.enable",
|
|
||||||
|
|
||||||
"vendor.gatekeeper.disable_spu",
|
|
||||||
"vendor.gatekeeper.is_security_level_spu",
|
|
||||||
|
|
||||||
"debug.sf.auto_latch_unsignaled",
|
|
||||||
"debug.sf.disable_client_composition_cache",
|
|
||||||
"debug.sf.early.app.duration",
|
|
||||||
"debug.sf.early.sf.duration",
|
|
||||||
"debug.sf.earlyGl.app.duration",
|
|
||||||
"debug.sf.earlyGl.sf.duration",
|
|
||||||
"debug.sf.enable_advanced_sf_phase_offset",
|
|
||||||
"debug.sf.enable_gl_backpressure",
|
|
||||||
"debug.sf.enable_hwc_vds",
|
|
||||||
"debug.sf.predict_hwc_composition_strategy",
|
|
||||||
"debug.sf.latch_unsignaled",
|
|
||||||
"debug.sf.late.app.duration",
|
|
||||||
"debug.sf.late.sf.duration",
|
|
||||||
"debug.sf.treat_170m_as_sRGB",
|
|
||||||
"debug.sf.use_phase_offsets_as_durations",
|
|
||||||
"ro.hardware.egl",
|
|
||||||
"ro.hardware.vulkan",
|
|
||||||
"ro.opengles.version",
|
|
||||||
"ro.surface_flinger.force_hwc_copy_for_virtual_displays",
|
|
||||||
"ro.surface_flinger.game_default_frame_rate_override",
|
|
||||||
"ro.surface_flinger.has_HDR_display",
|
|
||||||
"ro.surface_flinger.has_wide_color_display",
|
|
||||||
"ro.surface_flinger.max_frame_buffer_acquired_buffers",
|
|
||||||
"ro.surface_flinger.max_virtual_display_dimension",
|
|
||||||
"ro.surface_flinger.protected_contents",
|
|
||||||
"ro.surface_flinger.use_color_management",
|
|
||||||
"ro.surface_flinger.use_content_detection_for_refresh_rate",
|
|
||||||
"ro.surface_flinger.wcg_composition_dataspace",
|
|
||||||
|
|
||||||
"ro.incremental.enable",
|
|
||||||
|
|
||||||
"debug.c2.use_dmabufheaps",
|
|
||||||
"debug.stagefright.c2inputsurface",
|
|
||||||
"vendor.media.omx",
|
|
||||||
|
|
||||||
"ro.netflix.bsp_rev",
|
|
||||||
|
|
||||||
"ro.vendor.extension_library",
|
|
||||||
|
|
||||||
"persist.radio.multisim.config",
|
|
||||||
"persist.vendor.radio.apm_sim_not_pwdn",
|
|
||||||
"persist.vendor.radio.custom_ecc",
|
|
||||||
"persist.vendor.radio.enableadvancedscan",
|
|
||||||
"persist.vendor.radio.procedure_bytes",
|
|
||||||
"persist.vendor.radio.rat_on",
|
|
||||||
"persist.vendor.radio.sib16_support",
|
|
||||||
"ro.telephony.default_network",
|
|
||||||
|
|
||||||
"persist.vendor.rcs.singlereg.feature",
|
|
||||||
|
|
||||||
"persist.vendor.sensors.debug.hal",
|
|
||||||
"vendor.dynamic_sensor.setup.timeout.ms",
|
|
||||||
|
|
||||||
"sys.usb.mtp.batchcancel",
|
|
||||||
"vendor.usb.controller",
|
|
||||||
"vendor.usb.diag.func.name",
|
|
||||||
"vendor.usb.dpl.inst.name",
|
|
||||||
"vendor.usb.qdss.inst.name",
|
|
||||||
"vendor.usb.rmnet.func.name",
|
|
||||||
"vendor.usb.rmnet.inst.name",
|
|
||||||
"vendor.usb.rndis.func.name",
|
|
||||||
"vendor.usb.use_ffs_mtp",
|
|
||||||
"vendor.usb.use_gadget_hal",
|
|
||||||
|
|
||||||
"wifi.aware.interface",
|
|
||||||
|
|
||||||
"zygote.critical_window.minute",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"bluetooth.device.default_name",
|
|
||||||
|
|
||||||
"ro.surface_flinger.set_idle_timer_ms",
|
|
||||||
"ro.surface_flinger.set_touch_timer_ms",
|
|
||||||
|
|
||||||
"vendor.usb.product_string",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.bionic.arch",
|
|
||||||
"ro.bionic.cpu_variant",
|
|
||||||
"ro.bionic.2nd_arch",
|
|
||||||
"ro.bionic.2nd_cpu_variant",
|
|
||||||
"persist.sys.dalvik.vm.lib.2",
|
|
||||||
"dalvik.vm.isa.arm64.variant",
|
|
||||||
"dalvik.vm.isa.arm64.features",
|
|
||||||
"ro.minui.pixel_format",
|
|
||||||
"ro.boot.dynamic_partitions",
|
|
||||||
"ro.product.first_api_level",
|
|
||||||
"ro.product.debugfs_restrictions.enabled",
|
|
||||||
"ro.board.first_api_level",
|
|
||||||
"ro.board.api_level",
|
|
||||||
"ro.board.api_frozen",
|
|
||||||
"ro.vendor.build.security_patch",
|
|
||||||
"ro.product.board",
|
|
||||||
"ro.board.platform",
|
|
||||||
"ro.hwui.use_vulkan",
|
|
||||||
"ro.sf.lcd_density",
|
|
||||||
"ro.build.ab_update",
|
|
||||||
"ro.vendor.build.ab_ota_partitions",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.zygote",
|
|
||||||
"dalvik.vm.dex2oat64.enabled",
|
|
||||||
"keyguard.no_require_sim",
|
|
||||||
"ro.com.android.dataroaming",
|
|
||||||
"ro.config.ringtone",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"tombstoned.max_tombstone_count",
|
|
||||||
"ro.logd.size.stats",
|
|
||||||
"log.tag.stats_log",
|
|
||||||
"ro.carrier",
|
|
||||||
"ro.config.notification_sound",
|
|
||||||
"ro.config.alarm_alert",
|
|
||||||
"ro.recovery.usb.vid",
|
|
||||||
"ro.recovery.usb.adb.pid",
|
|
||||||
"ro.recovery.usb.fastboot.pid",
|
|
||||||
"ro.virtual_ab.enabled",
|
|
||||||
"dalvik.vm.heapstartsize",
|
|
||||||
"dalvik.vm.heapgrowthlimit",
|
|
||||||
"dalvik.vm.heapsize",
|
|
||||||
"dalvik.vm.heaptargetutilization",
|
|
||||||
"dalvik.vm.heapminfree",
|
|
||||||
"dalvik.vm.heapmaxfree",
|
|
||||||
"external_storage.projid.enabled",
|
|
||||||
"external_storage.casefold.enabled",
|
|
||||||
"external_storage.sdcardfs.enabled",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.product.vendor.brand",
|
|
||||||
"ro.product.vendor.device",
|
|
||||||
"ro.product.vendor.manufacturer",
|
|
||||||
"ro.product.vendor.model",
|
|
||||||
"ro.product.vendor.name",
|
|
||||||
"ro.vendor.product.cpu.abilist",
|
|
||||||
"ro.vendor.product.cpu.abilist32",
|
|
||||||
"ro.vendor.product.cpu.abilist64",
|
|
||||||
"ro.vendor.build.date",
|
|
||||||
"ro.vendor.build.date.utc",
|
|
||||||
"ro.vendor.build.fingerprint",
|
|
||||||
"ro.vendor.build.id",
|
|
||||||
"ro.vendor.build.tags",
|
|
||||||
"ro.vendor.build.type",
|
|
||||||
"ro.vendor.build.version.incremental",
|
|
||||||
"ro.vendor.build.version.release",
|
|
||||||
"ro.vendor.build.version.release_or_codename",
|
|
||||||
"ro.vendor.build.version.sdk",
|
|
||||||
"ro.vendor.build.version.sdk_minor",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"aaudio.hw_burst_min_usec",
|
|
||||||
"aaudio.mmap_exclusive_policy",
|
|
||||||
"aaudio.mmap_policy",
|
|
||||||
"audio.deep_buffer.media",
|
|
||||||
"audio.offload.video",
|
|
||||||
"audio.sys.offload.pstimeout.secs",
|
|
||||||
"audio.sys.noisy.broadcast.delay",
|
|
||||||
"persist.vendor.audio.spf_restart",
|
|
||||||
"ro.af.client_heap_size_kbyte",
|
|
||||||
"ro.audio.flinger_standbytime_ms",
|
|
||||||
"vendor.audio_hal.period_size",
|
|
||||||
"vendor.audio.adm.buffering.ms",
|
|
||||||
"vendor.audio.c2.preferred",
|
|
||||||
"vendor.audio.flac.sw.decoder.24bit",
|
|
||||||
"vendor.audio.enable.mirrorlink",
|
|
||||||
"vendor.audio.feature.a2dp_offload.enable",
|
|
||||||
"vendor.audio.feature.afe_proxy.enable",
|
|
||||||
"vendor.audio.feature.battery_listener.enable",
|
|
||||||
"vendor.audio.feature.dmabuf.cma.memory.enable",
|
|
||||||
"vendor.audio.feature.handset.profile.disable",
|
|
||||||
"vendor.audio.feature.hfp.enable",
|
|
||||||
"vendor.audio.feature.kpi_optimize.enable",
|
|
||||||
"vendor.audio.hdr.record.enable",
|
|
||||||
"vendor.audio.hw.aac.encoder",
|
|
||||||
"vendor.audio.offload.buffer.size.kb",
|
|
||||||
"vendor.audio.offload.multiple.enabled",
|
|
||||||
"vendor.audio.offload.track.enable",
|
|
||||||
"vendor.audio.safx.pbe.enabled",
|
|
||||||
"vendor.audio.ull_record_period_multiplier",
|
|
||||||
"vendor.audio.use.sw.alac.decoder",
|
|
||||||
"vendor.audio.use.sw.ape.decoder",
|
|
||||||
"vendor.audio.use.sw.mpegh.decoder",
|
|
||||||
"vendor.audio.volume.headset.gain.depcal",
|
|
||||||
"vendor.qc2audio.suspend.enabled",
|
|
||||||
"vendor.qc2audio.per_frame.flac.dec.enabled",
|
|
||||||
|
|
||||||
"bluetooth.device.class_of_device",
|
|
||||||
"bluetooth.hardware.power.idle_cur_ma",
|
|
||||||
"bluetooth.hardware.power.operating_voltage_mv",
|
|
||||||
"bluetooth.hardware.power.rx_cur_ma",
|
|
||||||
"bluetooth.hardware.power.tx_cur_ma",
|
|
||||||
"bluetooth.profile.a2dp.source.enabled",
|
|
||||||
"bluetooth.profile.asha.central.enabled",
|
|
||||||
"bluetooth.profile.avrcp.target.enabled",
|
|
||||||
"bluetooth.profile.bas.client.enabled",
|
|
||||||
"bluetooth.profile.gatt.enabled",
|
|
||||||
"bluetooth.profile.hfp.ag.enabled",
|
|
||||||
"bluetooth.profile.hid.device.enabled",
|
|
||||||
"bluetooth.profile.hid.host.enabled",
|
|
||||||
"bluetooth.profile.map.server.enabled",
|
|
||||||
"bluetooth.profile.opp.enabled",
|
|
||||||
"bluetooth.profile.pan.nap.enabled",
|
|
||||||
"bluetooth.profile.pan.panu.enabled",
|
|
||||||
"bluetooth.profile.pbap.server.enabled",
|
|
||||||
"bluetooth.profile.sap.server.enabled",
|
|
||||||
"persist.bluetooth.a2dp_offload.disabled",
|
|
||||||
"persist.vendor.bt.aac_frm_ctl.enabled",
|
|
||||||
"persist.vendor.bt.aac_vbr_frm_ctl.enabled",
|
|
||||||
"persist.vendor.qcom.bluetooth.a2dp_offload_cap",
|
|
||||||
"persist.vendor.qcom.bluetooth.aac_frm_ctl.enabled",
|
|
||||||
"persist.vendor.qcom.bluetooth.aptxadaptiver2_1_support",
|
|
||||||
"ro.bluetooth.a2dp_offload.supported",
|
|
||||||
|
|
||||||
"vendor.camera.aux.packageexcludelist",
|
|
||||||
|
|
||||||
"ro.soc.manufacturer",
|
|
||||||
|
|
||||||
"persist.vendor.dpm.vndr.idletimer.mode",
|
|
||||||
"persist.vendor.dpm.vndr.halservice.enable",
|
|
||||||
"persist.vendor.dpm.vndr.feature",
|
|
||||||
|
|
||||||
"persist.sys.sf.color_mode",
|
|
||||||
"persist.sys.sf.color_saturation",
|
|
||||||
"vendor.display.comp_mask",
|
|
||||||
"vendor.display.disable_3d_adaptive_tm",
|
|
||||||
"vendor.display.disable_excl_rect",
|
|
||||||
"vendor.display.disable_excl_rect_partial_fb",
|
|
||||||
"vendor.display.disable_hw_recovery_dump",
|
|
||||||
"vendor.display.disable_offline_rotator",
|
|
||||||
"vendor.display.disable_scaler",
|
|
||||||
"vendor.display.disable_sdr_dimming",
|
|
||||||
"vendor.display.disable_sdr_histogram",
|
|
||||||
"vendor.display.disable_stc_dimming",
|
|
||||||
"vendor.display.enable_async_powermode",
|
|
||||||
"vendor.display.enable_async_vds_creation",
|
|
||||||
"vendor.display.enable_dpps_dynamic_fps",
|
|
||||||
"vendor.display.enable_early_wakeup",
|
|
||||||
"vendor.display.enable_hdr10_gpu_target",
|
|
||||||
"vendor.display.enable_optimize_refresh",
|
|
||||||
"vendor.display.use_smooth_motion",
|
|
||||||
"vendor.display.vds_allow_hwc",
|
|
||||||
|
|
||||||
"drm.service.enabled",
|
|
||||||
|
|
||||||
"ro.frp.pst",
|
|
||||||
|
|
||||||
"persist.sys.fuse.passthrough.enable",
|
|
||||||
|
|
||||||
"vendor.gatekeeper.disable_spu",
|
|
||||||
"vendor.gatekeeper.is_security_level_spu",
|
|
||||||
|
|
||||||
"debug.sf.auto_latch_unsignaled",
|
|
||||||
"debug.sf.disable_client_composition_cache",
|
|
||||||
"debug.sf.early.app.duration",
|
|
||||||
"debug.sf.early.sf.duration",
|
|
||||||
"debug.sf.earlyGl.app.duration",
|
|
||||||
"debug.sf.earlyGl.sf.duration",
|
|
||||||
"debug.sf.enable_advanced_sf_phase_offset",
|
|
||||||
"debug.sf.enable_gl_backpressure",
|
|
||||||
"debug.sf.enable_hwc_vds",
|
|
||||||
"debug.sf.predict_hwc_composition_strategy",
|
|
||||||
"debug.sf.latch_unsignaled",
|
|
||||||
"debug.sf.late.app.duration",
|
|
||||||
"debug.sf.late.sf.duration",
|
|
||||||
"debug.sf.treat_170m_as_sRGB",
|
|
||||||
"debug.sf.use_phase_offsets_as_durations",
|
|
||||||
"ro.hardware.egl",
|
|
||||||
"ro.hardware.vulkan",
|
|
||||||
"ro.opengles.version",
|
|
||||||
"ro.surface_flinger.force_hwc_copy_for_virtual_displays",
|
|
||||||
"ro.surface_flinger.game_default_frame_rate_override",
|
|
||||||
"ro.surface_flinger.has_HDR_display",
|
|
||||||
"ro.surface_flinger.has_wide_color_display",
|
|
||||||
"ro.surface_flinger.max_frame_buffer_acquired_buffers",
|
|
||||||
"ro.surface_flinger.max_virtual_display_dimension",
|
|
||||||
"ro.surface_flinger.protected_contents",
|
|
||||||
"ro.surface_flinger.use_color_management",
|
|
||||||
"ro.surface_flinger.use_content_detection_for_refresh_rate",
|
|
||||||
"ro.surface_flinger.wcg_composition_dataspace",
|
|
||||||
|
|
||||||
"ro.incremental.enable",
|
|
||||||
|
|
||||||
"debug.c2.use_dmabufheaps",
|
|
||||||
"debug.stagefright.c2inputsurface",
|
|
||||||
"vendor.media.omx",
|
|
||||||
|
|
||||||
"ro.netflix.bsp_rev",
|
|
||||||
|
|
||||||
"ro.vendor.extension_library",
|
|
||||||
|
|
||||||
"persist.radio.multisim.config",
|
|
||||||
"persist.vendor.radio.apm_sim_not_pwdn",
|
|
||||||
"persist.vendor.radio.custom_ecc",
|
|
||||||
"persist.vendor.radio.enableadvancedscan",
|
|
||||||
"persist.vendor.radio.procedure_bytes",
|
|
||||||
"persist.vendor.radio.rat_on",
|
|
||||||
"persist.vendor.radio.sib16_support",
|
|
||||||
"ro.telephony.default_network",
|
|
||||||
|
|
||||||
"persist.vendor.rcs.singlereg.feature",
|
|
||||||
|
|
||||||
"persist.vendor.sensors.debug.hal",
|
|
||||||
"vendor.dynamic_sensor.setup.timeout.ms",
|
|
||||||
|
|
||||||
"sys.usb.mtp.batchcancel",
|
|
||||||
"vendor.usb.controller",
|
|
||||||
"vendor.usb.diag.func.name",
|
|
||||||
"vendor.usb.dpl.inst.name",
|
|
||||||
"vendor.usb.qdss.inst.name",
|
|
||||||
"vendor.usb.rmnet.func.name",
|
|
||||||
"vendor.usb.rmnet.inst.name",
|
|
||||||
"vendor.usb.rndis.func.name",
|
|
||||||
"vendor.usb.use_ffs_mtp",
|
|
||||||
"vendor.usb.use_gadget_hal",
|
|
||||||
|
|
||||||
"wifi.aware.interface",
|
|
||||||
|
|
||||||
"zygote.critical_window.minute",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"bluetooth.device.default_name",
|
|
||||||
|
|
||||||
"ro.surface_flinger.set_idle_timer_ms",
|
|
||||||
"ro.surface_flinger.set_touch_timer_ms",
|
|
||||||
|
|
||||||
"vendor.usb.product_string",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.bionic.arch",
|
|
||||||
"ro.bionic.cpu_variant",
|
|
||||||
"ro.bionic.2nd_arch",
|
|
||||||
"ro.bionic.2nd_cpu_variant",
|
|
||||||
"persist.sys.dalvik.vm.lib.2",
|
|
||||||
"dalvik.vm.isa.arm64.variant",
|
|
||||||
"dalvik.vm.isa.arm64.features",
|
|
||||||
"ro.minui.pixel_format",
|
|
||||||
"ro.boot.dynamic_partitions",
|
|
||||||
"ro.product.first_api_level",
|
|
||||||
"ro.product.debugfs_restrictions.enabled",
|
|
||||||
"ro.board.first_api_level",
|
|
||||||
"ro.board.api_level",
|
|
||||||
"ro.board.api_frozen",
|
|
||||||
"ro.vendor.build.security_patch",
|
|
||||||
"ro.product.board",
|
|
||||||
"ro.board.platform",
|
|
||||||
"ro.hwui.use_vulkan",
|
|
||||||
"ro.sf.lcd_density",
|
|
||||||
"ro.build.ab_update",
|
|
||||||
"ro.vendor.build.ab_ota_partitions",
|
|
||||||
|
|
||||||
|
|
||||||
"ro.product.odm.brand",
|
|
||||||
"ro.product.odm.device",
|
|
||||||
"ro.product.odm.manufacturer",
|
|
||||||
"ro.product.odm.model",
|
|
||||||
"ro.product.odm.name",
|
|
||||||
"ro.odm.product.cpu.abilist",
|
|
||||||
"ro.odm.product.cpu.abilist32",
|
|
||||||
"ro.odm.product.cpu.abilist64",
|
|
||||||
"ro.odm.build.date",
|
|
||||||
"ro.odm.build.date.utc",
|
|
||||||
"ro.odm.build.fingerprint",
|
|
||||||
"ro.odm.build.id",
|
|
||||||
"ro.odm.build.tags",
|
|
||||||
"ro.odm.build.type",
|
|
||||||
"ro.odm.build.version.incremental",
|
|
||||||
"ro.odm.build.version.release",
|
|
||||||
"ro.odm.build.version.release_or_codename",
|
|
||||||
"ro.odm.build.version.sdk",
|
|
||||||
"ro.odm.build.version.sdk_minor",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"ro.config.media_vol_steps",
|
|
||||||
"ro.config.vc_call_vol_steps",
|
|
||||||
"ro.vendor.qti.va_odm.support",
|
|
||||||
|
|
||||||
"persist.vendor.bluetooth.modem_nv_support",
|
|
||||||
|
|
||||||
"ro.hardware.camera",
|
|
||||||
|
|
||||||
"ro.vendor.display.sensortype",
|
|
||||||
"vendor.display.enable_rc_support",
|
|
||||||
"vendor.display.enable_rounded_corner",
|
|
||||||
"vendor.display.disable_noise_layer",
|
|
||||||
"vendor.display.force_dv_support",
|
|
||||||
|
|
||||||
"persist.vendor.radio.force_on_dc",
|
|
||||||
"persist.vendor.radio.poweron_opt",
|
|
||||||
"persist.vendor.radio.stack_id_0",
|
|
||||||
"persist.vendor.radio.stack_id_1",
|
|
||||||
"ro.sys.reserve.integrate",
|
|
||||||
"ro.vendor.oplus.radio.project",
|
|
||||||
"ro.vendor.oplus.radio.sar_regionmark",
|
|
||||||
|
|
||||||
"ro.build.version.svn",
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
)
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
package com.xyzshell.mydev.utils
|
|
||||||
|
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.ServiceConnection
|
|
||||||
import android.os.IBinder
|
|
||||||
import android.os.IInterface
|
|
||||||
import android.os.Parcel
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
|
||||||
|
|
||||||
|
|
||||||
class AdvertisingId private constructor() {
|
|
||||||
companion object {
|
|
||||||
private const val ADVERTISING_ID_SERVICE_NAME =
|
|
||||||
"com.google.android.gms.ads.identifier.internal.IAdvertisingIdService"
|
|
||||||
private val instance = SingletonHolder.holder
|
|
||||||
fun getAdvertisingTrackingId(): String {
|
|
||||||
return instance.advertisingIdentifier ?: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLimitedAdTracking(): Boolean {
|
|
||||||
return instance.limitedAdvertisingTracking
|
|
||||||
}
|
|
||||||
|
|
||||||
fun init(paramContext: Context) {
|
|
||||||
instance.fetchAdvertisingId(paramContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private object SingletonHolder {
|
|
||||||
val holder = AdvertisingId()
|
|
||||||
}
|
|
||||||
|
|
||||||
private var advertisingIdentifier: String? = null
|
|
||||||
|
|
||||||
private var limitedAdvertisingTracking = false
|
|
||||||
|
|
||||||
|
|
||||||
private fun fetchAdvertisingId(paramContext: Context) {
|
|
||||||
val connection = GoogleAdvertisingServiceConnection();
|
|
||||||
val intent = Intent("com.google.android.gms.ads.identifier.service.START")
|
|
||||||
intent.setPackage("com.google.android.gms")
|
|
||||||
try {
|
|
||||||
val bool1 = paramContext.bindService(
|
|
||||||
intent,
|
|
||||||
connection,
|
|
||||||
Context.BIND_AUTO_CREATE
|
|
||||||
)
|
|
||||||
if(bool1) {
|
|
||||||
val iBinder = connection.getBinder()
|
|
||||||
val googleAdvertisingInfo =
|
|
||||||
iBinder?.let { GoogleAdvertisingInfo(it) }
|
|
||||||
|
|
||||||
val str = googleAdvertisingInfo?.getId()
|
|
||||||
this.advertisingIdentifier = str
|
|
||||||
val bool2 = googleAdvertisingInfo?.getEnabled(true)
|
|
||||||
if (bool2 != null) {
|
|
||||||
this.limitedAdvertisingTracking = bool2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
paramContext.unbindService(connection)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class GoogleAdvertisingServiceConnection : ServiceConnection {
|
|
||||||
private var retrieved: Boolean = false
|
|
||||||
private val queue = LinkedBlockingQueue<IBinder>(1)
|
|
||||||
|
|
||||||
fun getBinder(): IBinder? {
|
|
||||||
check(!this.retrieved)
|
|
||||||
this.retrieved = true
|
|
||||||
return queue.take()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
|
||||||
try {
|
|
||||||
queue.put(service)
|
|
||||||
} catch (e: InterruptedException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceDisconnected(name: ComponentName?) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class GoogleAdvertisingInfo(private val _binder: IBinder) : IInterface {
|
|
||||||
fun getEnabled(paramBoolean: Boolean): Boolean {
|
|
||||||
val parcel1 = Parcel.obtain()
|
|
||||||
val parcel2 = Parcel.obtain()
|
|
||||||
try {
|
|
||||||
parcel1.writeInterfaceToken(ADVERTISING_ID_SERVICE_NAME)
|
|
||||||
parcel1.writeInt(if (paramBoolean) 1 else 0)
|
|
||||||
this._binder.transact(2, parcel1, parcel2, 0)
|
|
||||||
parcel2.readException()
|
|
||||||
val i = parcel2.readInt()
|
|
||||||
return i != 0
|
|
||||||
} finally {
|
|
||||||
parcel1.recycle()
|
|
||||||
parcel2.recycle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getId(): String {
|
|
||||||
val parcel1 = Parcel.obtain()
|
|
||||||
val parcel2 = Parcel.obtain()
|
|
||||||
try {
|
|
||||||
parcel1.writeInterfaceToken(ADVERTISING_ID_SERVICE_NAME)
|
|
||||||
val iBinder = this._binder
|
|
||||||
iBinder.transact(1, parcel1, parcel2, 0)
|
|
||||||
parcel2.readException()
|
|
||||||
val b = parcel2.readString() ?: return ""
|
|
||||||
return b
|
|
||||||
} finally {
|
|
||||||
parcel2.recycle()
|
|
||||||
parcel1.recycle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun asBinder(): IBinder {
|
|
||||||
return this._binder
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,742 +0,0 @@
|
|||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package com.xyzshell.mydev.utils
|
|
||||||
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import kotlinx.serialization.encodeToString
|
|
||||||
|
|
||||||
|
|
||||||
class JsonSerializer {
|
|
||||||
companion object {
|
|
||||||
val json = Json {
|
|
||||||
prettyPrint = true
|
|
||||||
ignoreUnknownKeys = true
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T> toJson(obj: T): String {
|
|
||||||
return json.encodeToString(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T> fromJson(jsonString: String): T {
|
|
||||||
return json.decodeFromString(jsonString)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.xyzshell.mydev.utils
|
|
||||||
|
|
||||||
enum class MemoryInfoType {
|
|
||||||
FREE_MEMORY, TOTAL_MEMORY
|
|
||||||
}
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
package com.xyzshell.mydev.utils
|
|
||||||
|
|
||||||
import android.util.Base64
|
|
||||||
import com.google.protobuf.ByteString
|
|
||||||
import java.nio.charset.Charset
|
|
||||||
import java.util.UUID
|
|
||||||
import kotlin.jvm.internal.Intrinsics
|
|
||||||
|
|
||||||
|
|
||||||
class ProtobufExtensionsKt {
|
|
||||||
fun fromBase64(paramString: String?, paramBoolean: Boolean): ByteString {
|
|
||||||
val b = if (paramBoolean) {
|
|
||||||
10
|
|
||||||
} else {
|
|
||||||
2
|
|
||||||
}
|
|
||||||
val byteString: ByteString = ByteString.copyFrom(Base64.decode(paramString, b))
|
|
||||||
Intrinsics.checkNotNullExpressionValue(
|
|
||||||
byteString,
|
|
||||||
"copyFrom(android.util.Base64.decode(this, flag))"
|
|
||||||
)
|
|
||||||
return byteString
|
|
||||||
}
|
|
||||||
fun toISO8859String(paramByteString: ByteString): String {
|
|
||||||
val charset: Charset = Charsets.UTF_8
|
|
||||||
val bytes = paramByteString.toByteArray()
|
|
||||||
//val str = paramByteString.toString(charset)
|
|
||||||
val str = String(bytes, charset)
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
fun toUUID(paramByteString: ByteString): UUID? {
|
|
||||||
val byteBuffer = paramByteString.asReadOnlyByteBuffer()
|
|
||||||
var i = byteBuffer.remaining()
|
|
||||||
var b: Byte = 36
|
|
||||||
if (i == b.toInt()) {
|
|
||||||
val uUID = UUID.fromString(paramByteString.toStringUtf8())
|
|
||||||
return uUID
|
|
||||||
}
|
|
||||||
i = byteBuffer.remaining()
|
|
||||||
b = 16
|
|
||||||
if (i == b.toInt()) {
|
|
||||||
val l1 = byteBuffer.getLong()
|
|
||||||
val l2 = byteBuffer.getLong()
|
|
||||||
val uUID = UUID(l1,l2)
|
|
||||||
return uUID
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
package com.xyzshell.mydev.utils
|
|
||||||
|
|
||||||
import android.hardware.Sensor
|
|
||||||
import android.hardware.SensorEvent
|
|
||||||
import android.hardware.SensorEventListener
|
|
||||||
import android.hardware.SensorManager
|
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.acos
|
|
||||||
|
|
||||||
class SensorCollect(private val sensorManager: SensorManager): SensorEventListener {
|
|
||||||
private val sensor1:Sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)!!
|
|
||||||
private val sensor2:Sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)!!
|
|
||||||
private var gravityData: FloatArray? = null
|
|
||||||
private var gyroscopeData:Float = 1.3E-44F
|
|
||||||
init {
|
|
||||||
sensorManager.registerListener(this,sensor1,SensorManager.SENSOR_DELAY_NORMAL)
|
|
||||||
sensorManager.registerListener(this,sensor2,SensorManager.SENSOR_DELAY_NORMAL)
|
|
||||||
}
|
|
||||||
override fun onSensorChanged(event: SensorEvent?) {
|
|
||||||
val sensor: Sensor = event?.sensor ?: return
|
|
||||||
val i = sensor.type
|
|
||||||
if(i == Sensor.TYPE_GRAVITY) {
|
|
||||||
gravityData = event.values
|
|
||||||
} else {
|
|
||||||
var f1: Float = this.gyroscopeData
|
|
||||||
var f = 0.1f
|
|
||||||
f1 *= f
|
|
||||||
this.gyroscopeData = f1
|
|
||||||
val arrayOfFloat1 = event.values
|
|
||||||
f = abs(arrayOfFloat1[0])
|
|
||||||
val arrayOfFloat2 = event.values
|
|
||||||
var f2 = abs(arrayOfFloat2[1].toDouble()).toFloat()
|
|
||||||
f += f2
|
|
||||||
val arrayOfFloat = event.values
|
|
||||||
val b1: Byte = 2
|
|
||||||
f2 = 2.8E-45f
|
|
||||||
val f3: Float = abs(arrayOfFloat[b1.toInt()])
|
|
||||||
f += f3
|
|
||||||
f1 += f
|
|
||||||
this.gyroscopeData = f1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGravityData(): Float {
|
|
||||||
val arrayOfFloat: FloatArray? = this.gravityData
|
|
||||||
return if ((arrayOfFloat == null)) 0.0f else Math.toDegrees(acos((arrayOfFloat[2] / 9.81f).toDouble()))
|
|
||||||
.toFloat()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGyroscopeData(): Float {
|
|
||||||
return gyroscopeData
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,43 +0,0 @@
|
|||||||
package com.xyzshell.mydev.utils
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.InputStream
|
|
||||||
import java.security.MessageDigest
|
|
||||||
|
|
||||||
class Utilities {
|
|
||||||
companion object {
|
|
||||||
fun sha256(inputStream:InputStream):String {
|
|
||||||
if (inputStream == null) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
val baos = ByteArrayOutputStream()
|
|
||||||
val messageDigest = MessageDigest.getInstance("SHA-256")
|
|
||||||
inputStream.use {
|
|
||||||
inputStream.copyTo(baos)
|
|
||||||
messageDigest.update(baos.toByteArray(), 0, baos.size())
|
|
||||||
}
|
|
||||||
val hashBytes = messageDigest.digest()
|
|
||||||
return toHexString(hashBytes)
|
|
||||||
}catch (e:Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toHexString(byteBuffer:ByteArray):String {
|
|
||||||
// 將 byte 轉換爲 string
|
|
||||||
val strHexString = StringBuffer()
|
|
||||||
|
|
||||||
// 遍歷 byte buffer
|
|
||||||
for (element in byteBuffer) {
|
|
||||||
val hex = Integer.toHexString(0xff and element.toInt())
|
|
||||||
if (hex.length == 1) {
|
|
||||||
strHexString.append('0')
|
|
||||||
}
|
|
||||||
strHexString.append(hex)
|
|
||||||
}
|
|
||||||
return strHexString.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,170 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path
|
|
||||||
android:fillColor="#3DDC84"
|
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M9,0L9,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,0L19,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,0L29,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,0L39,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,0L49,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,0L59,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,0L69,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,0L79,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M89,0L89,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M99,0L99,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,9L108,9"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,19L108,19"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,29L108,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,39L108,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,49L108,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,59L108,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,69L108,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,79L108,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,89L108,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,99L108,99"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,29L89,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,39L89,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,49L89,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,59L89,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,69L89,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,79L89,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,19L29,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,19L39,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,19L49,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,19L59,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,19L69,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,19L79,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
</vector>
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:strokeColor="#00000000" />
|
|
||||||
</vector>
|
|
||||||