package com.boeyu.systemmanagerlib;
import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageInstallObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.hardware.usb.UsbManager;
import android.media.Image;
import android.media.ImageReader;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Looper;
import android.os.PowerManager;
import android.os.RecoverySystem;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Created by yuanfang235 on 2019-12-26.
*/
public class SystemApi {
private static final String TAG = "WALX";
/**
* op值,参考AppOpsManager类的声明
*/
public static final int OP_NONE = -1;
public static final int OP_COARSE_LOCATION = 0;
public static final int OP_FINE_LOCATION = 1;
public static final int OP_GPS = 2;
public static final int OP_VIBRATE = 3;
public static final int OP_READ_CONTACTS = 4;
public static final int OP_WRITE_CONTACTS = 5;
public static final int OP_READ_CALL_LOG = 6;
public static final int OP_WRITE_CALL_LOG = 7;
public static final int OP_READ_CALENDAR = 8;
public static final int OP_WRITE_CALENDAR = 9;
public static final int OP_WIFI_SCAN = 10;
public static final int OP_POST_NOTIFICATION = 11;
public static final int OP_NEIGHBORING_CELLS = 12;
public static final int OP_CALL_PHONE = 13;
public static final int OP_READ_SMS = 14;
public static final int OP_WRITE_SMS = 15;
public static final int OP_RECEIVE_SMS = 16;
public static final int OP_RECEIVE_EMERGECY_SMS = 17;
public static final int OP_RECEIVE_MMS = 18;
public static final int OP_RECEIVE_WAP_PUSH = 19;
public static final int OP_SEND_SMS = 20;
public static final int OP_READ_ICC_SMS = 21;
public static final int OP_WRITE_ICC_SMS = 22;
public static final int OP_WRITE_SETTINGS = 23;
public static final int OP_SYSTEM_ALERT_WINDOW = 24;
public static final int OP_ACCESS_NOTIFICATIONS = 25;
public static final int OP_CAMERA = 26;
public static final int OP_RECORD_AUDIO = 27;
public static final int OP_PLAY_AUDIO = 28;
public static final int OP_READ_CLIPBOARD = 29;
public static final int OP_WRITE_CLIPBOARD = 30;
public static final int OP_TAKE_MEDIA_BUTTONS = 31;
public static final int OP_TAKE_AUDIO_FOCUS = 32;
public static final int OP_AUDIO_MASTER_VOLUME = 33;
public static final int OP_AUDIO_VOICE_VOLUME = 34;
public static final int OP_AUDIO_RING_VOLUME = 35;
public static final int OP_AUDIO_MEDIA_VOLUME = 36;
public static final int OP_AUDIO_ALARM_VOLUME = 37;
public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
public static final int OP_WAKE_LOCK = 40;
public static final int OP_MONITOR_LOCATION = 41;
public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
public static final int OP_GET_USAGE_STATS = 43;
public static final int OP_MUTE_MICROPHONE = 44;
public static final int OP_TOAST_WINDOW = 45;
public static final int OP_PROJECT_MEDIA = 46;
public static final int OP_ACTIVATE_VPN = 47;
public static final int OP_WRITE_WALLPAPER = 48;
public static final int OP_ASSIST_STRUCTURE = 49;
public static final int OP_ASSIST_SCREENSHOT = 50;
public static final int OP_READ_PHONE_STATE = 51;
public static final int OP_ADD_VOICEMAIL = 52;
public static final int OP_USE_SIP = 53;
public static final int OP_PROCESS_OUTGOING_CALLS = 54;
public static final int OP_USE_FINGERPRINT = 55;
public static final int OP_BODY_SENSORS = 56;
public static final int OP_READ_CELL_BROADCASTS = 57;
public static final int OP_MOCK_LOCATION = 58;
public static final int OP_READ_EXTERNAL_STORAGE = 59;
public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
public static final int OP_TURN_SCREEN_ON = 61;
public static final int OP_GET_ACCOUNTS = 62;
public static final int OP_RUN_IN_BACKGROUND = 63;
public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
public static final int OP_READ_PHONE_NUMBERS = 65;
public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
public static final int OP_PICTURE_IN_PICTURE = 67;
public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
public static final int OP_ANSWER_PHONE_CALLS = 69;
public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
public static final int STATUS_SUCCESS = 0;
public static final int STATUS_FAILURE = 1;
public static final String USB_FUNCTION_NONE = "none";
public static final String USB_FUNCTION_ADB = "adb";
public static final String USB_FUNCTION_RNDIS = "rndis";
public static final String USB_FUNCTION_MTP = "mtp";
public static final String USB_FUNCTION_PTP = "ptp";
public static final int ERROR_COMPONENT_STATE = -1;
/* 权限标志 */
public static final int FLAG_PERMISSION_ERROR = 0;
public static final int FLAG_PERMISSION_USER_SET = 1 << 0;
public static final int FLAG_PERMISSION_USER_FIXED = 1 << 1;
public static final int FLAG_PERMISSION_POLICY_FIXED = 1 << 2;
public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 1 << 3;
public static final int FLAG_PERMISSION_SYSTEM_FIXED = 1 << 4;
public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 1 << 5;
public static final int FLAG_PERMISSION_REVIEW_REQUIRED = 1 << 6;
public static final int MASK_PERMISSION_FLAGS = 0xFF;
/*************************************************/
private static final int INSTALL_SUCCEEDED = 1;
private static final int DELETE_SUCCEEDED = 1;
private static final int INSTALL_REPLACE_EXISTING = 0x00000002;
private static final int DELETE_SYSTEM_APP = 0x00000004;
private static final int OP_MODE_INVALID = -1;
private static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
private static final String EXTRA_REASON = "android.intent.extra.REASON";
private static final String EXTRA_WIPE_EXTERNAL_STORAGE = "android.intent.extra.WIPE_EXTERNAL_STORAGE";
private static final String ACTION_FACTORY_RESET = "android.intent.action.FACTORY_RESET"; //8.0
private static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;
private static final int DISABLE2_QUICK_SETTINGS = 1;
private static final int DISABLE2_SYSTEM_ICONS = 1 << 1;
private static final int DISABLE2_NOTIFICATION_SHADE = 1 << 2;
private static final int DISABLE2_GLOBAL_ACTIONS = 1 << 3;
private static final int DISABLE2_ROTATE_SUGGESTIONS = 1 << 4;
private static final int DISABLE2_NONE = 0x00000000;
private static final int DISABLE2_MASK = DISABLE2_QUICK_SETTINGS | DISABLE2_SYSTEM_ICONS
| DISABLE2_NOTIFICATION_SHADE | DISABLE2_ROTATE_SUGGESTIONS;
private static final int FIREWALL_RULE_DEFAULT = 0;
private static final int FIREWALL_RULE_ALLOW = 1;
private static final int FIREWALL_RULE_DENY = 2;
private Context mContext;
private Handler mHandler = new Handler(Looper.getMainLooper());
private boolean mDebug;
private boolean mLoggerEnabled;
public SystemApi(Context context) {
this.mContext = context;
mDebug = (mContext.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
}
/**
* 允许运行时权限
*
* @param packageName
* @param permissions
* @return
*/
public SystemApi allowPermission(String packageName, String... permissions) {
if (permissions == null || permissions.length == 0) return this;
if (!needRuntimePermission()) return this;
for (String permission : permissions) {
if (!grantRuntimePermission(packageName, permission)) {
setUidMode(packageName, AppOpsManager.permissionToOp(permission), AppOpsManager.MODE_ALLOWED);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setUidMode(packageName, AppOpsManager.permissionToOp(permission), AppOpsManager.MODE_ALLOWED);
}
}
return this;
}
public SystemApi allowPermission(String packageName, Collection<String> permissions) {
if (permissions == null || permissions.isEmpty()) return this;
String[] array = new String[permissions.size()];
permissions.toArray(array);
return allowPermission(packageName, array);
}
/**
* 禁止运行时权限
*
* @param packageName
* @param permissions
* @return
*/
public SystemApi denyPermission(String packageName, String... permissions) {
if (permissions == null || permissions.length == 0) return this;
if (!needRuntimePermission()) return this;
for (String permission : permissions) {
revokeRuntimePermission(packageName, permission);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setUidMode(packageName, AppOpsManager.permissionToOp(permission), AppOpsManager.MODE_IGNORED);
}
}
return this;
}
public SystemApi denyPermission(String packageName, Collection<String> permissions) {
if (permissions == null || permissions.isEmpty()) return this;
String[] array = new String[permissions.size()];
permissions.toArray(array);
return denyPermission(packageName, array);
}
/**
* 固定权限
*
* @param packageName
* @param permissions
* @return
*/
public SystemApi fixedPermission(String packageName, String... permissions) {
if (permissions == null || permissions.length == 0) return this;
if (!needRuntimePermission()) return this;
for (String permission : permissions) {
fixedPermissionInner(packageName, permission);
}
return this;
}
/**
* 不固定权限
*
* @param packageName
* @param permissions
* @return
*/
public SystemApi unfixedPermission(String packageName, String... permissions) {
if (permissions == null || permissions.length == 0) return this;
if (!needRuntimePermission()) return this;
for (String permission : permissions) {
unfixedPermissionInner(packageName, permission);
}
return this;
}
/**
* 获取权限标志
*
* @param packageName
* @param permission
* @return
*/
public int getPermissionFlags(String packageName, String permission) {
try {
Method method = PackageManager.class.getMethod("getPermissionFlags", String.class, String.class, UserHandle.class);
UserHandle userHandle = (UserHandle) newInstance(UserHandle.class, new Class[]{int.class}, 0);
return (int) method.invoke(mContext.getPackageManager(), permission, packageName, userHandle);
} catch (Exception e) {
printError(e);
}
return FLAG_PERMISSION_ERROR;
}
/**
* 更新权限标志
*
* @param packageName
* @param permission
* @param flagMask
* @param flagValues
*/
public void updatePermissionFlags(String packageName, String permission, int flagMask, int flagValues) {
try {
Method method = PackageManager.class.getMethod("updatePermissionFlags", String.class, String.class, int.class, int.class, UserHandle.class);
UserHandle userHandle = (UserHandle) newInstance(UserHandle.class, new Class[]{int.class}, 0);
method.invoke(mContext.getPackageManager(), permission, packageName, flagMask, flagValues, userHandle);
} catch (Exception e) {
printError(e);
}
}
/**
* 是否获取权限
*
* @param packageName
* @param permissions
* @return
*/
public boolean isPermissionAllowed(String packageName, String... permissions) {
if (permissions == null || permissions.length == 0) return true;
if (!needRuntimePermission()) return true;
Set<String> mDeniedPermissionList = getDeniedPermissionList(packageName, permissions);
return mDeniedPermissionList.isEmpty();
}
/**
* 是否是固定权限
*
* @param packageName
* @param permission
* @return
*/
public boolean isFixedPermission(String packageName, String permission) {
int flags = getPermissionFlags(packageName, permission);
return (flags & FLAG_PERMISSION_SYSTEM_FIXED) == FLAG_PERMISSION_SYSTEM_FIXED
|| (flags & FLAG_PERMISSION_POLICY_FIXED) == FLAG_PERMISSION_POLICY_FIXED;
}
/**
* 设置OP模式
*
* @param packageName
* @param opCode
* @param mode
* @return
*/
public SystemApi setOpMode(String packageName, int opCode, int mode) {
try {
Method method = AppOpsManager.class.getMethod("setMode", int.class, int.class, String.class, int.class);
AppOpsManager mAppOps = (AppOpsManager) mContext.getSystemService(Service.APP_OPS_SERVICE);
method.invoke(mAppOps, opCode, getPackageUid(packageName), packageName, mode);
} catch (Exception e) {
printError(e);
}
return this;
}
/**
* 设置Uid模式
*
* @param packageName
* @param opCode
* @param mode
*/
public void setUidMode(String packageName, int opCode, int mode) {
try {
Method method = AppOpsManager.class.getMethod("setUidMode", int.class, int.class, int.class);
AppOpsManager mAppOps = (AppOpsManager) mContext.getSystemService(Service.APP_OPS_SERVICE);
method.invoke(mAppOps, opCode, getPackageUid(packageName), mode);
} catch (Exception e) {
printError(e);
}
}
/**
* 设置Uid模式
*
* @param packageName
* @param appOp
* @param mode
*/
public void setUidMode(String packageName, String appOp, int mode) {
try {
Method method = AppOpsManager.class.getMethod("setUidMode", String.class, int.class, int.class);
AppOpsManager mAppOps = (AppOpsManager) mContext.getSystemService(Service.APP_OPS_SERVICE);
method.invoke(mAppOps, appOp, getPackageUid(packageName), mode);
} catch (Exception e) {
printError(e);
}
}
/**
* 允许OP权限
*
* @param packageName
* @param opCode
* @return
*/
public SystemApi allowOp(String packageName, int opCode) {
setOpMode(packageName, opCode, AppOpsManager.MODE_ALLOWED);
return this;
}
/**
* 禁止OP权限
*
* @param packageName
* @param opCode
* @return
*/
public SystemApi denyOp(String packageName, int opCode) {
setOpMode(packageName, opCode, AppOpsManager.MODE_IGNORED);
return this;
}
public SystemApi allowOp(String packageName, int opCode, boolean isAllow) {
if (isAllow) {
allowOp(packageName, opCode);
} else {
denyOp(packageName, opCode);
}
return this;
}
/**
* 是否允许OP
*
* @param packageName
* @param opCode
* @return
*/
public boolean isOpAllowed(String packageName, int opCode) {
return getOpMode(packageName, opCode) == AppOpsManager.MODE_ALLOWED;
}
/**
* 获取OP模式
*
* @param packageName
* @param opCode
* @return
*/
public int getOpMode(String packageName, int opCode) {
try {
Object object = mContext.getSystemService(Context.APP_OPS_SERVICE);
if (object == null) {
return AppOpsManager.MODE_ALLOWED;
}
Class localClass = object.getClass();
Class[] arrayOfClass = new Class[3];
arrayOfClass[0] = Integer.TYPE;
arrayOfClass[1] = Integer.TYPE;
arrayOfClass[2] = String.class;
Method method = localClass.getMethod("checkOpNoThrow", arrayOfClass);
if (method == null) {
return OP_MODE_INVALID;
}
Object[] arrayOfObject = new Object[3];
arrayOfObject[0] = Integer.valueOf(opCode);
arrayOfObject[1] = Integer.valueOf(getPackageUid(packageName));
arrayOfObject[2] = packageName;
int m = ((Integer) method.invoke(object, arrayOfObject)).intValue();
return m;
} catch (Exception e) {
printError(e);
}
return OP_MODE_INVALID;
}
/**
* 允许禁止悬浮窗权限
*
* @param packageName
* @return
*/
public SystemApi allowDrawOverlays(String packageName, boolean isAllow) {
if (needRuntimePermission()) {
setOpState(packageName, OP_SYSTEM_ALERT_WINDOW, isAllow);
}
return this;
}
/**
* 是否允许悬浮窗
*
* @param packageName
* @return
*/
public boolean isDrawOverlaysAllowed(String packageName) {
return isOpAllowed(packageName, OP_SYSTEM_ALERT_WINDOW);
}
/**
* 允许禁止修改设置权限
*
* @param packageName
* @return
*/
public SystemApi allowWriteSettings(String packageName, boolean isAllow) {
if (needRuntimePermission()) {
setOpState(packageName, OP_WRITE_SETTINGS, isAllow);
}
return this;
}
/**
* 是否允许修改设置
*
* @param packageName
* @return
*/
public boolean isWriteSettingsAllowed(String packageName) {
return isOpAllowed(packageName, OP_WRITE_SETTINGS);
}
/**
* 允许禁止查看应用统计
*
* @param packageName
* @return
*/
public SystemApi allowUsageStats(String packageName, boolean isAllow) {
setOpState(packageName, OP_GET_USAGE_STATS, isAllow);
return this;
}
/**
* 是否允许查看应用统计
*
* @param packageName
* @return
*/
public boolean isUsageStatsAllowed(String packageName) {
return isOpAllowed(packageName, OP_GET_USAGE_STATS);
}
/**
* 允许禁止投屏
*
* @param packageName
* @return
*/
public SystemApi allowProjectMedia(String packageName, boolean isAllow) {
setOpState(packageName, OP_PROJECT_MEDIA, isAllow);
return this;
}
/**
* 是否允许投屏
*
* @param packageName
* @return
*/
public boolean isProjectMediaAllowed(String packageName) {
return isOpAllowed(packageName, OP_PROJECT_MEDIA);
}
/**
* 允许安装包,android11会被系统杀死
*
* @param packageName
* @param isAllow
* @return
*/
public SystemApi allowInstallPackage(String packageName, boolean isAllow) {
if (Build.VERSION.SDK_INT < 30) {
//android10及以下
setOpState(packageName, OP_REQUEST_INSTALL_PACKAGES, isAllow);
}
return this;
}
/**
* 是否允许安装包
*
* @param packageName
* @return
*/
public boolean isInstallPackageAllowed(String packageName) {
return isOpAllowed(packageName, OP_REQUEST_INSTALL_PACKAGES);
}
/**
* 允许禁止无障碍
*
* @param packageName
* @param className
* @param allow
* @return
*/
public SystemApi allowAccessibility(String packageName, String className, boolean allow) {
if (!isSupportAccessibility()) return this;
boolean hasService = isAccessibilityServiceEnabled(packageName, className);
String srcServiceName = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
String myServiceName = packageName + "/" + className;
if (allow) {
if (!hasService) {
int enabled = 0;
try {
enabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
} catch (Throwable e) {
printError(e);
}
if (enabled == 0) {
try {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, 1);
} catch (Throwable e) {
printError(e);
}
}
if (srcServiceName == null || srcServiceName.trim().isEmpty()) {
srcServiceName = myServiceName;
} else {
srcServiceName = srcServiceName + ":" + myServiceName;
}
try {
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, makeSettingsValue(srcServiceName));
} catch (Throwable e) {
e.printStackTrace();
}
}
} else {
if (hasService) {
if (srcServiceName.equals(myServiceName)) {
srcServiceName = "";
} else {
if (srcServiceName.endsWith(myServiceName)) {
srcServiceName = srcServiceName.replace(":" + myServiceName, "");
} else {
srcServiceName = srcServiceName.replace(myServiceName + ":", "");
}
}
if (srcServiceName.isEmpty()) {
srcServiceName = "\"\"";
}
try {
Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, makeSettingsValue(srcServiceName));
} catch (Throwable e) {
printError(e);
}
}
}
return this;
}
/**
* 允许禁止无障碍
*
* @param service
* @param allow
* @return
*/
public SystemApi allowAccessibility(Class<? extends AccessibilityService> service, boolean allow) {
allowAccessibility(mContext.getPackageName(), service.getName(), allow);
return this;
}
/**
* 允许禁止无障碍
*
* @param service
* @param allow
* @return
*/
public SystemApi allowAccessibility(ComponentName service, boolean allow) {
allowAccessibility(service.getPackageName(), service.getClassName(), allow);
return this;
}
/**
* 允许禁止设备管理器
*
* @param packageName
* @param className
* @param allow
* @return
*/
public SystemApi allowDeviceAdmin(String packageName, String className, boolean allow) {
allowDeviceAdmin(new ComponentName(packageName, className), allow);
return this;
}
public SystemApi allowDeviceAdmin(String componentName, boolean allow) {
allowDeviceAdmin(parse(componentName), allow);
return this;
}
/**
* 允许禁止设备管理器
*
* @param activeAdmin
* @param allow
* @return
*/
public SystemApi allowDeviceAdmin(Class<? extends DeviceAdminReceiver> activeAdmin, boolean allow) {
allowDeviceAdmin(new ComponentName(mContext, activeAdmin), allow);
return this;
}
/**
* 允许禁止设备管理器
*
* @param activeAdmin
* @param allow
* @return
*/
public SystemApi allowDeviceAdmin(ComponentName activeAdmin, boolean allow) {
if (activeAdmin == null) return this;
if (!isSupportDeviceAdmin()) return this;
if (allow) {
try {
Method method = DevicePolicyManager.class.getMethod("setActiveAdmin", ComponentName.class, boolean.class);
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Service.DEVICE_POLICY_SERVICE);
method.invoke(dpm, activeAdmin, true);
} catch (Exception e) {
printError(e);
}
} else {
try {
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Service.DEVICE_POLICY_SERVICE);
dpm.removeActiveAdmin(activeAdmin);
} catch (Exception e) {
printError(e);
}
}
return this;
}
/**
* 是否支持设备管理器
*
* @return
*/
public static boolean isSupportDeviceAdmin() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}
/**
* 是否支持无障碍
*
* @return
*/
public static boolean isSupportAccessibility() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.DONUT;
}
/**
* 是否需要请求权限
*
* @return
*/
public static boolean needRuntimePermission() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
/**
* 是否启用无障碍
*
* @param pkgName
* @param className
* @return
*/
public boolean isAccessibilityServiceEnabled(String pkgName, String className) {
if (!isSupportAccessibility()) {
return false;
}
if (isEmpty(pkgName) || isEmpty(className)) {
return false;
}
try {
int enabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
if (enabled == 1) {
String service = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (className.startsWith(".")) {
className = pkgName + className;
}
String myServiceName = pkgName + "/" + className;
boolean hasService = service != null && service.contains(myServiceName);
return hasService;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 是否启用无障碍
*
* @param serviceClass
* @return
*/
public boolean isAccessibilityServiceEnabled(Class<? extends AccessibilityService> serviceClass) {
return isAccessibilityServiceEnabled(mContext.getPackageName(), serviceClass.getCanonicalName());
}
/**
* 是否启用无障碍
*
* @param service
* @return
*/
public boolean isAccessibilityServiceEnabled(ComponentName service) {
return isAccessibilityServiceEnabled(service.getPackageName(), service.getClassName());
}
/**
* 是否是设备管理器
*
* @param admin
* @return
*/
public boolean isDeviceAdmin(ComponentName admin) {
if (!isSupportDeviceAdmin()) {
return false;
}
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Service.DEVICE_POLICY_SERVICE);
return dpm.isAdminActive(admin);
}
/**
* 是否是设备管理器
*
* @param pkgName
* @param className
* @return
*/
public boolean isDeviceAdmin(String pkgName, String className) {
return isDeviceAdmin(new ComponentName(pkgName, className));
}
/**
* 是否是设备管理器
*
* @param receiverClass
* @return
*/
public boolean isDeviceAdmin(Class<? extends DeviceAdminReceiver> receiverClass) {
return isDeviceAdmin(new ComponentName(mContext, receiverClass));
}
/**
* 设置设备所有者
*
* @param pkgName
* @return
*/
public boolean setDeviceOwner(String pkgName) {
if (!isSupportDeviceAdmin()) {
return false;
}
ComponentName admin = getDeviceAdminClass(mContext, pkgName);
if (admin == null) {
return false;
}
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Service.DEVICE_POLICY_SERVICE);
try {
Method method = dpm.getClass().getMethod("setDeviceOwner", ComponentName.class);
return (boolean) method.invoke(dpm, admin);
} catch (Exception e) {
printError("setDeviceOwner", e);
}
return false;
}
/**
* 移除设备所有者
*
* @param pkgName
*/
public void removeDeviceOwner(String pkgName) {
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Service.DEVICE_POLICY_SERVICE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
dpm.clearDeviceOwnerApp(pkgName);
}
} catch (Exception e) {
printError(e);
}
}
/**
* 是否设备所有者
*
* @param pkgName
* @return
*/
public boolean isDeviceOwner(String pkgName) {
if (!isSupportDeviceAdmin()) {
return false;
}
DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(Service.DEVICE_POLICY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
return dpm.isDeviceOwnerApp(pkgName);
}
return false;
}
/**
* 设置包状态
*
* @param packageName
* @param state PackageManager.COMPONENT_
*/
public boolean setPackageState(String packageName, int state) {
try {
Log.d(TAG, "setPackageState: " + packageName + ", state=" + state);
mContext.getPackageManager().setApplicationEnabledSetting(packageName, state, 0);
return true;
} catch (Exception e) {
printError(e);
}
return false;
}
/**
* 获取包状态
*
* @param packageName
* @return
*/
public int getPackageState(String packageName) {
try {
return mContext.getPackageManager().getApplicationEnabledSetting(packageName);
} catch (Exception e) {
printError(e);
}
return ERROR_COMPONENT_STATE;
}
/**
* 设置组件状态
*
* @param componentName
* @param state:PackageManager.COMPONENT_
*/
public boolean setComponentState(ComponentName componentName, int state) {
try {
Log.d(TAG, "setComponentEnabledSetting: " + componentName.toShortString() + ", state=" + state);
mContext.getPackageManager().setComponentEnabledSetting(componentName, state, 0);
return true;
} catch (Exception e) {
printError("setComponentState", e);
}
return false;
}
/**
* 获取组件状态
*
* @param componentName
* @return
*/
public int getComponentState(ComponentName componentName) {
try {
return mContext.getPackageManager().getComponentEnabledSetting(componentName);
} catch (Exception e) {
printError(e);
}
return ERROR_COMPONENT_STATE;
}
/**
* 设置组件状态
*
* @param packageName
* @param className
* @param state:PackageManager.COMPONENT_
*/
public boolean setComponentState(String packageName, String className, int state) {
return setComponentState(new ComponentName(packageName, className), state);
}
/**
* 禁止包
*
* @param packageName
* @param disable true:禁止,false:恢复默认
*/
public boolean disablePackage(String packageName, boolean disable) {
return setPackageState(packageName, disable ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
}
/**
* 判断包是否禁止
*
* @param packageName
* @return
*/
public boolean isPackageDisabled(String packageName) {
int state = getPackageState(packageName);
return state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
}
/**
* 启用包
*
* @param packageName
* @return
*/
public boolean enablePackage(String packageName) {
return setPackageState(packageName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
}
/**
* 禁止组件
*
* @param componentName
* @param disable
*/
public boolean disableComponent(ComponentName componentName, boolean disable) {
return setComponentState(componentName, disable ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
}
/**
* 禁止组件
*
* @param packageName
* @param className
* @param disable true:禁止,false:恢复默认
*/
public boolean disableComponent(String packageName, String className, boolean disable) {
if (className != null && className.startsWith(".")) {
className = packageName + className;
}
return disableComponent(new ComponentName(packageName, className), disable);
}
/**
* 禁止组件
*
* @param componentName
* @param disable
*/
public void disableComponent(String componentName, boolean disable) {
int start = componentName.indexOf('/');
if (start != -1) {
disableComponent(componentName.substring(0, start), componentName.substring(start + 1), disable);
}
}
/**
* 启用组件
*
* @param componentName
* @return
*/
public boolean enableComponent(ComponentName componentName) {
return setComponentState(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
}
/**
* 启用组件
*
* @param packageName
* @param className
* @return
*/
public boolean enableComponent(String packageName, String className) {
return enableComponent(new ComponentName(packageName, className));
}
/**
* 判断组件是否禁止
*
* @param componentName
* @return
*/
public boolean isComponentDisabled(ComponentName componentName) {
int state = getComponentState(componentName);
return state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|| state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
}
/**
* 判断组件是否禁止
*
* @param packageName
* @param className
* @return
*/
public boolean isComponentDisabled(String packageName, String className) {
return isComponentDisabled(new ComponentName(packageName, className));
}
/**
* 隐藏包
*
* @param packageName
* @param hidden
*/
public void hideApplication(String packageName, boolean hidden) {
try {
Method method = PackageManager.class.getMethod("setApplicationHiddenSettingAsUser", String.class, boolean.class, UserHandle.class);
PackageManager pm = mContext.getPackageManager();
method.invoke(pm, packageName, hidden, newUserHandler(0));
} catch (Exception e) {
printError(e);
}
}
/**
* 判断包是否隐藏
*
* @param packageName
* @return
*/
public boolean isApplicationHidden(String packageName) {
try {
Method method = PackageManager.class.getMethod("getApplicationHiddenSettingAsUser", String.class, UserHandle.class);
PackageManager pm = mContext.getPackageManager();
return (boolean) method.invoke(pm, packageName, newUserHandler(0));
} catch (Exception e) {
printError(e);
}
return false;
}
/*public String[] suspendPackage(String[] packageNames, boolean suspended) {
try {
Method method = PackageManager.class.getMethod("setPackagesSuspendedAsUser", String[].class, boolean.class, int.class);
PackageManager pm = mContext.getPackageManager();
return (String[]) method.invoke(pm, packageNames, suspended, 0);
} catch (Exception e) {
printError(e);
}
return null;
}*/
/**
* 杀死应用
*
* @param packageName
*/
public void forceStopPackage(String packageName) {
try {
Method method = ActivityManager.class.getMethod("forceStopPackage", String.class);
ActivityManager am = (ActivityManager) mContext.getSystemService(Service.ACTIVITY_SERVICE);
method.invoke(am, packageName);
} catch (Exception e) {
printError(e);
}
}
/**
* 清除应用数据
*
* @param packageName
* @return
*/
public boolean clearApplicationData(String packageName) {
boolean isSuccess = false;
IPackageDataObserver.Stub mStub = new IPackageDataObserver.Stub() {
public void onRemoveCompleted(String paramAnonymousString, boolean paramAnonymousBoolean) {
}
};
try {
Method method = ActivityManager.class.getMethod("clearApplicationUserData", String.class, IPackageDataObserver.class);
ActivityManager am = (ActivityManager) mContext.getSystemService(Service.ACTIVITY_SERVICE);
isSuccess = (boolean) method.invoke(am, packageName, mStub);
} catch (Exception e) {
printError(e);
}
return isSuccess;
}
/**
* 清除应用缓存
*
* @param packageName
*/
public void clearApplicationCache(String packageName) {
IPackageDataObserver.Stub mStub = new IPackageDataObserver.Stub() {
public void onRemoveCompleted(String paramAnonymousString, boolean paramAnonymousBoolean) {
}
};
try {
Method method = PackageManager.class.getMethod("deleteApplicationCacheFiles", String.class, IPackageDataObserver.class);
PackageManager pm = mContext.getPackageManager();
method.invoke(pm, packageName, mStub);
} catch (Exception e) {
printError(e);
}
}
/**
* 安装应用
*
* @param path
*/
public void installPackage(final String path, final OnPackageInstallListener listener) {
// Toast.makeText(mContext, "path="+ path, Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT < 28) {
IPackageInstallObserver.Stub mStub = new IPackageInstallObserver.Stub() {
@Override
public void packageInstalled(String packageName, int returnCode) throws RemoteException {
if (listener != null)
listener.onPackageInstalled(packageName, returnCode == INSTALL_SUCCEEDED ? STATUS_SUCCESS : STATUS_FAILURE);
}
};
try {
Method method = PackageManager.class.getMethod("installPackage", Uri.class, IPackageInstallObserver.class, int.class, String.class);
PackageManager pm = mContext.getPackageManager();
Uri uri = Uri.fromFile(new File(path));
method.invoke(pm, uri, mStub, INSTALL_REPLACE_EXISTING, null);
} catch (Exception e) {
printError(e);
if (listener != null) {
listener.onPackageInstalled(null, STATUS_FAILURE);
}
}
} else {
installPackageFromQ(path, listener);
}
}
public int installExistingPackage(String packageName) {
try {
Method method = PackageManager.class.getMethod("installExistingPackage", String.class);
PackageManager pm = mContext.getPackageManager();
return (int) method.invoke(pm, packageName);
} catch (Exception e) {
printError(e);
}
return -1;
}
/**
* 安装应用
*
* @param path
*/
public void installPackage(String path) {
installPackage(path, null);
}
public boolean launchApplication(String packageName) {
try {
Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 卸载应用
*
* @param packageName
*/
public void deletePackage(String packageName, boolean isDeleteSystemApp, final OnPackageDeleteListener listener) {
IPackageDeleteObserver.Stub mStub = new IPackageDeleteObserver.Stub() {
@Override
public void packageDeleted(String packageName, int returnCode) throws RemoteException {
if (listener != null) {
listener.onPackageDeleted(packageName, returnCode == DELETE_SUCCEEDED ? STATUS_SUCCESS : STATUS_FAILURE);
}
}
};
try {
Method method = PackageManager.class.getMethod("deletePackage", String.class, IPackageDeleteObserver.class, int.class);
PackageManager pm = mContext.getPackageManager();
method.invoke(pm, packageName, mStub, isDeleteSystemApp ? DELETE_SYSTEM_APP : 0);
} catch (Exception e) {
printError(e);
}
}
/**
* 卸载应用
*
* @param packageName
*/
public void deletePackage(String packageName, final OnPackageDeleteListener listener) {
deletePackage(packageName, false, listener);
}
/**
* 卸载应用
*
* @param packageName
*/
public void deletePackage(String packageName) {
deletePackage(packageName, null);
}
/**
* 卸载应用
*
* @param packageName
*/
public void deletePackage(String packageName, boolean isDeleteSystemApp) {
deletePackage(packageName, isDeleteSystemApp, null);
}
/**
* 重启
*/
public void reboot() {
PowerManager pm = (PowerManager) mContext.getSystemService(Service.POWER_SERVICE);
try {
pm.reboot("");
} catch (Exception e) {
printError(e);
}
}
/**
* 关机
*/
public void shutdown() {
try {
Method method = PowerManager.class.getMethod("shutdown", boolean.class, String.class, boolean.class);
PowerManager pm = (PowerManager) mContext.getSystemService(Service.POWER_SERVICE);
method.invoke(pm, false, "", false);
} catch (Exception e) {
printError(e);
}
}
/**
* 恢复出厂设置
*/
public void wipeData() {
if (Build.VERSION.SDK_INT >= 26) {
//8.0以上
Intent intent = new Intent(ACTION_FACTORY_RESET);
intent.setPackage("android");
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(EXTRA_REASON, "MasterClearConfirm");
intent.putExtra(EXTRA_WIPE_EXTERNAL_STORAGE, true);
mContext.sendBroadcast(intent);
} else {
Intent intent = new Intent(ACTION_MASTER_CLEAR);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.putExtra(EXTRA_REASON, "MasterClearConfirm");
intent.putExtra(EXTRA_WIPE_EXTERNAL_STORAGE, true);
mContext.sendBroadcast(intent);
}
// try {
// RecoverySystem.rebootWipeUserData(mContext);
// } catch (IOException e) {
// e.printStackTrace();
// }
}
/**
* 设置系统时间
*
* @param time
*/
public void setSystemTime(long time) {
try {
AlarmManager am = (AlarmManager) mContext.getSystemService(Service.ALARM_SERVICE);
am.setTime(time);
} catch (Throwable e) {
printError(e);
}
}
/**
* 执行shell命令
*
* @param command
*/
public void execSync(String command) {
Process process = null;
try {
process = Runtime.getRuntime().exec(command);
process.waitFor();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (process != null) {
process.destroy();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 执行shell命令
*
* @param command
*/
public void exec(final String command) {
new Thread() {
@Override
public void run() {
super.run();
execSync(command);
}
}.start();
}
/**
* 设置主线程处理
*
* @param mHandler
*/
public void setUiHandler(Handler mHandler) {
this.mHandler = mHandler;
}
/**
* 禁止状态栏展开
*
* @param disable
*/
public void disableStatusBarExpand(boolean disable) {
try {
@SuppressLint("WrongConstant") Object service = mContext.getSystemService("statusbar");
Class<?> c = Class.forName("android.app.StatusBarManager");
Method method = c.getMethod("disable2", int.class);
method.invoke(service, disable ? DISABLE2_MASK : 0);
} catch (Exception e) {
printError(e);
}
}
/**
* 禁止系统界面
*
* @param statusbar
* @param notificationBar
* @param home
* @param back
* @param recent
*/
public void disableSystemUI(boolean statusbar, boolean notificationBar, boolean home, boolean back, boolean recent) {
int value = 0;
if (statusbar) value |= 0x00010000;
if (notificationBar) value |= (0x00020000 | 0x00040000 | 0x00080000);
if (home) value |= 0x00200000;
if (back) value |= 0x00400000;
if (recent) value |= 0x01000000;
disableSystemUI(value);
}
public void disableSystemUI(int state) {
try {
@SuppressLint("WrongConstant") Object service = mContext.getSystemService("statusbar");
Class<?> c = Class.forName("android.app.StatusBarManager");
Method method = c.getMethod("disable", int.class);
method.invoke(service, state);
} catch (Exception e) {
printError(e);
}
}
public void disableSystemUIEx(int state) {
try {
@SuppressLint("WrongConstant") Object service = mContext.getSystemService("statusbar");
Class<?> c = Class.forName("android.app.StatusBarManager");
Method method = c.getMethod("disable2", int.class);
method.invoke(service, state);
} catch (Exception e) {
printError(e);
}
}
/**
* 设置usb功能
*
* @param function
*/
public void setUsbFunction(String function) {
UsbManager um = (UsbManager) mContext.getSystemService(Service.USB_SERVICE);
if (Build.VERSION.SDK_INT < 26) {
//8.0以下
try {
Method setCurrentFunction = um.getClass().getMethod("setCurrentFunction", String.class);
setCurrentFunction.invoke(um, function);
Method setUsbDataUnlocked = um.getClass().getMethod("setUsbDataUnlocked", boolean.class);
if (function != null && function.equals("none")) {
setUsbDataUnlocked.invoke(um, false);
} else {
setUsbDataUnlocked.invoke(um, true);
}
} catch (Exception e) {
printError(e);
}
} else {
//8.0以上
try {
Method setCurrentFunction = um.getClass().getMethod("setCurrentFunction", String.class, boolean.class);
if (function != null && function.equals("none")) {
setCurrentFunction.invoke(um, function, false);
} else {
setCurrentFunction.invoke(um, function, true);
}
} catch (Exception e) {
printError(e);
}
}
}
/**
* 设置用户限制
*
* @param key
* @param value
*/
public void setUserRestriction(String key, boolean value) {
UserManager um = (UserManager) mContext.getSystemService(Service.USER_SERVICE);
try {
Method method = um.getClass().getMethod("setUserRestriction", String.class, boolean.class);
method.invoke(um, key, value);
} catch (Exception e) {
printError(e);
}
}
/**
* 是否有用户限制
*
* @param key
* @return
*/
public boolean hasUserRestriction(String key) {
UserManager um = (UserManager) mContext.getSystemService(Service.USER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
return um.hasUserRestriction(key);
} catch (Exception e) {
printError(e);
}
}
return false;
}
/**
* 权限转OP代码
*
* @param permission
* @return
*/
public int permissionToOpCode(String permission) {
AppOpsManager manager = (AppOpsManager) mContext.getSystemService(Service.APP_OPS_SERVICE);
try {
Method method = manager.getClass().getMethod("permissionToOpCode", String.class);
return (int) method.invoke(manager, permission);
} catch (Exception e) {
printError(e);
}
return -1;
}
/**
* 禁止卸载应用
*
* @param packageName
* @param block
* @return
*/
public boolean setBlockUninstall(String packageName, boolean block) {
Object mPm = getIPackageManager();
if (mPm == null) return false;
try {
Method method = mPm.getClass().getMethod("setBlockUninstallForUser", String.class, boolean.class, int.class);
return (boolean) method.invoke(mPm, packageName, block, 0);
} catch (Exception e) {
printError(e);
}
return false;
}
/**
* 是否禁止卸载应用
*
* @param packageName
* @return
*/
public boolean isUninstallBlocked(String packageName) {
Object mPm = getIPackageManager();
if (mPm == null) return false;
try {
Method method = mPm.getClass().getMethod("getBlockUninstallForUser", String.class, int.class);
return (boolean) method.invoke(mPm, packageName, 0);
} catch (Exception e) {
printError(e);
}
return false;
}
/**
* 设置默认桌面
*
* @param launcher
*/
public void setHomeLauncher(ComponentName launcher) {
Object mPm = getIPackageManager();
if (mPm == null) return;
try {
Method method = mPm.getClass().getMethod("setHomeActivity", ComponentName.class, int.class);
method.invoke(mPm, launcher, 0);
} catch (Exception e) {
printError(e);
}
}
/**
* 设置默认桌面
*
* @param packageName
* @param className
*/
public void setHomeLauncher(String packageName, String className) {
setHomeLauncher(new ComponentName(packageName, className));
}
/**
* 设置默认桌面
*
* @param packageName
*/
public boolean setHomeLauncher(String packageName) {
if (packageName == null) return false;
List<ComponentName> launchers = new ArrayList<>();
getHomeLauncherList(launchers);
for (ComponentName launcher : launchers) {
if (launcher.getPackageName().equals(packageName)) {
setHomeLauncher(launcher);
return true;
}
}
return false;
}
/**
* 获取默认桌面
*
* @return
*/
public ComponentName getHomeLauncher() {
List<ComponentName> mList = new ArrayList<>();
return getHomeLauncherList(mList);
}
/**
* 获取默认桌面包名
*
* @return
*/
public String getHomeLauncherPackage() {
ComponentName launcher = getHomeLauncher();
return launcher != null ? launcher.getPackageName() : null;
}
/**
* 清除默认桌面
*/
public void clearHomeLauncher() {
ComponentName launcher = getHomeLauncher();
if (launcher != null) {
try {
mContext.getPackageManager().clearPackagePreferredActivities(launcher.getPackageName());
} catch (Exception e) {
printError(e);
}
}
}
/**
* 获取桌面列表,返回默认桌面
*
* @param launchers
* @return
*/
public ComponentName getHomeLauncherList(List<ComponentName> launchers) {
if (launchers == null) return null;
try {
PackageManager pm = mContext.getPackageManager();
Method method = pm.getClass().getMethod("getHomeActivities", List.class);
List<ResolveInfo> resolveInfos = new ArrayList<>();
ComponentName defaultLauncher = (ComponentName) method.invoke(pm, resolveInfos);
for (ResolveInfo resolveInfo : resolveInfos) {
if (resolveInfo.activityInfo != null
&& hasValue(resolveInfo.activityInfo.packageName)
&& hasValue(resolveInfo.activityInfo.name)) {
launchers.add(new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name));
}
}
return defaultLauncher;
} catch (Exception e) {
printError(e);
}
return null;
}
/**
* 禁用sim卡
*/
public void disableMobileRadios() {
IInterface mIPhone = getAIDLService("phone", "com.android.internal.telephony.ITelephony");
try {
Method method = mIPhone.getClass().getMethod("shutdownMobileRadios");
method.invoke(mIPhone);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置电源保护模式
*
* @param mode
* @return
*/
public boolean setPowerSaveMode(int mode) {
try {
IInterface mIPowerManagerEx = getAIDLService("power_ex", "android.os.IPowerManagerEx");
Method setPowerSaveMode = mIPowerManagerEx.getClass().getMethod("setPowerSaveMode", int.class);
return (boolean) setPowerSaveMode.invoke(mIPowerManagerEx, mode);
} catch (Exception e) {
printError(e);
}
return false;
}
/**
* 添加电源优化白名单
*
* @param packageName
*/
public void addPowerSaveWhiteApp(String packageName) {
IInterface mIDeviceIdleController = getAIDLService("deviceidle", "android.os.IDeviceIdleController");
if (mIDeviceIdleController != null) {
try {
Method method = mIDeviceIdleController.getClass().getMethod("addPowerSaveWhitelistApp", String.class);
method.invoke(mIDeviceIdleController, packageName);
} catch (Exception e) {
printError(e);
}
}
}
/**
* 移除电源优化白名单
*
* @param packageName
*/
public void removePowerSaveWhiteApp(String packageName) {
IInterface mIDeviceIdleController = getAIDLService("deviceidle", "android.os.IDeviceIdleController");
if (mIDeviceIdleController != null) {
try {
Method method = mIDeviceIdleController.getClass().getMethod("removePowerSaveWhitelistApp", String.class);
method.invoke(mIDeviceIdleController, packageName);
} catch (Exception e) {
printError(e);
}
}
}
/**
* 是否电源优化白名单
*
* @param packageName
* @return
*/
public boolean isPowerSaveWhiteApp(String packageName) {
IInterface mIDeviceIdleController = getAIDLService("deviceidle", "android.os.IDeviceIdleController");
if (mIDeviceIdleController != null) {
try {
Method method = mIDeviceIdleController.getClass().getMethod("isPowerSaveWhitelistApp", String.class);
return (boolean) method.invoke(mIDeviceIdleController, packageName);
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
/**
* 挂载外部存储
*/
public void mountExternalStorage() {
StorageManager sm = (StorageManager) mContext.getSystemService(Service.STORAGE_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
List<StorageVolume> volumes = sm.getStorageVolumes();
if (volumes != null) {
for (StorageVolume volume : volumes) {
try {
if (!volume.isPrimary()) {
String volumeId = (String) volume.getClass().getMethod("getId").invoke(volume);
sm.getClass().getMethod("mount", String.class).invoke(sm, volumeId);
}
//print("挂载外部存储成功");
} catch (Exception e) {
e.printStackTrace();
printError(e);
//print("挂载外部存储失败");
}
}
}
}
}
/**
* 卸载外部存储
*/
public void unmountExternalStorage() {
StorageManager sm = (StorageManager) mContext.getSystemService(Service.STORAGE_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
List<StorageVolume> volumes = sm.getStorageVolumes();
if (volumes != null) {
for (StorageVolume volume : volumes) {
try {
if (!volume.isPrimary()) {
String volumeId = (String) volume.getClass().getMethod("getId").invoke(volume);
sm.getClass().getMethod("unmount", String.class).invoke(sm, volumeId);
}
//print("卸载外部存储成功");
} catch (Exception e) {
e.printStackTrace();
printError(e);
//print("卸载外部存储失败");
}
}
}
}
}
/**
* 截屏
*
* @return
*/
public Bitmap screenshot() {
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
if (Build.VERSION.SDK_INT >= 31) {
//android 12
VirtualDisplay virtualDisplay = null;
ImageReader reader = null;
Image image = null;
try {
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getRealMetrics(metrics);
DisplayManager dm = (DisplayManager) mContext.getSystemService(Service.DISPLAY_SERVICE);
reader = ImageReader.newInstance(metrics.widthPixels, metrics.heightPixels, PixelFormat.RGBA_8888, 1);
virtualDisplay = dm.createVirtualDisplay("launcher3_screen", metrics.widthPixels, metrics.heightPixels, metrics.densityDpi, reader.getSurface(),
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR);
int count = 0;
while (image == null) {
Thread.sleep(50);
image = reader.acquireLatestImage();
if (++count > 10) {
break;
}
}
if (image != null) {
int width = image.getWidth();
int height = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
return bitmap;
}
} catch (Throwable e) {
printError("screenshot", e);
} finally {
try {
if (image != null) {
image.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
try {
if (virtualDisplay != null) {
virtualDisplay.release();
}
} catch (Exception e2) {
e2.printStackTrace();
}
try {
if (reader != null) {
reader.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
} else {
try {
Class c = Class.forName("android.view.SurfaceControl");
// if (Build.VERSION.SDK_INT >= 31) {
// /*Class CDisplayCaptureArgs = Class.forName("android.view.SurfaceControl$DisplayCaptureArgs");
// Method method = c.getDeclaredMethod("captureDisplay", CDisplayCaptureArgs);
// method.setAccessible(true);
// Object mScreenshotHardwareBuffer = method.invoke(c, null);
// Log.i(TAG, "screenshot" + (mScreenshotHardwareBuffer == null));*/
// } else {
//
// }
Method method = c.getMethod("screenshot", Rect.class, int.class, int.class, int.class);
return (Bitmap) method.invoke(c, new Rect(), 0, 0, wm.getDefaultDisplay().getRotation());
} catch (Exception e) {
printError("screenshot", e);
}
}
return null;
}
public Bitmap screenshotHw() {
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
Class c = null;
try {
c = Class.forName("android.view.SurfaceControl");
Method method = c.getMethod("screenshot_ext_hw", Rect.class, int.class, int.class, int.class);
return (Bitmap) method.invoke(c, new Rect(0, 0, 2000, 1200), 2000, 1200, wm.getDefaultDisplay().getRotation());
} catch (Throwable e) {
printError(e);
}
return null;
}
public Bitmap screenshot(int minLayer, int maxLayer) {
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
try {
Class c = Class.forName("android.view.SurfaceControl");
Method method = c.getMethod("screenshot", Rect.class, int.class, int.class, int.class, int.class, boolean.class, int.class);
return (Bitmap) method.invoke(c, new Rect(), 0, 0, minLayer, maxLayer, true, wm.getDefaultDisplay().getRotation());
} catch (Exception e) {
printError(e);
}
return null;
}
/**
* 设置防火墙模式
*
* @param isWhiteMode
*/
public void setFirewallMode(boolean isWhiteMode) {
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
for (int i = 0; i <= 3; i++) {
try {
Method setFirewallChainEnabled = mINetworkManagementService.getClass().getDeclaredMethod("setFirewallChainEnabled", int.class, boolean.class);
setFirewallChainEnabled.invoke(mINetworkManagementService, i, isWhiteMode);
} catch (Exception e) {
printError(e);
}
}
}
}
/**
* 设置防火墙规则
*
* @param packageName
* @param allow
*/
public void setFirewallPackageRule(String packageName, boolean allow) {
int uid = getPackageUid(packageName);
if (uid <= 0) return;
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
for (int i = 0; i <= 3; i++) {
try {
Method method = mINetworkManagementService.getClass().getDeclaredMethod("setFirewallUidRule", int.class, int.class, int.class);
method.invoke(mINetworkManagementService, i, uid, allow ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DENY);
} catch (Exception e) {
printError("setFirewallPackageRule", e);
}
}
}
}
/**
* 设置防火墙规则 <=android9.0
*
* @param packageNames
* @param allow
*/
public void setFirewallPackageRules(List<String> packageNames, boolean allow) {
if (packageNames == null || packageNames.isEmpty()) return;
int size = packageNames.size();
int[] uids = new int[size];
int[] rules = new int[size];
int allowValue = allow ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DENY;
for (int i = 0; i < size; i++) {
uids[i] = getPackageUid(packageNames.get(i));
rules[i] = allowValue;
print(uids[i], rules[i]);
}
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
for (int i = 0; i <= 3; i++) {
try {
Method method = mINetworkManagementService.getClass().getDeclaredMethod("setFirewallUidRules", int.class, int[].class, int[].class);
method.invoke(mINetworkManagementService, i, uids, rules);
} catch (Exception e) {
e.printStackTrace();
print("setFirewallPackageRules", e);
}
}
}
}
/**
* 设置防火墙状态
*
* @param enabled
*/
public void setFirewallEnabled(boolean enabled) {
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
try {
Method setFirewallEnabled = mINetworkManagementService.getClass().getDeclaredMethod("setFirewallEnabled", boolean.class);
setFirewallEnabled.invoke(mINetworkManagementService, enabled);
} catch (Exception e) {
printError(e);
}
}
}
/**
* 防火墙是否开启
*
* @return
*/
public boolean isFirewallEnabled() {
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
try {
Method isFirewallEnabled = mINetworkManagementService.getClass().getDeclaredMethod("isFirewallEnabled");
return (boolean) isFirewallEnabled.invoke(mINetworkManagementService);
} catch (Exception e) {
printError(e);
}
}
return false;
}
/**
* 设置ip转发是否可用
*
* @param enabled
*/
public void setIpForwardingEnabled(boolean enabled) {
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
try {
Method setIpForwardingEnabled = mINetworkManagementService.getClass().getDeclaredMethod("setIpForwardingEnabled", boolean.class);
setIpForwardingEnabled.invoke(mINetworkManagementService, enabled);
} catch (Exception e) {
printError(e);
}
}
}
/**
* ip转发是否能用
*
* @return
*/
public boolean isIpForwardingEnabled() {
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
try {
Method getIpForwardingEnabled = mINetworkManagementService.getClass().getDeclaredMethod("getIpForwardingEnabled");
return (boolean) getIpForwardingEnabled.invoke(mINetworkManagementService);
} catch (Exception e) {
printError(e);
}
}
return false;
}
/**
* 设置锁屏是否禁用
*/
public void setLockScreenDisabled(boolean disabled) {
Class c = null;
try {
c = Class.forName("com.android.internal.widget.LockPatternUtils");
Method method = c.getDeclaredMethod("setLockScreenDisabled", boolean.class, int.class);
method.setAccessible(true);
method.invoke(newInstance(c, new Class[]{Context.class}, mContext), disabled, 0);
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* 内部数据
*
*/
private static boolean hasElement(Collection c) {
return c != null && !c.isEmpty();
}
private static boolean hasElement(Object[] array) {
return array != null && array.length > 0;
}
private static boolean hasElement(Map map) {
return map != null && !map.isEmpty();
}
private static boolean hasValue(String value) {
return value != null && !value.isEmpty();
}
private static boolean isEmpty(String value) {
return !hasValue(value);
}
private static boolean isNumeric(String str) {
Pattern pattern = Pattern.compile("[0-9]*");
return pattern.matcher(str).matches();
}
private static boolean equalsValue(String v1, String v2) {
return v1 != null && v2 != null && v1.equals(v2);
}
private SystemApi setOpState(String packageName, int opCode, boolean isAllow) {
if (isAllow) {
setOpMode(packageName, opCode, AppOpsManager.MODE_ALLOWED);
} else {
setOpMode(packageName, opCode, AppOpsManager.MODE_IGNORED);
}
return this;
}
public boolean grantRuntimePermission(String packageName, String permission) {
try {
Method method = PackageManager.class.getMethod("grantRuntimePermission", String.class, String.class, UserHandle.class);
UserHandle userHandle = (UserHandle) newInstance(UserHandle.class, new Class[]{int.class}, 0);
method.invoke(mContext.getPackageManager(), packageName, permission, userHandle);
return true;
} catch (Exception e) {
printError(e);
}
return false;
}
public void revokeRuntimePermission(String packageName, String permission) {
try {
Method method = PackageManager.class.getMethod("revokeRuntimePermission", String.class, String.class, UserHandle.class);
UserHandle userHandle = (UserHandle) newInstance(UserHandle.class, new Class[]{int.class}, 0);
method.invoke(mContext.getPackageManager(), packageName, permission, userHandle);
} catch (Exception e) {
printError(e);
}
}
private int getPackageUid(String packageName) {
try {
PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName, PackageManager.GET_DISABLED_COMPONENTS);
if (info != null && info.applicationInfo != null) {
return info.applicationInfo.uid;
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
private String makeSettingsValue(String value) {
return value != null && !value.trim().isEmpty() ? value : "\"\"";
}
// public void unlockDevice() {
// try {
// IInterface mITurstManager = getAIDLService("trust", "android.app.trust.ITrustManager");
// Method method= mITurstManager.getClass().getMethod("setDeviceLockedForUser", int.class, boolean.class);
// method.invoke(mITurstManager, 0, false);
// } catch (Exception e) {
// printError("unlockDevice", e);
// }
//
// }
public interface OnPackageInstallListener {
void onPackageInstalled(String packageName, int returnCode);
}
public interface OnPackageDeleteListener {
void onPackageDeleted(String packageName, int returnCode);
}
private Set<String> getDeniedPermissionList(String packageName, String[] permissions) {
Set<String> mDeniedPermissionList = new HashSet<>();
PackageManager pm = mContext.getPackageManager();
for (String permission : permissions) {
int pmState = pm.checkPermission(permission, packageName);
int opMode = getOpMode(packageName, permissionToOpCode(permission));
boolean hasPermission = pmState == PackageManager.PERMISSION_GRANTED && (opMode == AppOpsManager.MODE_ALLOWED || opMode == AppOpsManager.MODE_DEFAULT);
if (!hasPermission) {
mDeniedPermissionList.add(permission);
}
}
return mDeniedPermissionList;
}
private Object newInstance(Class clazz, Class[] argsType, Object... args) {
Object instance = null;
try {
Constructor constructor = clazz.getConstructor(argsType);
constructor.setAccessible(true);
instance = constructor.newInstance(args);
} catch (Exception e) {
printError(e);
}
return instance;
}
private void print(Object... info) {
if (mLoggerEnabled || mDebug) {
if (info == null || info.length == 0) {
return;
}
StringBuilder sb = new StringBuilder();
for (Object o : info) {
sb.append(o != null ? o.toString() + ", " : ", ");
}
String msg = sb.toString();
if (msg.endsWith(",")) msg = sb.deleteCharAt(sb.length() - 1).toString();
Log.i(TAG, msg);
}
}
private void printError(Throwable e) {
printError(null, e);
}
private void printError(String tag, Throwable e) {
if (mLoggerEnabled || mDebug) {
if (e.getCause() != null) {
Log.e(TAG, (tag == null ? "" : tag + " error=") + e.getCause().toString());
} else {
Log.e(TAG, (tag == null ? "" : tag + " error=") + e.toString());
}
}
}
/**
* android9.0 安装应用
*
* @param path
* @param listener
*/
private void installPackageFromQ(final String path, final OnPackageInstallListener listener) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return;
}
int mSessionId = -1;
String packageName = null;
try {
PackageManager pm = mContext.getPackageManager();
PackageInfo packageInfo = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
if (packageInfo != null) {
packageName = packageInfo.packageName;
}
PackageInstaller packageInstaller = pm.getPackageInstaller();
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
File apkFile = new File(path);
print("apkFile length" + apkFile.length());
sessionParams.setSize(apkFile.length());
mSessionId = packageInstaller.createSession(sessionParams);
} catch (Throwable e) {
printError(e);
}
if (mSessionId != -1 && packageName != null) {
final int finalMSessionId = mSessionId;
final String finalPackageName = packageName;
new Thread() {
@Override
public void run() {
super.run();
boolean copySuccess = onTransfesApkFile(path, finalMSessionId);
if (copySuccess) {
if (mHandler != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
execInstallAPP(finalMSessionId, finalPackageName, listener);
}
});
} else {
execInstallAPP(finalMSessionId, finalPackageName, listener);
}
} else {
if (mHandler != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (listener != null) {
listener.onPackageInstalled(finalPackageName, STATUS_FAILURE);
}
}
});
} else {
if (listener != null) {
listener.onPackageInstalled(finalPackageName, STATUS_FAILURE);
}
}
}
}
}.start();
} else {
if (listener != null) {
listener.onPackageInstalled(packageName, STATUS_FAILURE);
}
}
}
private boolean onTransfesApkFile(String apkFilePath, int mSessionId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
InputStream in = null;
OutputStream out = null;
PackageInstaller.Session session = null;
boolean success = false;
try {
File apkFile = new File(apkFilePath);
session = mContext.getPackageManager().getPackageInstaller().openSession(mSessionId);
out = session.openWrite("base.apk", 0, apkFile.length());
in = new FileInputStream(apkFile);
int total = 0, c;
byte[] buffer = new byte[1024 * 1024];
while ((c = in.read(buffer)) != -1) {
total += c;
out.write(buffer, 0, c);
}
session.fsync(out);
success = true;
} catch (Throwable e) {
printError(e);
} finally {
if (null != session) {
session.close();
}
try {
if (null != out) {
out.close();
}
if (null != in) {
in.close();
}
} catch (Exception e) {
printError(e);
}
}
return success;
}
return false;
}
/**
* 执行安装并通知安装结果
*/
private void execInstallAPP(int mSessionId, final String packageName, final OnPackageInstallListener listener) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
PackageInstaller.Session session = null;
try {
session = mContext.getPackageManager().getPackageInstaller().openSession(mSessionId);
Intent intent = new Intent(mContext, new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
if (listener != null) {
listener.onPackageInstalled(packageName, status);
}
}
}
}.getClass());
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,
1, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
session.commit(pendingIntent.getIntentSender());
} catch (Exception e) {
printError(e);
printError(e);
if (listener != null) {
listener.onPackageInstalled(packageName, STATUS_FAILURE);
}
} finally {
if (null != session) {
session.close();
}
}
}
}
private ComponentName getDeviceAdminClass(Context context, String pkgName) {
List<ResolveInfo> infos = context.getPackageManager().queryBroadcastReceivers(
new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
if (infos != null) {
for (ResolveInfo info : infos) {
if (info.activityInfo.packageName.equals(pkgName)) {
return new ComponentName(pkgName, info.activityInfo.name);
}
}
}
return null;
}
private boolean isAppInstalled(String pkgName) {
try {
PackageInfo info = mContext.getPackageManager().getPackageInfo(pkgName, PackageManager.GET_DISABLED_COMPONENTS);
return info != null;
} catch (Exception e) {
printError(e);
}
return false;
}
private void fixedPermissionInner(String packageName, String permission) {
updatePermissionFlags(packageName, permission, FLAG_PERMISSION_SYSTEM_FIXED, FLAG_PERMISSION_SYSTEM_FIXED);
}
private void unfixedPermissionInner(String packageName, String permission) {
updatePermissionFlags(packageName, permission, FLAG_PERMISSION_SYSTEM_FIXED, 0);
}
private UserHandle newUserHandler(int id) {
return (UserHandle) newInstance(UserHandle.class, new Class[]{int.class}, id);
}
private Object getIPackageManager() {
try {
Class<?> atClass = Class.forName("android.app.ActivityThread");
Method method = atClass.getDeclaredMethod("getPackageManager");
return method.invoke(atClass);
} catch (Exception e) {
printError(e);
}
return null;
}
private IInterface getAIDLService(String serverName, String interfaceName) {
IBinder binder = getService(serverName);
if (binder != null) {
return getInterface(interfaceName, binder);
}
return null;
}
private IBinder getService(String name) {
try {
Class ServiceManager = Class.forName("android.os.ServiceManager");
Method getService = ServiceManager.getMethod("getService", String.class);
return (IBinder) getService.invoke(ServiceManager, name);
} catch (Exception e) {
printError(e);
}
return null;
}
private IInterface getInterface(String name, IBinder service) {
try {
Class<?> mClass = Class.forName(name + "$Stub");
Method asInterface = mClass.getDeclaredMethod("asInterface", IBinder.class);
return (IInterface) asInterface.invoke(null, service);
} catch (Exception e) {
printError(e);
}
return null;
}
/**
* 是否禁止联网 error
*
* @param packageName
* @return
*/
private boolean isNetworkDisabled(String packageName) {
int uid = getPackageUid(packageName);
if (uid <= 0) return false;
IInterface mINetworkManagementService = getNetworkManagement();
if (mINetworkManagementService != null) {
try {
Method isNetworkRestricted = mINetworkManagementService.getClass().getDeclaredMethod("isNetworkRestricted", int.class);
return (boolean) isNetworkRestricted.invoke(mINetworkManagementService, uid);
} catch (Exception e) {
printError(e);
}
}
return false;
}
private IInterface getNetworkManagement() {
return getAIDLService("network_management", "android.os.INetworkManagementService");
}
public void setLoggerEnabled(boolean loggerEnabled) {
this.mLoggerEnabled = loggerEnabled;
}
public static ComponentName parse(String componentName) {
if (componentName == null || componentName.isEmpty()) return null;
int pos = componentName.indexOf('/');
if (pos > 0 && pos < componentName.length() - 1) {
String packageName = componentName.substring(0, pos).trim();
String className = componentName.substring(pos + 1).trim();
if (className.startsWith(".")) {
className = packageName + className;
}
return new ComponentName(packageName, className);
} else {
return null;
}
}
public boolean removeTask(int taskId) {
IInterface mIActivityManager = getAIDLService("activity", "android.app.IActivityManager");
if (mIActivityManager != null) {
try {
Method method = mIActivityManager.getClass().getDeclaredMethod("removeTask", int.class);
return (boolean) method.invoke(mIActivityManager, taskId);
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
public static String getFactoryMacAddr(Context context) {
WifiManager manager = (WifiManager) context.getApplicationContext().getSystemService(Service.WIFI_SERVICE);
try {
Method getFactoryMacAddresses = manager.getClass().getMethod("getFactoryMacAddresses");
getFactoryMacAddresses.setAccessible(true);
String[] macAddrs = (String[]) getFactoryMacAddresses.invoke(manager, null);
if (macAddrs != null && macAddrs.length > 0) {
return macAddrs[0].toUpperCase();
}
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
}
android系统api工具类
于 2020-06-02 18:05:20 首次发布