package com.emato.ich.utils; import android.Manifest; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Build; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.InputType; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import com.emato.ich.entity.vo.ShellVo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.NetworkInterface; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicReference; public class BaseUtils { private static final String TAG = "BaseUtils"; private static String getMac() { // TODO 加密传输 // start the ls command running //String[] args = new String[]{"sh", "-c", command}; Runtime runtime = Runtime.getRuntime(); String command = "cat /sys/class/net/eth0/address"; Process proc = null; //这句话就是shell与高级语言间的调用 try { proc = runtime.exec(command); // 如果有参数的话可以用另外一个被重载的exec方法 // 实际上这样执行时启动了一个子进程,它没有父进程的控制台 // 也就看不到输出,所以我们需要用输出流来得到shell执行后的输出 InputStream inputstream = proc.getInputStream(); InputStreamReader inputstreamreader = new InputStreamReader(inputstream); BufferedReader bufferedreader = new BufferedReader(inputstreamreader); // read the ls output String line = ""; StringBuilder sb = new StringBuilder(line); while ((line = bufferedreader.readLine()) != null) { //System.out.println(line); sb.append(line); } return sb.toString(); } catch (IOException e) { return ""; } //tv.setText(sb.toString()); //使用exec执行不会等执行成功以后才返回,它会立即返回 //所以在某些情况下是很要命的(比如复制文件的时候) //使用waitFor()可以等待命令执行完成以后才返回 // try { // if (proc.waitFor() != 0) { // System.err.println("exit value = " + proc.exitValue()); // } // } catch (InterruptedException e) { // System.err.println(e); // } // return null; } public static ShellVo executeShell(ShellVo shellVo){ Runtime runtime = Runtime.getRuntime(); Process proc = null; //这句话就是shell与高级语言间的调用 try { // 如果有参数的话可以用另外一个被重载的exec方法 if (shellVo.getArgs() == null) { proc = runtime.exec(shellVo.getScript()); } else { String[] argsArr = new String[shellVo.getArgs().size()]; proc = runtime.exec(shellVo.getScript(), argsArr); } // 实际上这样执行时启动了一个子进程,它没有父进程的控制台 // 也就看不到输出,所以我们需要用输出流来得到shell执行后的输出 InputStream inputstream = proc.getInputStream(); InputStreamReader inputstreamreader = new InputStreamReader(inputstream); BufferedReader bufferedreader = new BufferedReader(inputstreamreader); // read the ls output String line = ""; StringBuilder sb = new StringBuilder(line); while ((line = bufferedreader.readLine()) != null) { //System.out.println(line); sb.append(line); } shellVo.setResult(sb.toString()); return shellVo; } catch (IOException e) { shellVo.setResult("没有返回或执行脚本异常: " + e.getCause()); return shellVo; } } public static String getClientId() { return Md5Utils.string2Md5_16(getMac()).toUpperCase(); // return "285F18D92D0B6568"; } public static String getMac2() { try { List all = Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface nif : all) { if (!"eth0".equalsIgnoreCase(nif.getName())) { continue; } byte[] macBytes = nif.getHardwareAddress(); if (macBytes == null || macBytes.length == 0) { continue; } StringBuilder result = new StringBuilder(); for (byte b : macBytes) { result.append(String.format("%02X", b)); } return result.toString().toUpperCase(); } } catch (Exception x) { x.printStackTrace(); } return ""; } /** * 获取当前App的版本号 * * @param context 上下文 * @return app版本号 */ public static String getAppVersion(Context context) { PackageManager packageManager = context.getPackageManager(); try { PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); return packageInfo.versionName; } catch (Exception e) { Log.e(TAG, "getAppVersion: 获取APP版本失败!", e); } return ""; } /** * 获取Android版本号 * * @return 版本号 */ public static String getVersionName() { // return "Android " + Build.VERSION.RELEASE; return Build.VERSION.RELEASE; } /** * 获取IMEI * * @param context 程序上下文 * @return imei */ public static String getIMEI(Context context) { String imei = ""; //Android 6.0 以后需要获取动态权限 检查权限 if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { return imei; } try { TelephonyManager manager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); if (manager != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {// android 8 即以后建议用getImei 方法获取 不会获取到MEID Method method = manager.getClass().getMethod("getImei", int.class); imei = (String) method.invoke(manager, 0); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //5.0的系统如果想获取MEID/IMEI1/IMEI2 ----framework层提供了两个属性值“ril.cdma.meid"和“ril.gsm.imei"获取 imei = getSystemPropertyByReflect("ril.gsm.imei"); //如果获取不到 就调用 getDeviceId 方法获取 } else {//5.0以下获取imei/meid只能通过 getDeviceId 方法去取 } } } catch (Exception e) { } if (TextUtils.isEmpty(imei)) { String imeiOrMeid = getDeviceId(context); //长度15 的是imei 14的是meid if (!TextUtils.isEmpty(imeiOrMeid) && imeiOrMeid.length() >= 15) { imei = imeiOrMeid; } } return imei; } private static String getSystemPropertyByReflect(String key) { try { @SuppressLint("PrivateApi") Class clz = Class.forName("android.os.SystemProperties"); Method getMethod = clz.getMethod("get", String.class, String.class); return (String) getMethod.invoke(clz, key, ""); } catch (Exception e) {/**/} return ""; } public static String getDeviceId(Context context) { String imei = ""; //Android 6.0 以后需要获取动态权限 检查权限 if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { return imei; } // 1. 尝试通过系统api获取imei imei = getDeviceIdFromSystemApi(context, 0); if (TextUtils.isEmpty(imei)) { imei = getDeviceIdByReflect(context); } return imei; } @SuppressLint("MissingPermission") public static String getDeviceIdFromSystemApi(Context context, int slotId) { String imei = ""; try { TelephonyManager telephonyManager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager != null) { imei = telephonyManager.getDeviceId(slotId); } } catch (Throwable e) { } return imei; } public static String getDeviceIdByReflect(Context context) { try { TelephonyManager tm = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); if (Build.VERSION.SDK_INT >= 21) { Method simMethod = TelephonyManager.class.getDeclaredMethod("getDefaultSim"); Object sim = simMethod.invoke(tm); Method method = TelephonyManager.class.getDeclaredMethod("getDeviceId", int.class); return method.invoke(tm, sim).toString(); } else { Class clazz = Class.forName("com.android.internal.telephony.IPhoneSubInfo"); Method subInfoMethod = TelephonyManager.class.getDeclaredMethod("getSubscriberInfo"); subInfoMethod.setAccessible(true); Object subInfo = subInfoMethod.invoke(tm); Method method = clazz.getDeclaredMethod("getDeviceId"); return method.invoke(subInfo).toString(); } } catch (Throwable e) { } return ""; } public static String getIp(){ Runtime runtime = Runtime.getRuntime(); String command = "netcfg"; Process proc = null; //这句话就是shell与高级语言间的调用 try { proc = runtime.exec(command); // 如果有参数的话可以用另外一个被重载的exec方法 // 实际上这样执行时启动了一个子进程,它没有父进程的控制台 // 也就看不到输出,所以我们需要用输出流来得到shell执行后的输出 InputStream inputstream = proc.getInputStream(); InputStreamReader inputstreamreader = new InputStreamReader(inputstream); BufferedReader bufferedreader = new BufferedReader(inputstreamreader); // read the ls output String line = ""; StringBuilder sb = new StringBuilder(line); while ((line = bufferedreader.readLine()) != null) { //System.out.println(line); sb.append(line); } return sb.toString(); } catch (IOException e) { return ""; } } /** * 禁用EditText弹出输入框 * @param editText 输入框 */ public static void disableEditText(EditText editText) { if (Build.VERSION.SDK_INT <= 10) { editText.setInputType(InputType.TYPE_NULL); } else { Class editTextClass = EditText.class; Method method; try { method = editTextClass.getMethod("setShowSoftInputOnFocus", boolean.class); method.setAccessible(true); method.invoke(editText, false); } catch (Exception e) { } try { method = editTextClass.getMethod("setSoftInputShownOnFocus", boolean.class); method.setAccessible(true); method.invoke(editText, false); } catch (Exception e) { } } } }