mirror of
https://github.com/LittleTurtle2333/SimplicityTools.git
synced 2026-07-14 12:21:18 +08:00
适配Android多版本大框架
更新Blockmiui 优化结构
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.lt2333.simplicitytools.utils
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
|
||||
|
||||
object SPUtils {
|
||||
@SuppressLint("WorldReadableFiles")
|
||||
fun getBoolean(context: Context, key: String, defValue: Boolean): Boolean {
|
||||
val pref = context.getSharedPreferences("config",Context.MODE_WORLD_READABLE)
|
||||
return pref.getBoolean(key, defValue)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
package com.lt2333.simplicitytools.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
public class ShellUtils {
|
||||
|
||||
public static final String COMMAND_SU = "su";
|
||||
public static final String COMMAND_SH = "sh";
|
||||
public static final String COMMAND_EXIT = "exit\n";
|
||||
public static final String COMMAND_LINE_END = "\n";
|
||||
|
||||
private ShellUtils() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether has root permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean checkRootPermission() {
|
||||
return execCommand("echo root", true, false).result == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell command, default return result msg
|
||||
*
|
||||
* @param command command
|
||||
* @param isRoot whether need to run with root
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(String command, boolean isRoot) {
|
||||
return execCommand(new String[]{command}, isRoot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands, default return result msg
|
||||
*
|
||||
* @param commands command activity_wifi
|
||||
* @param isRoot whether need to run with root
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(List<String> commands, boolean isRoot) {
|
||||
return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands, default return result msg
|
||||
*
|
||||
* @param commands command array
|
||||
* @param isRoot whether need to run with root
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(String[] commands, boolean isRoot) {
|
||||
return execCommand(commands, isRoot, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell command
|
||||
*
|
||||
* @param command command
|
||||
* @param isRoot whether need to run with root
|
||||
* @param isNeedResultMsg whether need result msg
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
|
||||
return execCommand(new String[]{command}, isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands
|
||||
*
|
||||
* @param commands command activity_wifi
|
||||
* @param isRoot whether need to run with root
|
||||
* @param isNeedResultMsg whether need result msg
|
||||
* @return
|
||||
* @see ShellUtils#execCommand(String[], boolean, boolean)
|
||||
*/
|
||||
public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
|
||||
return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands
|
||||
*
|
||||
* @param commands command array
|
||||
* @param isRoot whether need to run with root
|
||||
* @param isNeedResultMsg whether need result msg
|
||||
* @return <ul>
|
||||
* <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
|
||||
* {@link CommandResult#errorMsg} is null.</li>
|
||||
* <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
|
||||
int result = -1;
|
||||
if (commands == null || commands.length == 0) {
|
||||
return new CommandResult(result, null, null);
|
||||
}
|
||||
|
||||
Process process = null;
|
||||
BufferedReader successResult = null;
|
||||
BufferedReader errorResult = null;
|
||||
StringBuilder successMsg = null;
|
||||
StringBuilder errorMsg = null;
|
||||
|
||||
DataOutputStream os = null;
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
for (String command : commands) {
|
||||
if (command == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// donnot use os.writeBytes(commmand), avoid chinese charset error
|
||||
os.write(command.getBytes());
|
||||
os.writeBytes(COMMAND_LINE_END);
|
||||
os.flush();
|
||||
}
|
||||
os.writeBytes(COMMAND_EXIT);
|
||||
os.flush();
|
||||
|
||||
result = process.waitFor();
|
||||
// get command result
|
||||
if (isNeedResultMsg) {
|
||||
successMsg = new StringBuilder();
|
||||
errorMsg = new StringBuilder();
|
||||
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
String s;
|
||||
while ((s = successResult.readLine()) != null) {
|
||||
successMsg.append(s);
|
||||
}
|
||||
while ((s = errorResult.readLine()) != null) {
|
||||
errorMsg.append(s);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
if (successResult != null) {
|
||||
successResult.close();
|
||||
}
|
||||
if (errorResult != null) {
|
||||
errorResult.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
|
||||
: errorMsg.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* result of command
|
||||
* <ul>
|
||||
* <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
|
||||
* linux shell</li>
|
||||
* <li>{@link CommandResult#successMsg} means success message of command result</li>
|
||||
* <li>{@link CommandResult#errorMsg} means error message of command result</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author <main href="http://www.trinea.cn" target="_blank">Trinea</main> 2013-5-16
|
||||
*/
|
||||
public static class CommandResult {
|
||||
|
||||
/**
|
||||
* result of command
|
||||
**/
|
||||
public int result;
|
||||
/**
|
||||
* success message of command result
|
||||
**/
|
||||
public String successMsg;
|
||||
/**
|
||||
* error message of command result
|
||||
**/
|
||||
public String errorMsg;
|
||||
|
||||
public CommandResult(int result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public CommandResult(int result, String successMsg, String errorMsg) {
|
||||
this.result = result;
|
||||
this.successMsg = successMsg;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.lt2333.simplicitytools.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
|
||||
object SystemProperties {
|
||||
@SuppressLint("PrivateApi")
|
||||
operator fun get(context: Context, key: String?): String {
|
||||
var ret = ""
|
||||
try {
|
||||
val cl = context.classLoader
|
||||
val systemProperties = cl.loadClass("android.os.SystemProperties")
|
||||
//参数类型
|
||||
val paramTypes: Array<Class<*>?> = arrayOfNulls(1)
|
||||
paramTypes[0] = String::class.java
|
||||
val get = systemProperties.getMethod("get", *paramTypes)
|
||||
//参数
|
||||
val params = arrayOfNulls<Any>(1)
|
||||
params[0] = key
|
||||
ret = get.invoke(systemProperties, *params) as String
|
||||
} catch (iAE: IllegalArgumentException) {
|
||||
throw iAE
|
||||
} catch (e: Exception) {
|
||||
ret = ""
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.lt2333.simplicitytools.utils
|
||||
|
||||
import com.lt2333.simplicitytools.BuildConfig
|
||||
import de.robv.android.xposed.XSharedPreferences
|
||||
|
||||
object XSPUtils {
|
||||
private var prefs = XSharedPreferences(BuildConfig.APPLICATION_ID, "config")
|
||||
|
||||
fun getBoolean(key: String, defValue: Boolean): Boolean {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getBoolean(key, defValue)
|
||||
}
|
||||
|
||||
fun getInt(key: String, defValue: Int): Int {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getInt(key, defValue)
|
||||
}
|
||||
|
||||
fun getFloat(key: String, defValue: Float): Float {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getFloat(key, defValue)
|
||||
}
|
||||
|
||||
fun getString(key: String, defValue: String): String? {
|
||||
if (prefs.hasFileChanged()) {
|
||||
prefs.reload()
|
||||
}
|
||||
return prefs.getString(key, defValue)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun hasEnable(
|
||||
key: String,
|
||||
default: Boolean = false,
|
||||
noinline extraCondition: (() -> Boolean)? = null,
|
||||
crossinline block: () -> Unit
|
||||
) {
|
||||
val conditionResult = if (extraCondition != null) extraCondition() else true
|
||||
if (XSPUtils.getBoolean(key, default) && conditionResult) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.lt2333.simplicitytools.utils.xposed
|
||||
|
||||
import com.github.kyuubiran.ezxhelper.init.EzXHelperInit
|
||||
import com.github.kyuubiran.ezxhelper.utils.Log.logexIfThrow
|
||||
import com.lt2333.simplicitytools.utils.xposed.base.AppRegister
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
abstract class EasyXposedInit : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||
|
||||
private lateinit var packageParam: XC_LoadPackage.LoadPackageParam
|
||||
abstract val registeredApp: List<AppRegister>
|
||||
private val TAG = "WooBox"
|
||||
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam?) {
|
||||
|
||||
packageParam = lpparam!!
|
||||
registeredApp.forEach { app ->
|
||||
if (app.packageName == lpparam.packageName) {
|
||||
EzXHelperInit.apply {
|
||||
setLogXp(true)
|
||||
setLogTag(TAG)
|
||||
setToastTag(TAG)
|
||||
initHandleLoadPackage(lpparam)
|
||||
}
|
||||
runCatching { app.handleLoadPackage(lpparam) }.logexIfThrow("Failed call handleLoadPackage, package: ${app.packageName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam?) {
|
||||
EzXHelperInit.initZygote(startupParam!!)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.lt2333.simplicitytools.utils.xposed.base
|
||||
|
||||
import com.github.kyuubiran.ezxhelper.utils.Log.logexIfThrow
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.XposedBridge
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
abstract class AppRegister: IXposedHookLoadPackage {
|
||||
|
||||
abstract val packageName: String
|
||||
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {}
|
||||
|
||||
protected fun autoInitHooks(lpparam: XC_LoadPackage.LoadPackageParam, vararg hook: HookRegister) {
|
||||
hook.also {
|
||||
XposedBridge.log("WooBox: Try to Hook [$packageName]")
|
||||
}.forEach {
|
||||
runCatching {
|
||||
if (it.isInit) return@forEach
|
||||
it.setLoadPackageParam(lpparam)
|
||||
it.init()
|
||||
it.isInit = true
|
||||
}.logexIfThrow("Failed to Hook [$packageName]")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.lt2333.simplicitytools.utils.xposed.base
|
||||
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
abstract class HookRegister {
|
||||
private lateinit var lpparam: XC_LoadPackage.LoadPackageParam
|
||||
var isInit: Boolean = false
|
||||
abstract fun init()
|
||||
|
||||
fun setLoadPackageParam(loadPackageParam: XC_LoadPackage.LoadPackageParam) {
|
||||
lpparam = loadPackageParam
|
||||
}
|
||||
|
||||
protected fun getLoadPackageParam(): XC_LoadPackage.LoadPackageParam {
|
||||
if (!this::lpparam.isInitialized) {
|
||||
throw RuntimeException("lpparam should be initialized")
|
||||
}
|
||||
return lpparam
|
||||
}
|
||||
|
||||
protected fun getDefaultClassLoader(): ClassLoader {
|
||||
return getLoadPackageParam().classLoader
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user