改机参数新增
This commit is contained in:
parent
0239820321
commit
e2800ffe8e
|
@ -48,6 +48,11 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.AndroidGrape"
|
android:theme="@style/Theme.AndroidGrape"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
<provider
|
||||||
|
android:name=".provider.DeviceInfoProvider"
|
||||||
|
android:authorities="com.android.grape.deviceinfo.provider"
|
||||||
|
android:exported="true">
|
||||||
|
</provider>
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|
|
@ -13,6 +13,8 @@ import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import com.android.grape.databinding.ActivityMainBinding
|
import com.android.grape.databinding.ActivityMainBinding
|
||||||
import com.android.grape.job.MonitorService
|
import com.android.grape.job.MonitorService
|
||||||
|
import com.android.grape.provider.DeviceDataAccessor
|
||||||
|
import com.android.grape.provider.DeviceInfoHelper
|
||||||
import com.android.grape.util.ClashUtil
|
import com.android.grape.util.ClashUtil
|
||||||
import com.android.grape.util.MockTools
|
import com.android.grape.util.MockTools
|
||||||
import com.android.grape.util.NotificationPermissionHandler
|
import com.android.grape.util.NotificationPermissionHandler
|
||||||
|
@ -22,6 +24,7 @@ import com.android.grape.util.StoragePermissionHelper
|
||||||
import com.android.grape.util.Util
|
import com.android.grape.util.Util
|
||||||
import com.android.grape.util.Util.AUTO_JSPACKAGENAME
|
import com.android.grape.util.Util.AUTO_JSPACKAGENAME
|
||||||
import com.android.grape.util.Util.killRecordProcess
|
import com.android.grape.util.Util.killRecordProcess
|
||||||
|
import com.google.gson.Gson
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
private val viewModel by viewModels<MainViewModel>()
|
private val viewModel by viewModels<MainViewModel>()
|
||||||
|
@ -42,9 +45,13 @@ class MainActivity : AppCompatActivity() {
|
||||||
ScriptUtil.registerScriptResultReceiver()
|
ScriptUtil.registerScriptResultReceiver()
|
||||||
viewBinding.start.setOnClickListener {
|
viewBinding.start.setOnClickListener {
|
||||||
MonitorService.onEvent(MainApplication.instance)
|
MonitorService.onEvent(MainApplication.instance)
|
||||||
|
// DeviceDataAccessor.saveDeviceInfo(this, DeviceInfoHelper.getDeviceId(this))
|
||||||
}
|
}
|
||||||
viewBinding.stop.setOnClickListener {
|
viewBinding.stop.setOnClickListener {
|
||||||
killRecordProcess(this, packageName)
|
killRecordProcess(this, packageName)
|
||||||
|
// DeviceDataAccessor.deleteDeviceInfo(this, DeviceInfoHelper.getDeviceId(this))
|
||||||
|
// val deviceInfo = DeviceDataAccessor.getDeviceInfo(this, DeviceInfoHelper.getDeviceId(this))
|
||||||
|
// Log.d("TAG", "onCreate: ${Gson().toJson(deviceInfo?:"")}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package com.android.grape.data
|
||||||
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
data class Device(
|
data class Device(
|
||||||
var advertiserId: String = "",
|
var advertiserId: String = "",
|
||||||
|
@ -110,4 +112,32 @@ data class Device(
|
||||||
var vendingVersionName: String = "",
|
var vendingVersionName: String = "",
|
||||||
@SerializedName("web_ua")
|
@SerializedName("web_ua")
|
||||||
var webUa: String = ""
|
var webUa: String = ""
|
||||||
)
|
){
|
||||||
|
fun toJson(): String {
|
||||||
|
return JSONObject().apply {
|
||||||
|
put("sensors", JSONArray(sensor))
|
||||||
|
put("arch", arch)
|
||||||
|
put("cpu_abi", cpuAbi)
|
||||||
|
put("cpu_abi2", cpuAbi2)
|
||||||
|
put("size", dim.size)
|
||||||
|
put("xdp", dim.xdp)
|
||||||
|
put("ydp", dim.ydp)
|
||||||
|
put("y_px", dim.yPx)
|
||||||
|
put("x_px", dim.xPx)
|
||||||
|
put("d_dpi", dim.dDpi)
|
||||||
|
put("btch", btch)
|
||||||
|
put("btl", batteryLevel)
|
||||||
|
put("disk", disk)
|
||||||
|
put("sdk", sdk)
|
||||||
|
put("network", network)
|
||||||
|
put("api_ver", vendingVersionCode)
|
||||||
|
put("api_ver_name", vendingVersionName)
|
||||||
|
put("carrier", carrier)
|
||||||
|
put("product", product)
|
||||||
|
put("last_boot_time", lastBootTime)
|
||||||
|
put("install_source_info", installerPackage)
|
||||||
|
put("advertiserId", advertiserId)
|
||||||
|
}.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,4 +9,6 @@ data class Sensor(
|
||||||
var sV: String = "",
|
var sV: String = "",
|
||||||
var sVE: List<Double> = listOf(),
|
var sVE: List<Double> = listOf(),
|
||||||
var sVS: List<Double> = listOf()
|
var sVS: List<Double> = listOf()
|
||||||
)
|
) {
|
||||||
|
companion object
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ class AutoJobService : JobIntentService() {
|
||||||
Handler(Looper.getMainLooper()).postDelayed({
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
ScriptUtil.execScript(
|
ScriptUtil.execScript(
|
||||||
this@AutoJobService,
|
this@AutoJobService,
|
||||||
"/sdcard/autojs/main.js"
|
"/sdcard/script/main.js"
|
||||||
)
|
)
|
||||||
}, 2000L)
|
}, 2000L)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package com.android.grape.provider
|
||||||
|
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import com.android.grape.data.Device
|
||||||
|
|
||||||
|
// DeviceDataAccessor.kt
|
||||||
|
object DeviceDataAccessor {
|
||||||
|
|
||||||
|
// 保存设备信息到提供方
|
||||||
|
fun saveDeviceInfo(context: Context, device: Device): Uri? {
|
||||||
|
val resolver = context.contentResolver
|
||||||
|
val actualDeviceId = DeviceInfoHelper.getDeviceId()
|
||||||
|
|
||||||
|
val values = ContentValues().apply {
|
||||||
|
put(DeviceInfoContract.DeviceInfoEntry.COLUMN_DEVICE_ID, actualDeviceId)
|
||||||
|
put(DeviceInfoContract.DeviceInfoEntry.COLUMN_DATA, device.toJson())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试更新现有记录
|
||||||
|
val updateCount = resolver.update(
|
||||||
|
getDeviceUri(actualDeviceId),
|
||||||
|
values,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
// 如果没有更新记录,则插入新记录
|
||||||
|
return if (updateCount == 0) {
|
||||||
|
resolver.insert(DeviceInfoContract.CONTENT_URI, values)
|
||||||
|
} else {
|
||||||
|
getDeviceUri(actualDeviceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取设备信息
|
||||||
|
fun getDeviceInfo(context: Context, deviceId: String? = null): String? {
|
||||||
|
val resolver = context.contentResolver
|
||||||
|
val actualDeviceId = deviceId ?: DeviceInfoHelper.getDeviceId()
|
||||||
|
|
||||||
|
val cursor = resolver.query(
|
||||||
|
getDeviceUri(actualDeviceId),
|
||||||
|
arrayOf(DeviceInfoContract.DeviceInfoEntry.COLUMN_DATA),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
return cursor?.use {
|
||||||
|
if (it.moveToFirst()) {
|
||||||
|
val json =
|
||||||
|
it.getString(it.run { it.getColumnIndex(DeviceInfoContract.DeviceInfoEntry.COLUMN_DATA) })
|
||||||
|
json
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取所有设备信息
|
||||||
|
fun getAllDeviceInfo(context: Context): List<String> {
|
||||||
|
val resolver = context.contentResolver
|
||||||
|
val deviceList = mutableListOf<String>()
|
||||||
|
|
||||||
|
resolver.query(
|
||||||
|
DeviceInfoContract.CONTENT_URI,
|
||||||
|
arrayOf(DeviceInfoContract.DeviceInfoEntry.COLUMN_DATA),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"${DeviceInfoContract.DeviceInfoEntry.COLUMN_TIMESTAMP} DESC"
|
||||||
|
)?.use { cursor ->
|
||||||
|
val dataIndex = cursor.getColumnIndex(DeviceInfoContract.DeviceInfoEntry.COLUMN_DATA)
|
||||||
|
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
val json = cursor.getString(dataIndex)
|
||||||
|
deviceList.add(json)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return deviceList
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除设备信息
|
||||||
|
fun deleteDeviceInfo(context: Context, deviceId: String? = null): Int {
|
||||||
|
val actualDeviceId = deviceId ?: DeviceInfoHelper.getDeviceId()
|
||||||
|
return context.contentResolver.delete(
|
||||||
|
getDeviceUri(actualDeviceId),
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getDeviceUri(deviceId: String): Uri {
|
||||||
|
return Uri.withAppendedPath(
|
||||||
|
DeviceInfoContract.CONTENT_URI,
|
||||||
|
"device/$deviceId"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.android.grape.provider
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
|
||||||
|
object DeviceInfoContract {
|
||||||
|
const val AUTHORITY = "com.android.grape.deviceinfo.provider"
|
||||||
|
val CONTENT_URI: Uri = "content://$AUTHORITY/device_info".toUri()
|
||||||
|
|
||||||
|
object DeviceInfoEntry {
|
||||||
|
const val TABLE_NAME = "device_info"
|
||||||
|
const val COLUMN_DEVICE_ID = "device_id"
|
||||||
|
const val COLUMN_DATA = "data"
|
||||||
|
const val COLUMN_TIMESTAMP = "timestamp"
|
||||||
|
|
||||||
|
// JSON 键名
|
||||||
|
const val KEY_CPU_ABI = "cpu_abi"
|
||||||
|
const val KEY_DIM = "dim"
|
||||||
|
const val KEY_BTCH = "btch"
|
||||||
|
const val KEY_ARCH = "arch"
|
||||||
|
const val KEY_BTL = "btl"
|
||||||
|
const val KEY_CPU_ABI2 = "cpu_abi2"
|
||||||
|
const val KEY_DISK = "disk"
|
||||||
|
const val KEY_SDK = "sdk"
|
||||||
|
const val KEY_NETWORK = "network"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.android.grape.provider
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.database.sqlite.SQLiteDatabase
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper
|
||||||
|
import android.provider.BaseColumns
|
||||||
|
|
||||||
|
class DeviceInfoDbHelper(context: Context) : SQLiteOpenHelper(
|
||||||
|
context, DATABASE_NAME, null, DATABASE_VERSION
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
const val DATABASE_NAME = "device_info.db"
|
||||||
|
const val DATABASE_VERSION = 1
|
||||||
|
|
||||||
|
const val SQL_CREATE_ENTRIES = """
|
||||||
|
CREATE TABLE ${DeviceInfoContract.DeviceInfoEntry.TABLE_NAME} (
|
||||||
|
${BaseColumns._ID} INTEGER PRIMARY KEY,
|
||||||
|
${DeviceInfoContract.DeviceInfoEntry.COLUMN_DEVICE_ID} TEXT UNIQUE,
|
||||||
|
${DeviceInfoContract.DeviceInfoEntry.COLUMN_DATA} TEXT NOT NULL,
|
||||||
|
${DeviceInfoContract.DeviceInfoEntry.COLUMN_TIMESTAMP} INTEGER NOT NULL DEFAULT (strftime('%s','now'))
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(db: SQLiteDatabase) {
|
||||||
|
db.execSQL(SQL_CREATE_ENTRIES)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||||
|
db.execSQL("DROP TABLE IF EXISTS ${DeviceInfoContract.DeviceInfoEntry.TABLE_NAME}")
|
||||||
|
onCreate(db)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.android.grape.provider
|
||||||
|
|
||||||
|
object DeviceInfoHelper {
|
||||||
|
// 获取设备唯一ID
|
||||||
|
fun getDeviceId(): String {
|
||||||
|
return "d1b3e7f8c9a04b8e9f2c1d5e6f7a8b9c"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
package com.android.grape.provider
|
||||||
|
|
||||||
|
import android.content.ContentProvider
|
||||||
|
import android.content.ContentUris
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.UriMatcher
|
||||||
|
import android.database.Cursor
|
||||||
|
import android.database.sqlite.SQLiteQueryBuilder
|
||||||
|
import android.net.Uri
|
||||||
|
import android.provider.BaseColumns
|
||||||
|
import java.sql.SQLException
|
||||||
|
|
||||||
|
// DeviceInfoProvider.kt
|
||||||
|
class DeviceInfoProvider : ContentProvider() {
|
||||||
|
private lateinit var dbHelper: DeviceInfoDbHelper
|
||||||
|
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
|
||||||
|
addURI(DeviceInfoContract.AUTHORITY, "device_info", 1)
|
||||||
|
addURI(DeviceInfoContract.AUTHORITY, "device_info/#", 2)
|
||||||
|
addURI(DeviceInfoContract.AUTHORITY, "device_info/device/*", 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(): Boolean {
|
||||||
|
dbHelper = DeviceInfoDbHelper(context!!)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun query(
|
||||||
|
uri: Uri,
|
||||||
|
projection: Array<String>?,
|
||||||
|
selection: String?,
|
||||||
|
selectionArgs: Array<String>?,
|
||||||
|
sortOrder: String?
|
||||||
|
): Cursor? {
|
||||||
|
val db = dbHelper.readableDatabase
|
||||||
|
val qb = SQLiteQueryBuilder().apply {
|
||||||
|
tables = DeviceInfoContract.DeviceInfoEntry.TABLE_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
when (uriMatcher.match(uri)) {
|
||||||
|
1 -> {} // 查询所有
|
||||||
|
2 -> qb.appendWhere("${BaseColumns._ID} = ${uri.lastPathSegment}")
|
||||||
|
3 -> qb.appendWhere("${DeviceInfoContract.DeviceInfoEntry.COLUMN_DEVICE_ID} = '${uri.lastPathSegment}'")
|
||||||
|
else -> throw IllegalArgumentException("Unknown URI: $uri")
|
||||||
|
}
|
||||||
|
|
||||||
|
return qb.query(db, projection, selection, selectionArgs, null, null, sortOrder).apply {
|
||||||
|
setNotificationUri(context!!.contentResolver, uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun insert(uri: Uri, values: ContentValues?): Uri? {
|
||||||
|
val db = dbHelper.writableDatabase
|
||||||
|
val now = System.currentTimeMillis() / 1000
|
||||||
|
|
||||||
|
// 添加时间戳
|
||||||
|
values?.put(DeviceInfoContract.DeviceInfoEntry.COLUMN_TIMESTAMP, now)
|
||||||
|
|
||||||
|
val rowId = db.insert(DeviceInfoContract.DeviceInfoEntry.TABLE_NAME, null, values)
|
||||||
|
|
||||||
|
if (rowId > 0) {
|
||||||
|
val newUri = ContentUris.withAppendedId(DeviceInfoContract.CONTENT_URI, rowId)
|
||||||
|
context?.contentResolver?.notifyChange(newUri, null)
|
||||||
|
return newUri
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(
|
||||||
|
uri: Uri,
|
||||||
|
values: ContentValues?,
|
||||||
|
selection: String?,
|
||||||
|
selectionArgs: Array<String>?
|
||||||
|
): Int {
|
||||||
|
val db = dbHelper.writableDatabase
|
||||||
|
val now = System.currentTimeMillis() / 1000
|
||||||
|
|
||||||
|
// 更新时间戳
|
||||||
|
values?.put(DeviceInfoContract.DeviceInfoEntry.COLUMN_TIMESTAMP, now)
|
||||||
|
|
||||||
|
val count = when (uriMatcher.match(uri)) {
|
||||||
|
1 -> db.update(
|
||||||
|
DeviceInfoContract.DeviceInfoEntry.TABLE_NAME,
|
||||||
|
values, selection, selectionArgs
|
||||||
|
)
|
||||||
|
2 -> {
|
||||||
|
val id = uri.lastPathSegment
|
||||||
|
db.update(
|
||||||
|
DeviceInfoContract.DeviceInfoEntry.TABLE_NAME,
|
||||||
|
values,
|
||||||
|
"${BaseColumns._ID} = ?",
|
||||||
|
arrayOf(id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
3 -> {
|
||||||
|
val deviceId = uri.lastPathSegment
|
||||||
|
db.update(
|
||||||
|
DeviceInfoContract.DeviceInfoEntry.TABLE_NAME,
|
||||||
|
values,
|
||||||
|
"${DeviceInfoContract.DeviceInfoEntry.COLUMN_DEVICE_ID} = ?",
|
||||||
|
arrayOf(deviceId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> throw IllegalArgumentException("Unknown URI: $uri")
|
||||||
|
}
|
||||||
|
|
||||||
|
context?.contentResolver?.notifyChange(uri, null)
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
|
||||||
|
val db = dbHelper.writableDatabase
|
||||||
|
|
||||||
|
val count = when (uriMatcher.match(uri)) {
|
||||||
|
1 -> db.delete(
|
||||||
|
DeviceInfoContract.DeviceInfoEntry.TABLE_NAME,
|
||||||
|
selection, selectionArgs
|
||||||
|
)
|
||||||
|
2 -> {
|
||||||
|
val id = uri.lastPathSegment
|
||||||
|
db.delete(
|
||||||
|
DeviceInfoContract.DeviceInfoEntry.TABLE_NAME,
|
||||||
|
"${BaseColumns._ID} = ?",
|
||||||
|
arrayOf(id)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
3 -> {
|
||||||
|
val deviceId = uri.lastPathSegment
|
||||||
|
db.delete(
|
||||||
|
DeviceInfoContract.DeviceInfoEntry.TABLE_NAME,
|
||||||
|
"${DeviceInfoContract.DeviceInfoEntry.COLUMN_DEVICE_ID} = ?",
|
||||||
|
arrayOf(deviceId)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else -> throw IllegalArgumentException("Unknown URI: $uri")
|
||||||
|
}
|
||||||
|
|
||||||
|
context?.contentResolver?.notifyChange(uri, null)
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(uri: Uri): String? {
|
||||||
|
return when (uriMatcher.match(uri)) {
|
||||||
|
1 -> "${DeviceInfoContract.AUTHORITY}/device_info"
|
||||||
|
2, 3 -> "vnd.android.cursor.item/vnd.example.deviceinfo"
|
||||||
|
else -> throw IllegalArgumentException("Unknown URI: $uri")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import com.android.grape.MainApplication
|
||||||
import com.android.grape.data.Device
|
import com.android.grape.data.Device
|
||||||
import com.android.grape.net.Api
|
import com.android.grape.net.Api
|
||||||
import com.android.grape.net.ChangeCallBack
|
import com.android.grape.net.ChangeCallBack
|
||||||
|
import com.android.grape.provider.DeviceDataAccessor
|
||||||
import com.android.grape.util.Util.paramsJson
|
import com.android.grape.util.Util.paramsJson
|
||||||
import com.blankj.utilcode.util.LogUtils
|
import com.blankj.utilcode.util.LogUtils
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -28,6 +29,7 @@ object ChangeDeviceInfoUtil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val device = GsonUtils.fromJsonObject(deviceObject.toString(), Device::class.java)
|
val device = GsonUtils.fromJsonObject(deviceObject.toString(), Device::class.java)
|
||||||
|
DeviceDataAccessor.saveDeviceInfo(MainApplication.instance, device)
|
||||||
val padCode = ShellUtils.execRootCmdAndGetResult("getprop ro.boot.pad_code")
|
val padCode = ShellUtils.execRootCmdAndGetResult("getprop ro.boot.pad_code")
|
||||||
Log.d("TAG", "changeDevice: $padCode")
|
Log.d("TAG", "changeDevice: $padCode")
|
||||||
val jsonString = JSONObject().apply {
|
val jsonString = JSONObject().apply {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.android.grape.util
|
package com.android.grape.util
|
||||||
|
|
||||||
|
import android.os.Environment
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import com.blankj.utilcode.util.LogUtils
|
||||||
import java.io.BufferedInputStream
|
import java.io.BufferedInputStream
|
||||||
import java.io.BufferedOutputStream
|
import java.io.BufferedOutputStream
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
|
@ -16,6 +18,7 @@ import java.io.InputStreamReader
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.io.RandomAccessFile
|
import java.io.RandomAccessFile
|
||||||
import java.io.UnsupportedEncodingException
|
import java.io.UnsupportedEncodingException
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
import java.util.Enumeration
|
import java.util.Enumeration
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
import java.util.zip.ZipFile
|
import java.util.zip.ZipFile
|
||||||
|
@ -387,4 +390,31 @@ object FileUtils {
|
||||||
output.close()
|
output.close()
|
||||||
input.close()
|
input.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun writePackageName(packageName: String) {
|
||||||
|
val file = File(
|
||||||
|
Environment.getExternalStorageDirectory(),
|
||||||
|
"script/packagesname.txt"
|
||||||
|
)
|
||||||
|
val parentDir = file.getParentFile()
|
||||||
|
if (parentDir != null && !parentDir.exists()) {
|
||||||
|
val dirsCreated = parentDir.mkdirs()
|
||||||
|
if (!dirsCreated) {
|
||||||
|
Log.e("FileWrite", "Failed to create directories: $parentDir")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogUtils.d("TAG", "writePackageName: $packageName", null)
|
||||||
|
try {
|
||||||
|
BufferedOutputStream(
|
||||||
|
FileOutputStream(file)
|
||||||
|
).use { bos ->
|
||||||
|
bos.write(packageName.toByteArray(StandardCharsets.UTF_8))
|
||||||
|
bos.flush() // 确保数据写入磁盘
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.e("FileWrite", "Failed to write package name: $packageName", e)
|
||||||
|
// 6. 可以考虑添加重试机制或通知用户
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -185,9 +185,9 @@ public class ShellUtils {
|
||||||
|
|
||||||
public static void execRootCmd(String cmd) {
|
public static void execRootCmd(String cmd) {
|
||||||
// 校验命令是否安全
|
// 校验命令是否安全
|
||||||
if (!isCommandSafe(cmd)) {
|
// if (!isCommandSafe(cmd)) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
List<String> cmds = new ArrayList<>();
|
List<String> cmds = new ArrayList<>();
|
||||||
cmds.add(cmd);
|
cmds.add(cmd);
|
||||||
|
|
||||||
|
|
|
@ -1140,7 +1140,7 @@ object Util {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
unzipAPkSh(script_path, "/sdcard/autojs/")
|
unzipAPkSh(script_path, "/sdcard/script/")
|
||||||
delFileSh(script_path)
|
delFileSh(script_path)
|
||||||
}
|
}
|
||||||
return isDownload
|
return isDownload
|
||||||
|
@ -2571,9 +2571,9 @@ object Util {
|
||||||
*/
|
*/
|
||||||
//当本应用位于后台时,则将它切换到最前端
|
//当本应用位于后台时,则将它切换到最前端
|
||||||
fun setTopApp(context: Context) {
|
fun setTopApp(context: Context) {
|
||||||
// Log.i(TAG, "start to setTopApp");
|
Log.i(TAG, "start to setTopApp");
|
||||||
if (isRunningForeground(context)) {
|
if (isRunningForeground(context)) {
|
||||||
// Log.i(TAG, "app isRunningForeground");
|
Log.i(TAG, "app isRunningForeground");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//获取ActivityManager
|
//获取ActivityManager
|
||||||
|
|
Loading…
Reference in New Issue