提交 2ca18ef7 编写于 作者: C cmj

see 10/21 log

上级 e7b11cee
package com.blankj.utilcode.utils;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
......@@ -361,8 +362,37 @@ public class AppUtils {
return ai != null && (ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
/**
* 判断App是否是Debug版本
*
* @param context 上下文
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isAppDebug(Context context) {
return isAppDebug(context, context.getPackageName());
}
/**
* 判断App是否是Debug版本
*
* @param context 上下文
* @param packageName 包名
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isAppDebug(Context context, String packageName) {
if (StringUtils.isSpace(packageName)) return false;
try {
PackageManager pm = context.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
return ai != null && (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
return false;
}
/**
......@@ -382,11 +412,12 @@ public class AppUtils {
* @param packageName 包名
* @return App签名
*/
@SuppressLint("PackageManagerGetSignatures")
public static Signature[] getAppSignature(Context context, String packageName) {
if (StringUtils.isSpace(packageName)) return null;
try {
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(packageName, 0);
PackageInfo pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
return pi == null ? null : pi.signatures;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
......@@ -427,33 +458,28 @@ public class AppUtils {
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isAppForeground(Context context) {
return ProcessUtils.isAppForeground(context);
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
if (infos == null || infos.size() == 0) return false;
for (ActivityManager.RunningAppProcessInfo info : infos) {
if (info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return info.processName.equals(context.getPackageName());
}
}
return false;
}
/**
* 判断某个App是否处于前台(系统应用调用)
* <p>API < 21,需要添加 {@code <uses-permission android:name="android.permission.GET_TASKS"/>} 权限</p>
* <p>API >= 22,需要添加 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>} 权限</p>
* 判断App是否处于前台
* <p>当不是查看当前App,且SDK >= 22时,
* 需添加权限 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>}</p>
*
* @param context 上下文
* @param packageName 包名
* @return {@code true}: 是<br>{@code false}: 否
*/
@Deprecated
public static boolean isAppForeground(Context context, String packageName) {
return ProcessUtils.isAppForeground(context, packageName);;
}
/**
* 获取前台应用包名(系统应用调用)
* <p>API < 21,需要添加 {@code <uses-permission android:name="android.permission.GET_TASKS"/>} 权限</p>
* <p>API >= 22,需要添加 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>} 权限</p>
*
* @param context 上下文
* @return 前台应用包名
*/
public String getForegroundApp(Context context) {
return ProcessUtils.getForegroundPackage(context);
return !StringUtils.isSpace(packageName) && packageName.equals(ProcessUtils.getForegroundProcessName(context));
}
/**
......@@ -662,4 +688,4 @@ public class AppUtils {
}
return isSuccess;
}
}
}
\ No newline at end of file
package com.blankj.utilcode.utils;
import android.app.ActivityManager;
import android.content.Context;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* <pre>
......
......@@ -25,14 +25,14 @@ public class CloseUtils {
*/
public static void closeIO(Closeable... closeables) {
if (closeables == null) return;
try {
for (Closeable closeable : closeables) {
if (closeable != null) {
for (Closeable closeable : closeables) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
......@@ -43,14 +43,13 @@ public class CloseUtils {
*/
public static void closeIOQuietly(Closeable... closeables) {
if (closeables == null) return;
try {
for (Closeable closeable : closeables) {
if (closeable != null) {
for (Closeable closeable : closeables) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ignored) {
}
}
} catch (IOException e) {
// e.printStackTrace();
}
}
}
package com.blankj.utilcode.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
import android.text.format.Formatter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import static android.R.attr.name;
/**
* <pre>
......@@ -23,31 +34,47 @@ public class DeviceUtils {
private DeviceUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
/**
* 判断设备是否 root
* @return the boolean
*
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isDeviceRooted() {
String su = "su";
String[] locations = {"/sbin/", "/system/bin/", "/system/xbin/", "/system/sd/xbin/", "/system/bin/failsafe/",
"/data/local/xbin/", "/data/local/bin/", "/data/local/"};
for (String location: locations) {
if (new File(location + su).exists()) {
return true;
}
}
return false;
public static boolean isRoot() {
return isRootByShell() || isRootByFile();
}
/**
* 判断设备是否root
* 根据文件判断设备是否 root
*
* @return the boolean{@code true}: 是<br>{@code false}: 否
*/
private static boolean isRootByFile() {
String su = "su";
String[] locations = {"/sbin/", "/system/bin/", "/system/xbin/", "/system/sd/xbin/", "/system/bin/failsafe/",
"/data/local/xbin/", "/data/local/bin/", "/data/local/"};
for (String location : locations) {
if (new File(location + su).exists()) {
return true;
}
}
return false;
}
/**
* 根据shell判断设备是否root
*
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isRoot() {
return ShellUtils.execCmd("echo root", true, false).result == 0;
private static boolean isRootByShell() {
ShellUtils.CommandResult result = ShellUtils.execCmd("echo root", true);
if (result.result == 0) {
return true;
}
if (result.errorMsg != null) {
LogUtils.d("isRootByShell", result.errorMsg);
}
return false;
}
/**
......@@ -66,6 +93,7 @@ public class DeviceUtils {
* @param context 上下文
* @return AndroidID
*/
@SuppressLint("HardwareIds")
public static String getAndroidID(Context context) {
return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
......@@ -73,44 +101,93 @@ public class DeviceUtils {
/**
* 获取设备MAC地址
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}</p>
* <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
*
* @param context 上下文
* @return MAC地址
*/
public static String getMacAddress(Context context) {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
if (info != null) {
String macAddress = info.getMacAddress();
if (macAddress != null) {
return macAddress.replace(":", "");
}
String macAddress = getMacAddressByWifiInfo(context);
if (!"02:00:00:00:00:00".equals(macAddress)) {
return macAddress;
}
macAddress = getMacAddressByNetworkInterface();
if (!"02:00:00:00:00:00".equals(macAddress)) {
return macAddress;
}
macAddress = getMacAddressByFile();
if (!"02:00:00:00:00:00".equals(macAddress)) {
return macAddress;
}
return null;
return "please open wifi";
}
/**
* 获取设备MAC地址
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>}</p>
*
* @param context 上下文
* @return MAC地址
*/
@SuppressLint("HardwareIds")
private static String getMacAddressByWifiInfo(Context context) {
try {
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (wifi != null) {
WifiInfo info = wifi.getConnectionInfo();
if (info != null) return info.getMacAddress();
}
} catch (Exception e) {
e.printStackTrace();
}
return "02:00:00:00:00:00";
}
public static String getMacAddress() {
String macAddress = null;
LineNumberReader lnr = null;
InputStreamReader isr = null;
/**
* 获取设备MAC地址
* <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
*
* @return MAC地址
*/
private static String getMacAddressByNetworkInterface() {
try {
Process pp = Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address");
isr = new InputStreamReader(pp.getInputStream());
lnr = new LineNumberReader(isr);
macAddress = lnr.readLine().replace(":", "");
} catch (IOException e) {
List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface ni : nis) {
if (!ni.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = ni.getHardwareAddress();
if (macBytes != null && macBytes.length > 0) {
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02x:", b));
}
return res1.deleteCharAt(res1.length() - 1).toString();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
CloseUtils.closeIO(lnr, isr);
}
return macAddress == null ? "" : macAddress;
return "02:00:00:00:00:00";
}
/**
* 获取设备MAC地址
*
* @return MAC地址
*/
private static String getMacAddressByFile() {
ShellUtils.CommandResult result = ShellUtils.execCmd("getprop wifi.interface", false);
if (result.result == 0) {
String name = result.successMsg;
if (name != null) {
result = ShellUtils.execCmd("cat /sys/class/net/" + name + "/address", false);
if (result.result == 0) {
if (result.successMsg != null) {
return result.successMsg;
}
}
}
}
return "02:00:00:00:00:00";
}
/**
......@@ -118,6 +195,7 @@ public class DeviceUtils {
*
* @return 设备厂商
*/
public static String getManufacturer() {
return Build.MANUFACTURER;
}
......
......@@ -619,7 +619,6 @@ public class ImageUtils {
Canvas canvas = new Canvas(ret);
Rect rect = new Rect(0, 0, width, height);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
canvas.drawRoundRect(new RectF(rect), radius, radius, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(src, rect, rect, paint);
......@@ -989,31 +988,27 @@ public class ImageUtils {
*/
public static Bitmap addReflection(Bitmap src, int reflectionHeight, boolean recycle) {
if (isEmptyBitmap(src)) return null;
// 原图与倒影之间的间距
final int REFLECTION_GAP = 0;
int srcWidth = src.getWidth();
int srcHeight = src.getHeight();
if (0 == srcWidth || srcHeight == 0) return null;
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
Bitmap reflectionBitmap = Bitmap.createBitmap(src, 0, srcHeight - reflectionHeight,
srcWidth, reflectionHeight, matrix, false);
if (null == reflectionBitmap) return null;
Bitmap ret = Bitmap.createBitmap(srcWidth, srcHeight + reflectionHeight, src.getConfig());
Canvas canvas = new Canvas(ret);
canvas.drawBitmap(src, 0, 0, null);
canvas.drawBitmap(reflectionBitmap, 0, srcHeight + REFLECTION_GAP, null);
Paint paint = new Paint();
paint.setAntiAlias(true);
LinearGradient shader = new LinearGradient(0, srcHeight, 0,
ret.getHeight() + REFLECTION_GAP,
LinearGradient shader = new LinearGradient(0, srcHeight,
0, ret.getHeight() + REFLECTION_GAP,
0x70FFFFFF, 0x00FFFFFF, Shader.TileMode.MIRROR);
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(
android.graphics.PorterDuff.Mode.DST_IN));
canvas.save();
canvas.drawRect(0, srcHeight, srcWidth,
ret.getHeight() + REFLECTION_GAP, paint);
canvas.restore();
paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN));
canvas.drawRect(0, srcHeight + REFLECTION_GAP,
srcWidth, ret.getHeight(), paint);
if (!reflectionBitmap.isRecycled()) reflectionBitmap.recycle();
if (recycle && !src.isRecycled()) src.recycle();
return ret;
......
......@@ -33,44 +33,12 @@ public class KeyboardUtils {
* @param activity activity
*/
public static void hideSoftInput(Activity activity) {
View view = activity.getWindow().peekDecorView();
if (view != null) {
InputMethodManager inputmanger = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
View view = activity.getCurrentFocus();
if (view == null) {
view = new View(activity);
}
}
/**
* 动态隐藏软键盘
*
* @param context 上下文
* @param edit 输入框
*/
public static void hideSoftInput(Context context, EditText edit) {
edit.clearFocus();
InputMethodManager inputmanger = (InputMethodManager) context
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputmanger.hideSoftInputFromWindow(edit.getWindowToken(), 0);
}
/**
* 点击屏幕空白区域隐藏软键盘(方法1)
* <p>在onTouch中处理,未获焦点则隐藏</p>
* <p>参照以下注释代码</p>
*/
public static void clickBlankArea2HideSoftInput0() {
Log.d("tips", "U should copy the following code.");
/*
@Override
public boolean onTouchEvent (MotionEvent event){
if (null != this.getCurrentFocus()) {
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
return mInputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
}
return super.onTouchEvent(event);
}
*/
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
/**
......@@ -79,7 +47,7 @@ public class KeyboardUtils {
* <p>需重写dispatchTouchEvent</p>
* <p>参照以下注释代码</p>
*/
public static void clickBlankArea2HideSoftInput1() {
public static void clickBlankArea2HideSoftInput() {
Log.d("tips", "U should copy the following code.");
/*
@Override
......
......@@ -30,7 +30,7 @@ public class LogUtils {
private static boolean log2FileSwitch = false;
private static char logFilter = 'v';
private static String tag = "TAG";
private static String dir;
private static String dir = null;
/**
* 初始化函数
......
......@@ -4,10 +4,17 @@ import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.telephony.TelephonyManager;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
......@@ -39,11 +46,6 @@ public class NetworkUtils {
private static final int NETWORK_TYPE_TD_SCDMA = 17;
private static final int NETWORK_TYPE_IWLAN = 18;
private static final String CMCC_ISP = "46000";//中国移动
private static final String CMCC2_ISP = "46002";//中国移动
private static final String CU_ISP = "46001";//中国联通
private static final String CT_ISP = "46003";//中国电信
/**
* 打开网络设置界面
* <p>3.0以下打开设置界面</p>
......@@ -60,6 +62,7 @@ public class NetworkUtils {
/**
* 获取活动网络信息
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
*
* @param context 上下文
* @return NetworkInfo
......@@ -72,14 +75,60 @@ public class NetworkUtils {
/**
* 判断网络是否可用
* <p>需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}</p>
* <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
*
* @param context 上下文
* @return {@code true}: 可用<br>{@code false}: 不可用
*/
public static boolean isAvailable(Context context) {
NetworkInfo info = getActiveNetworkInfo(context);
return info != null && info.isAvailable();
public static boolean isAvailableByPing(Context context) {
ShellUtils.CommandResult result = ShellUtils.execCmd("ping -c 1 -w 1 123.125.114.144", false);
boolean ret = result.result == 0;
if (result.errorMsg != null) {
LogUtils.d("isAvailableByPing", result.errorMsg);
}
if (result.successMsg != null) {
LogUtils.d("isAvailableByPing", result.successMsg);
}
return ret;
}
/**
* 判断移动数据是否打开
* <p>需系统应用 需添加权限{@code <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>}</p>
*
* @param context 上下文
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean getDataEnabled(Context context) {
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Method getMobileDataEnabledMethod = tm.getClass().getDeclaredMethod("getDataEnabled");
if (null != getMobileDataEnabledMethod) {
return (boolean) getMobileDataEnabledMethod.invoke(tm);
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 打开或关闭移动数据
* <p>需系统应用 需添加权限{@code <uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>}</p>
*
* @param context 上下文
* @param enabled {@code true}: 打开<br>{@code false}: 关闭
*/
private void setDataEnabled(Context context, boolean enabled) {
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Method setMobileDataEnabledMethod = tm.getClass().getDeclaredMethod("setDataEnabled", boolean.class);
if (null != setMobileDataEnabledMethod) {
setMobileDataEnabledMethod.invoke(tm, enabled);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
......@@ -121,45 +170,35 @@ public class NetworkUtils {
}
/**
* 获取移动网络运营商名称
* <p>中国移动、如中国联通、中国电信</p>
* 判断wifi是否打开
* <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
*
* @param context 上下文
* @return 移动网络运营商名称
* @return {@code true}: 是<br>{@code false}: 否
*/
public static String getNetworkOperatorName(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
String np = tm != null ? tm.getNetworkOperatorName() : null;
String teleCompany = "unknown";
if (np != null) {
if (np.equals(CMCC_ISP) || np.equals(CMCC2_ISP)) {
teleCompany = "中国移动";
} else if (np.startsWith(CU_ISP)) {
teleCompany = "中国联通";
} else if (np.startsWith(CT_ISP)) {
teleCompany = "中国电信";
}
}
return teleCompany;
public static boolean getWifiEnabled(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
return wifiManager.isWifiEnabled();
}
/**
* 获取移动终端类型
* 打开或关闭wifi
* <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
*
* @param context 上下文
* @return 手机制式
* <ul>
* <li>{@link TelephonyManager#PHONE_TYPE_NONE } : 0 手机制式未知</li>
* <li>{@link TelephonyManager#PHONE_TYPE_GSM } : 1 手机制式为GSM,移动和联通</li>
* <li>{@link TelephonyManager#PHONE_TYPE_CDMA } : 2 手机制式为CDMA,电信</li>
* <li>{@link TelephonyManager#PHONE_TYPE_SIP } : 3</li>
* </ul>
* @param enabled {@code true}: 打开<br>{@code false}: 关闭
*/
public static int getPhoneType(Context context) {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getPhoneType() : -1;
public static void setWifiEnabled(Context context, boolean enabled) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (enabled) {
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
} else {
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
}
}
}
......@@ -266,12 +305,46 @@ public class NetworkUtils {
}
/**
* 根据域名获取ip地址
* 获取IP地址
* <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
*
* @param useIPv4 是否用IPv4
* @return IP地址
*/
public static String getIPAddress(boolean useIPv4) {
try {
for (Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces(); nis.hasMoreElements(); ) {
NetworkInterface ni = nis.nextElement();
for (Enumeration<InetAddress> addresses = ni.getInetAddresses(); addresses.hasMoreElements(); ) {
InetAddress inetAddress = addresses.nextElement();
if (!inetAddress.isLoopbackAddress()) {
String hostAddress = inetAddress.getHostAddress();
boolean isIPv4 = hostAddress.indexOf(':') < 0;
if (useIPv4) {
if (isIPv4) return hostAddress;
} else {
if (!isIPv4) {
int index = hostAddress.indexOf('%');
return index < 0 ? hostAddress.toUpperCase() : hostAddress.substring(0, index).toUpperCase();
}
}
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取域名ip地址
* <p>需添加权限 {@code <uses-permission android:name="android.permission.INTERNET"/>}</p>
*
* @param domain 域名
* @return ip地址
*/
public static String getIpAddress(final String domain) {
public static String getDomainAddress(final String domain) {
try {
ExecutorService exec = Executors.newCachedThreadPool();
Future<String> fs = exec.submit(new Callable<String>() {
......
......@@ -71,6 +71,72 @@ public class PhoneUtils {
return ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE)).getSubscriberId();
}
/**
* 获取移动终端类型
*
* @param context 上下文
* @return 手机制式
* <ul>
* <li>{@link TelephonyManager#PHONE_TYPE_NONE } : 0 手机制式未知</li>
* <li>{@link TelephonyManager#PHONE_TYPE_GSM } : 1 手机制式为GSM,移动和联通</li>
* <li>{@link TelephonyManager#PHONE_TYPE_CDMA } : 2 手机制式为CDMA,电信</li>
* <li>{@link TelephonyManager#PHONE_TYPE_SIP } : 3</li>
* </ul>
*/
public static int getPhoneType(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getPhoneType() : -1;
}
/**
* 获取运营商名称
* <p>中国移动、如中国联通、中国电信</p>
*
* @param context 上下文
* @return 运营商名称
*/
public static String getNetworkOperatorName(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getNetworkOperatorName() : null;
}
/**
* 获取运营商名称
* <p>中国移动、如中国联通、中国电信</p>
*
* @param context 上下文
* @return sim卡运营商名称
*/
public static String getSimOperatorName(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm != null ? tm.getSimOperatorName() : null;
}
/**
* 获取运营商名称
* <p>中国移动、如中国联通、中国电信</p>
*
* @param context 上下文
* @return 移动网络运营商名称
*/
public static String getSimOperatorByMnc(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String operator = tm != null ? tm.getSimOperator() : null;
if (operator == null) return null;
switch (operator) {
case "46000":
case "46002":
case "46007":
return "中国移动";
case "46001":
return "中国联通";
case "46003":
return "中国电信";
default:
return operator;
}
}
/**
* 获取手机状态信息
* <p>需添加权限 {@code <uses-permission android:name="android.permission.READ_PHONE_STATE"/>}</p>
......
package com.blankj.utilcode.utils;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.usage.UsageEvents;
import android.app.AppOpsManager;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.provider.Settings;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* <pre>
* author: onlylemi
* blog : https://github.com/onlylemi
* time : 2016/10/14
* desc : 前台进程信息获取相关
* author: Blankj
* blog : http://blankj.com
* time : 2016/10/18
* desc : 进程相关工具类
* </pre>
*/
public class ProcessUtils {
private static UsageStats recentStats;
private static String result;
private ProcessUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
* 判断应用是否处于前台
* 获取前台应用包名
* <p>当不是查看当前App,且SDK >= 22时,
* 需添加权限 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>}</p>
*
* @param context
* @return
* @param context 上下文
* @return 前台应用包名
*/
public static boolean isAppForeground(Context context) {
public static String getForegroundProcessName(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfos = manager.getRunningAppProcesses();
if (runningAppProcessInfos == null || runningAppProcessInfos.size() == 0) {
return false;
}
for (ActivityManager.RunningAppProcessInfo ra : runningAppProcessInfos) {
if (ra.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& Arrays.asList(ra.pkgList).contains(context.getPackageName())) {
return true;
List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
if (infos != null && infos.size() != 0) {
for (ActivityManager.RunningAppProcessInfo info : infos) {
if (info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return info.processName;
}
}
}
return false;
}
/**
* 判断某个应用是否处于前台(系统应用调用)
* <p>API < 21,需要添加 {@code <uses-permission android:name="android.permission.GET_TASKS"/>} 权限</p>
* <p>API >= 22,需要添加 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>} 权限</p>
*
* @param context
* @param packageName
* @return
*/
public static boolean isAppForeground(Context context, String packageName) {
return TextUtils.equals(packageName, getForegroundPackage(context));
}
/**
* 获取前台应用包名(系统应用调用)
* <p>API < 21,需要添加 {@code <uses-permission android:name="android.permission.GET_TASKS"/>} 权限</p>
* <p>API >= 22,需要添加 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>} 权限</p>
*
* @param context
* @return
*/
public static String getForegroundPackage(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return getForegroundPackage1(context);
} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
return getForegroundPackage2(context);
} else {
return getForegroundPackage3(context);
}
}
/**
* 获取前台应用包名(API < 21,已被遗弃,不能使用)
* <p>需要添加 {@code <uses-permission android:name="android.permission.GET_TASKS"/>} 权限</p>
*
* @param context
* @return
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static String getForegroundPackage1(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);
if (runningTaskInfos == null || runningTaskInfos.size() == 0
|| runningTaskInfos.get(0) == null) {
return null;
}
return runningTaskInfos.get(0).topActivity.getPackageName();
}
/**
* 获取前台应用包名(在 API 22 开始仅可以获取自己的应用,其他应用位于前台时获取到为 null,但可以通过此方式判断自己的应用是否处于前台)
*
* @param context
* @return
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
private static String getForegroundPackage2(Context context) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfos = manager.getRunningAppProcesses();
if (runningAppProcessInfos == null || runningAppProcessInfos.size() == 0) {
return null;
}
for (ActivityManager.RunningAppProcessInfo ra : runningAppProcessInfos) {
if (ra.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
return ra.processName;
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP) {
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
System.out.println(list);
if (list.size() > 0) {// 有"有权查看使用权限的应用"选项
try {
ApplicationInfo info = packageManager.getApplicationInfo(context.getPackageName(), 0);
AppOpsManager aom = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
if (aom.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, info.uid, info.packageName) != AppOpsManager.MODE_ALLOWED) {
context.startActivity(intent);
}
if (aom.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, info.uid, info.packageName) != AppOpsManager.MODE_ALLOWED) {
LogUtils.d("getForegroundApp", "没有打开\"有权查看使用权限的应用\"选项");
return null;
}
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long endTime = System.currentTimeMillis();
long beginTime = endTime - 86400000 * 7;
List<UsageStats> usageStatses = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, beginTime, endTime);
if (usageStatses == null || usageStatses.isEmpty()) return null;
UsageStats recentStats = null;
for (UsageStats usageStats : usageStatses) {
if (recentStats == null || usageStats.getLastTimeUsed() > recentStats.getLastTimeUsed()) {
recentStats = usageStats;
}
}
return recentStats == null ? null : recentStats.getPackageName();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
} else {
LogUtils.d("getForegroundApp", "无\"有权查看使用权限的应用\"选项");
}
}
return null;
}
/**
* 获取前台应用包名(API >= 22)
* <p>需要添加 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>} 权限</p>
* 清除后台进程
* <p>需添加权限 {@code <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>}</p>
*
* @param context
* @return
* @param context 上下文
* @return 清除后台进程数
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
public static String getForegroundPackage3(Context context) {
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
long endTime = calendar.getTimeInMillis();// 结束时间
calendar.add(Calendar.DAY_OF_MONTH, -1);// 时间间隔为一个月
long beginTime = calendar.getTimeInMillis();// 开始时间
// 获取一个月内的信息
List<UsageStats> usageStatses = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_MONTHLY, beginTime, endTime);
if (usageStatses == null || usageStatses.size() == 0) {
return null;
public static int cleanAllBackgroundProcesses(Context context) {
int count = 0;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> infos = am.getRunningAppProcesses();
if (infos == null || infos.size() == 0) return 0;
Set<ActivityManager.RunningAppProcessInfo> set = new HashSet<>();
for (ActivityManager.RunningAppProcessInfo info : infos) {
infos.remove(info);
set.add(info);
++count;
}
for (UsageStats usageStats : usageStatses) {
if (recentStats == null || usageStats.getLastTimeUsed() > recentStats.getLastTimeUsed()) {
recentStats = usageStats;
}
infos = am.getRunningAppProcesses();
if (infos == null || infos.size() == 0) return count;
for (ActivityManager.RunningAppProcessInfo info : infos) {
set.remove(info);
--count;
}
return recentStats.getPackageName();
System.out.println(set);
return count;
}
/**
* 获取前台应用包名(API >= 22)
* <p>需要添加 {@code <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>} 权限</p>
* 清除后台进程
* <p>需添加权限 {@code <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>}</p>
*
* @param context
* @return
* @param context 上下文
* @param packageName 包名
* @return {@code true}: 清除成功<br>{@code false}: 清除失败
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
private static String getForegroundPackage4(Context context) {
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
long endTime = System.currentTimeMillis();
long beginTime = endTime - 10 * 1000;
UsageEvents.Event event = new UsageEvents.Event();
UsageEvents usageEvents = usageStatsManager.queryEvents(beginTime, endTime);
while (usageEvents.hasNextEvent()) {
usageEvents.getNextEvent(event);
if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
result = event.getPackageName();
public static boolean cleanBackgroundProcesses(Context context, String packageName) {
if (StringUtils.isSpace(packageName)) return false;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> infos = am.getRunningAppProcesses();
if (infos == null || infos.size() == 0) return true;
for (ActivityManager.RunningAppProcessInfo info : infos) {
if (Arrays.asList(info.pkgList).contains(packageName)) {
am.killBackgroundProcesses(packageName);
}
}
return result;
infos = am.getRunningAppProcesses();
if (infos == null || infos.size() == 0) return true;
for (ActivityManager.RunningAppProcessInfo info : infos) {
if (Arrays.asList(info.pkgList).contains(packageName)) {
return false;
}
}
return true;
}
}
\ No newline at end of file
}
......@@ -8,7 +8,13 @@ import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* <pre>
......@@ -25,19 +31,53 @@ public class ServiceUtils {
}
/**
* 获取服务是否开启
* 获取所有运行的服务
*
* @param context 上下文
* @return 服务名集合
*/
public static Set getAllRunningService(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> infos = activityManager.getRunningServices(0x7FFFFFFF);
Set<String> names = new HashSet<>();
if (infos == null || infos.size() == 0) return null;
for (RunningServiceInfo info : infos) {
names.add(info.service.getClassName());
}
return names;
}
/**
* 判断服务是否运行
*
* @param context 上下文
* @param className 完整包名的服务类名
* @return {@code true}: 是<br>{@code false}: 否
*/
public static boolean isRunningService(Context context, String className) {
public static boolean isServiceRunning(Context context, String className) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> infoList = activityManager.getRunningServices(0x7FFFFFFF);
if (infoList == null || infoList.size() == 0) return false;
for (RunningServiceInfo info : infoList) {
List<RunningServiceInfo> infos = activityManager.getRunningServices(0x7FFFFFFF);
if (infos == null || infos.size() == 0) return false;
for (RunningServiceInfo info : infos) {
if (className.equals(info.service.getClassName())) return true;
}
return false;
}
/**
* 停止服务
*
* @param context 上下文
* @param className 完整包名的服务类名
* @return {@code true}: 停止成功<br>{@code false}: 停止失败
*/
public static boolean stopService(Context context, String className) {
try {
Intent intent = new Intent(context, Class.forName(className));
return context.stopService(intent);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
\ No newline at end of file
......@@ -23,7 +23,7 @@ public class ShellUtils {
* 是否是在root下执行命令
*
* @param command 命令
* @param isRoot 是否root
* @param isRoot 是否需要root权限执行
* @return CommandResult
*/
public static CommandResult execCmd(String command, boolean isRoot) {
......@@ -34,7 +34,7 @@ public class ShellUtils {
* 是否是在root下执行命令
*
* @param commands 多条命令链表
* @param isRoot 是否root
* @param isRoot 是否需要root权限执行
* @return CommandResult
*/
public static CommandResult execCmd(List<String> commands, boolean isRoot) {
......@@ -45,7 +45,7 @@ public class ShellUtils {
* 是否是在root下执行命令
*
* @param commands 多条命令数组
* @param isRoot 是否root
* @param isRoot 是否需要root权限执行
* @return CommandResult
*/
public static CommandResult execCmd(String[] commands, boolean isRoot) {
......@@ -56,7 +56,7 @@ public class ShellUtils {
* 是否是在root下执行命令
*
* @param command 命令
* @param isRoot 是否root
* @param isRoot 是否需要root权限执行
* @param isNeedResultMsg 是否需要结果消息
* @return CommandResult
*/
......@@ -68,7 +68,7 @@ public class ShellUtils {
* 是否是在root下执行命令
*
* @param commands 命令链表
* @param isRoot 是否root
* @param isRoot 是否需要root权限执行
* @param isNeedResultMsg 是否需要结果消息
* @return CommandResult
*/
......@@ -80,7 +80,7 @@ public class ShellUtils {
* 是否是在root下执行命令
*
* @param commands 命令数组
* @param isRoot 是否root
* @param isRoot 是否需要root权限执行
* @param isNeedResultMsg 是否需要结果消息
* @return CommandResult
*/
......@@ -99,9 +99,7 @@ public class ShellUtils {
process = Runtime.getRuntime().exec(isRoot ? "su" : "sh");
os = new DataOutputStream(process.getOutputStream());
for (String command : commands) {
if (command == null) {
continue;
}
if (command == null) continue;
os.write(command.getBytes());
os.writeBytes("\n");
os.flush();
......
package com.blankj.utilcode.utils;
import android.graphics.Color;
import android.support.design.widget.Snackbar;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.blankj.utilcode.R;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2016/10/16
* desc : SnackBar相关工具类
* </pre>
*/
public class SnackbarUtils {
private static Snackbar snackbar;
public enum SnackbarType {
INFO,
CONFIRM,
WARNING,
ALERT
}
private Snackbar mSnackbar;
public static Snackbar getSnackbar() {
return snackbar;
}
public static final int INFO = 1;
public static final int CONFIRM = 2;
public static final int WARNING = 3;
public static final int ALERT = 4;
public static int red = 0xfff44336;
public static int green = 0xff4caf50;
public static int blue = 0xff2195f3;
public static int orange = 0xffffc107;
/**
* Snackbar:自定义颜色的短显示
*
* @param view 视图
* @param text 文本
* @param textColor 文本颜色
* @param bgColor
* @return
*/
public static Snackbar shortSnackbar(View view, CharSequence text, int textColor, int bgColor) {
Snackbar snackbar = Snackbar.make(view, text, Snackbar.LENGTH_SHORT);
return setSnackBarColor(snackbar, textColor, bgColor);
}
/**
* Snackbar:自定义颜色的长显示
*
* @param view
* @param text
* @param textColor
* @param bgColor
* @return
*/
public static Snackbar longSnackbar(View view, CharSequence text, int textColor, int bgColor) {
Snackbar snackbar = Snackbar.make(view, text, Snackbar.LENGTH_LONG);
return setSnackBarColor(snackbar, textColor, bgColor);
}
/**
* 短显示Snackbar,可选预设类型
*
* @param view
* @param text
* @param type
* @return
*/
public static Snackbar shortSnackbar(View view, CharSequence text, int type) {
Snackbar snackbar = Snackbar.make(view, text, Snackbar.LENGTH_SHORT);
switchType(snackbar, type);
return snackbar;
}
/**
* 长显示Snackbar,可选预设类型
*
* @param view
* @param text
* @param type
* @return
*/
public static Snackbar longSnackbar(View view, CharSequence text, int type) {
Snackbar snackbar = Snackbar.make(view, text, Snackbar.LENGTH_LONG);
switchType(snackbar, type);
return snackbar;
}
/**
* 自定义时常显示Snackbar,自定义颜色
*
* @param view
* @param text
* @param textColor
* @param bgColor
* @return
*/
public static Snackbar IndefiniteSnackbar(View view, CharSequence text, int duration,
int textColor, int bgColor) {
Snackbar snackbar = Snackbar
.make(view, text, Snackbar.LENGTH_INDEFINITE)
.setDuration(duration);
return setSnackBarColor(snackbar, textColor, bgColor);
}
/**
* 自定义时常显示Snackbar,可选预设类型
*
* @param view
* @param text
* @param type
* @return
*/
public static Snackbar IndefiniteSnackbar(View view, String text, int duration, int type) {
Snackbar snackbar = Snackbar.make(view, text, Snackbar.LENGTH_INDEFINITE).setDuration(duration);
switchType(snackbar, type);
return snackbar;
}
/**
* 设置Snackbar背景颜色
*
* @param snackbar
* @param bgColor
*/
public static Snackbar setSnackBarColor(Snackbar snackbar, int bgColor) {
snackbar.getView().setBackgroundColor(bgColor);
return snackbar;
}
/**
* 设置SnackBar消息的颜色
*
* @param snackbar
* @param textColor
*/
public static void setSnackBarTextColor(Snackbar snackbar, int textColor) {
((TextView) snackbar.getView().findViewById(R.id.snackbar_text)).setTextColor(textColor);
}
/**
* 设置Snackbar文字和背景颜色
*
* @param snackbar
* @param textColor
* @param bgColor
*/
public static Snackbar setSnackBarColor(Snackbar snackbar, int textColor, int bgColor) {
View view = snackbar.getView();
view.setBackgroundColor(bgColor);
((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(textColor);
return snackbar;
}
/**
* 为SnackBar添加布局
*
* @param snackbar SnackBar实例
* @param layoutId 布局文件
* @param index 位置
*/
public static void addView(Snackbar snackbar, int layoutId, int index) {
View view = snackbar.getView();
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) view;
View add_view = LayoutInflater.from(view.getContext()).inflate(layoutId, null);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
p.gravity = Gravity.CENTER_VERTICAL;
layout.addView(add_view, index, p);
}
private static void switchType(Snackbar snackbar, int type) {
switch (type) {
case INFO:
setSnackBarColor(snackbar, blue);
break;
case CONFIRM:
setSnackBarColor(snackbar, green);
break;
case WARNING:
setSnackBarColor(snackbar, orange);
break;
case ALERT:
setSnackBarColor(snackbar, Color.YELLOW, red);
break;
}
}
}
......@@ -36,6 +36,29 @@ public class StringUtils {
return (s == null || s.trim().length() == 0);
}
/**
* 判断两字符串是否相等
*
* @param a 待校验字符串a
* @param b 待校验字符串b
* @return @return {@code true}: 相等<br>{@code false}: 不相等
*/
public static boolean equals(CharSequence a, CharSequence b) {
if (a == b) return true;
int length;
if (a != null && b != null && (length = a.length()) == b.length()) {
if (a instanceof String && b instanceof String) {
return a.equals(b);
} else {
for (int i = 0; i < length; i++) {
if (a.charAt(i) != b.charAt(i)) return false;
}
return true;
}
}
return false;
}
/**
* null转为长度为0的字符串
*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册