version:1.0.0
fix: update:更换包名,修改样式
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.vscool.os.service.WeAccessibilityService;
|
||||
|
||||
public class AccessibilityUtils {
|
||||
private static final String TAG = "AccessibilityUtils";
|
||||
|
||||
public static boolean isAccessibilitySettingsOn(Context context) {
|
||||
int accessibilityEnabled = 0;
|
||||
final String service = context.getPackageName() + "/" + WeAccessibilityService.class.getCanonicalName();
|
||||
try {
|
||||
accessibilityEnabled = Settings.Secure.getInt(
|
||||
context.getApplicationContext().getContentResolver(),
|
||||
android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
|
||||
} catch (Settings.SettingNotFoundException e) {
|
||||
Log.e(TAG, "Error finding setting, default accessibility to not found: " + e.getMessage());
|
||||
}
|
||||
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
|
||||
|
||||
if (accessibilityEnabled == 1) {
|
||||
String settingValue = Settings.Secure.getString(
|
||||
context.getApplicationContext().getContentResolver(),
|
||||
Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
|
||||
if (settingValue != null) {
|
||||
mStringColonSplitter.setString(settingValue);
|
||||
while (mStringColonSplitter.hasNext()) {
|
||||
String accessibilityService = mStringColonSplitter.next();
|
||||
if (accessibilityService.equalsIgnoreCase(service)) {
|
||||
Log.v(TAG, "***ACCESSIBILITY IS ENABLED*** -----------------");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.v(TAG, "***ACCESSIBILITY IS DISABLED***");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
91
app/src/main/java/com/vscool/os/utils/ActivationUtil.java
Normal file
91
app/src/main/java/com/vscool/os/utils/ActivationUtil.java
Normal file
@@ -0,0 +1,91 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
|
||||
public class ActivationUtil {
|
||||
|
||||
/*写入1为激活*/
|
||||
private static final int ACTIVATED_KEY = 1;
|
||||
private static final int INACTIVATED_KEY = 0;
|
||||
/*默认激活码类型*/
|
||||
private static final int DEFAULT_CODE_TYPE = -1;
|
||||
/*默认过期时间*/
|
||||
private static final int DEFAULT_EXPIRE_TIME = -1;
|
||||
|
||||
|
||||
/**
|
||||
* 获取激活状态
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static int getActivationStateCode(Context context) {
|
||||
int activation = Settings.Global.getInt(context.getContentResolver(), CommonConfig.UIUI_ACTIVATION_KEY, INACTIVATED_KEY);
|
||||
return activation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否激活
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static boolean isActivation(Context context) {
|
||||
if (context == null) return false;
|
||||
return getActivationStateCode(context) == ACTIVATED_KEY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置激活状态
|
||||
*
|
||||
* @param context
|
||||
* @param code
|
||||
*/
|
||||
public static void setActivation(Context context, int code) {
|
||||
Settings.Global.putInt(context.getContentResolver(), CommonConfig.UIUI_ACTIVATION_KEY, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置激活码类型
|
||||
*
|
||||
* @param context
|
||||
* @param code
|
||||
*/
|
||||
public static void setActivationCodeType(Context context, int code) {
|
||||
Settings.Global.putInt(context.getContentResolver(), CommonConfig.UIUI_CODE_TYPE_KEY, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取激活码类型
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static int getActivationCodeType(Context context) {
|
||||
return Settings.Global.getInt(context.getContentResolver(), CommonConfig.UIUI_CODE_TYPE_KEY, DEFAULT_CODE_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置过期时间
|
||||
*
|
||||
* @param context
|
||||
* @param expireTime
|
||||
*/
|
||||
public static void setActivationExpireTime(Context context, long expireTime) {
|
||||
Settings.Global.putLong(context.getContentResolver(), CommonConfig.UIUI_EXPIRE_TIME_KEY, expireTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取过期时间
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static long getActivationExpireTime(Context context) {
|
||||
return Settings.Global.getLong(context.getContentResolver(), CommonConfig.UIUI_EXPIRE_TIME_KEY, DEFAULT_EXPIRE_TIME);
|
||||
}
|
||||
|
||||
}
|
||||
1056
app/src/main/java/com/vscool/os/utils/ApkUtils.java
Normal file
1056
app/src/main/java/com/vscool/os/utils/ApkUtils.java
Normal file
File diff suppressed because it is too large
Load Diff
170
app/src/main/java/com/vscool/os/utils/AppUsedTimeUtils.java
Normal file
170
app/src/main/java/com/vscool/os/utils/AppUsedTimeUtils.java
Normal file
@@ -0,0 +1,170 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class AppUsedTimeUtils {
|
||||
private static final String TAG = "AppUsedTimeUtils";
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static AppUsedTimeUtils sInstance;
|
||||
private Context mContext;
|
||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||
|
||||
private SimpleDateFormat ruleSDF = new SimpleDateFormat("HH:mm:ss");
|
||||
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private AppTimeinfo appTimeinfo;
|
||||
|
||||
private AppUsedTimeUtils(Context context) {
|
||||
this.mContext = context;
|
||||
appTimeinfo = getAppTimeinfo();
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new AppUsedTimeUtils(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static AppUsedTimeUtils getInstance() {
|
||||
if (sInstance == null) {
|
||||
throw new IllegalStateException("You must be init TimeUtils first");
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private static String normalStartTime = "8:00:00";
|
||||
private static String unusualStartTime = "22:00:00";
|
||||
|
||||
static class AppTimeinfo implements Serializable {
|
||||
private static final long serialVersionUID = 5373751133823666192L;
|
||||
|
||||
AppTimeinfo() {
|
||||
this.appPackageName = "";
|
||||
this.endTime = 0;
|
||||
this.startTime = 0;
|
||||
}
|
||||
|
||||
private String appPackageName;
|
||||
private long endTime;
|
||||
private long startTime;
|
||||
|
||||
public String getAppPackageName() {
|
||||
return appPackageName;
|
||||
}
|
||||
|
||||
public void setAppPackageName(String appPackageName) {
|
||||
this.appPackageName = appPackageName;
|
||||
}
|
||||
|
||||
public long getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(long endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public void setAppPackageName(String name) {
|
||||
appTimeinfo.setAppPackageName(name);
|
||||
setAppTimeinfo();
|
||||
}
|
||||
|
||||
synchronized public String getAppPackageName() {
|
||||
return appTimeinfo.getAppPackageName();
|
||||
}
|
||||
|
||||
synchronized public void setStartTime(long time) {
|
||||
appTimeinfo.setStartTime(time);
|
||||
setAppTimeinfo();
|
||||
}
|
||||
|
||||
synchronized public long getStartTime() {
|
||||
return appTimeinfo.getStartTime();
|
||||
}
|
||||
|
||||
synchronized public void setEndTime(long time) {
|
||||
appTimeinfo.setEndTime(time);
|
||||
setAppTimeinfo();
|
||||
}
|
||||
|
||||
synchronized public long getEndTime() {
|
||||
return appTimeinfo.getEndTime();
|
||||
}
|
||||
|
||||
synchronized private AppTimeinfo getAppTimeinfo() {
|
||||
String jsonString = mMMKV.decodeString("runningAppInfo");
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
return new AppTimeinfo();
|
||||
}
|
||||
Log.e(TAG, "getAppTimeinfo: " + jsonString);
|
||||
Type type = new TypeToken<AppTimeinfo>() {
|
||||
}.getType();
|
||||
Gson gson = new Gson();
|
||||
AppTimeinfo appTimeinfo = gson.fromJson(jsonString, type);
|
||||
return appTimeinfo;
|
||||
}
|
||||
|
||||
synchronized private void setAppTimeinfo() {
|
||||
String jsonString = JsonParser.parseString(appTimeinfo.toString()).getAsJsonObject().toString();
|
||||
mMMKV.encode("runningAppInfo", jsonString);
|
||||
}
|
||||
|
||||
private static final long DAY_TIME = 1000 * 60 * 60 * 24;
|
||||
|
||||
public boolean isNormalTime() {
|
||||
long nowTime = System.currentTimeMillis();
|
||||
String nowTimeString = ruleSDF.format(new Date(nowTime)); // 时间戳转换日期
|
||||
try {
|
||||
Date startDate = ruleSDF.parse(normalStartTime);
|
||||
Date endDate = ruleSDF.parse(unusualStartTime);
|
||||
Date now = ruleSDF.parse(nowTimeString);
|
||||
Log.e(TAG, "isScreenshot: startDate = " + startDate);
|
||||
Log.e(TAG, "isScreenshot: endDate = " + endDate);
|
||||
Log.e(TAG, "isScreenshot: now = " + now);
|
||||
if (startDate.getTime() <= now.getTime() && now.getTime() <= endDate.getTime()) {
|
||||
return true;
|
||||
} else if (endDate.getTime() < now.getTime() && now.getTime() <= startDate.getTime() + DAY_TIME) {
|
||||
return false;
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "isScreenshot: " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
91
app/src/main/java/com/vscool/os/utils/AppUtil.java
Normal file
91
app/src/main/java/com/vscool/os/utils/AppUtil.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2012 www.amsoft.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.vscool.os.utils;
|
||||
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
|
||||
public class AppUtil {
|
||||
private static String TAG = "AppUtil";
|
||||
|
||||
/**
|
||||
* 描述:获取可用内存.
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static long getAvailMemory(Context context) {
|
||||
// 获取android当前可用内存大小
|
||||
ActivityManager activityManager = (ActivityManager) context
|
||||
.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
activityManager.getMemoryInfo(memoryInfo);
|
||||
// 当前系统可用内存 ,将获得的内存大小规格化
|
||||
|
||||
return memoryInfo.availMem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @return 可用的内存大小
|
||||
*/
|
||||
public static long getFreeMemory(Context context) {
|
||||
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
|
||||
activityManager.getMemoryInfo(memoryInfo);
|
||||
long freeMem = memoryInfo.totalMem - memoryInfo.availMem;
|
||||
// Log.e("getHardware", "getFreeMemory: " + freeMem);
|
||||
return freeMem;
|
||||
}
|
||||
|
||||
/**
|
||||
* 描述:总内存.
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static long getTotalMemory(Context context) {
|
||||
// 系统内存信息文件
|
||||
String file = "/proc/meminfo";
|
||||
String memInfo;
|
||||
String[] strs;
|
||||
long memory = 0;
|
||||
|
||||
try {
|
||||
FileReader fileReader = new FileReader(file);
|
||||
BufferedReader bufferedReader = new BufferedReader(fileReader, 8192);
|
||||
// 读取meminfo第一行,系统内存大小
|
||||
memInfo = bufferedReader.readLine();
|
||||
strs = memInfo.split("\\s+");
|
||||
for (String str : strs) {
|
||||
Log.e(TAG, "getTotalMemory: " + str + "\t");
|
||||
}
|
||||
// 获得系统总内存,单位KB
|
||||
memory = Integer.valueOf(strs[1]).intValue();
|
||||
bufferedReader.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Byte转位KB或MB
|
||||
return memory * 1024;
|
||||
}
|
||||
|
||||
}
|
||||
203
app/src/main/java/com/vscool/os/utils/BitmapUtils.java
Normal file
203
app/src/main/java/com/vscool/os/utils/BitmapUtils.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.AdaptiveIconDrawable;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.VectorDrawable;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import com.vscool.os.R;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class BitmapUtils {
|
||||
public static Bitmap Bytes2Bimap(byte[] b) {
|
||||
if (b.length != 0) {
|
||||
return BitmapFactory.decodeByteArray(b, 0, b.length);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] Bitmap2Bytes(Bitmap bitmap) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
|
||||
byte[] data = baos.toByteArray();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drawable转换成一个Bitmap
|
||||
*
|
||||
* @param drawable drawable对象
|
||||
* @return
|
||||
*/
|
||||
public static final Bitmap drawableToBitmap(Drawable drawable) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
|
||||
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap drawableToBitamp(Drawable drawable) {
|
||||
Bitmap bitmap;
|
||||
BitmapDrawable bd = (BitmapDrawable) drawable;
|
||||
bitmap = bd.getBitmap();
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public static Bitmap getIconBitmap(Context context, Drawable drawable) {
|
||||
try {
|
||||
if (drawable == null) {
|
||||
return null;
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && drawable instanceof AdaptiveIconDrawable) {
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return Utils.getRoundedBitmap(bitmap, context);
|
||||
} else if (drawable instanceof VectorDrawable) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
|
||||
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||
drawable.draw(canvas);
|
||||
return Utils.getRoundedBitmap(bitmap, context);
|
||||
} else {
|
||||
return Utils.getRoundedBitmap(((BitmapDrawable) drawable).getBitmap(), context);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("getIconBitmap", "getIconBitmap: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Bitmap getbatteryIcon(Context context, Bitmap bitmap, int level, boolean charging) {
|
||||
String st_level = String.valueOf(level);
|
||||
int paddingLeft = 6;
|
||||
int paddingRight = 8;
|
||||
int paddingTop = 6;
|
||||
int paddingBottom = 6;
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
Bitmap background = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Bitmap bitmapScale = Bitmap.createScaledBitmap(bitmap, width, height, true);
|
||||
Canvas canvas = new Canvas();
|
||||
canvas.setBitmap(background);
|
||||
Paint paint = new Paint();
|
||||
if (charging) {
|
||||
paint.setColor(context.getColor(R.color.charging_color));
|
||||
} else {
|
||||
if (level <= 20) {
|
||||
paint.setColor(Color.RED);
|
||||
} else {
|
||||
paint.setColor(context.getColor(R.color.no_charging_color));
|
||||
}
|
||||
}
|
||||
//设置画笔类型
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
//使用画笔在画布上画矩形
|
||||
paint.setAntiAlias(true);
|
||||
Rect mSrcRect = new Rect(0, 0, width, height);
|
||||
canvas.drawBitmap(bitmapScale, mSrcRect, mSrcRect, null);
|
||||
RectF rectF = new RectF(paddingLeft, paddingTop, (bitmap.getWidth() - paddingRight) * level / 100, bitmap.getHeight() - paddingBottom);// 设置个新的长方形
|
||||
canvas.drawRoundRect(rectF, 3, 3, paint);
|
||||
|
||||
final float mDensity = context.getResources().getDisplayMetrics().density;
|
||||
Rect rect = new Rect();
|
||||
Paint mDatePaint = new Paint();
|
||||
mDatePaint.setTypeface(Typeface.SANS_SERIF);
|
||||
mDatePaint.setTextSize((int) 9F * mDensity);//文字大小
|
||||
mDatePaint.setColor(Color.BLACK);
|
||||
mDatePaint.setAntiAlias(true);
|
||||
|
||||
mDatePaint.getTextBounds(st_level, 0, st_level.length(), rect);
|
||||
//通过文字获取矩形的面积
|
||||
int width1 = rect.right - rect.left;
|
||||
int height1 = rect.bottom - rect.top;
|
||||
int width2 = background.getWidth();
|
||||
int height2 = background.getHeight();
|
||||
canvas.drawText(st_level, (width2 - width1) / 2 - rect.left, (height2 - height1) / 2 - rect.top, mDatePaint);
|
||||
return background;
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap createQRImage(String content, int widthPix, int heightPix) {
|
||||
try {
|
||||
// if (content == null || "".equals(content)) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
//配置参数
|
||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
|
||||
//容错级别
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
||||
//设置空白边距的宽度
|
||||
hints.put(EncodeHintType.MARGIN, 1); //default is 4
|
||||
|
||||
// 图像数据转换,使用了矩阵转换
|
||||
BitMatrix bitMatrix = null;
|
||||
try {
|
||||
bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix,
|
||||
heightPix, hints);
|
||||
} catch (WriterException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int[] pixels = new int[widthPix * heightPix];
|
||||
// 下面这里按照二维码的算法,逐个生成二维码的图片,
|
||||
// 两个for循环是图片横列扫描的结果
|
||||
for (int y = 0; y < heightPix; y++) {
|
||||
for (int x = 0; x < widthPix; x++) {
|
||||
if (bitMatrix.get(x, y)) {
|
||||
pixels[y * widthPix + x] = 0xff000000;
|
||||
} else {
|
||||
pixels[y * widthPix + x] = 0xffffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成二维码图片的格式,使用ARGB_8888
|
||||
Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);
|
||||
//
|
||||
// if (logoBm != null) {
|
||||
// bitmap = addLogo(bitmap, logoBm);
|
||||
// }
|
||||
|
||||
//必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,
|
||||
// 内存消耗巨大!
|
||||
return bitmap;
|
||||
// return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
140
app/src/main/java/com/vscool/os/utils/BrightnessUtils.java
Normal file
140
app/src/main/java/com/vscool/os/utils/BrightnessUtils.java
Normal file
@@ -0,0 +1,140 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.vscool.os.utils;
|
||||
|
||||
public class BrightnessUtils {
|
||||
|
||||
public static final int GAMMA_SPACE_MIN = 0;
|
||||
public static final int GAMMA_SPACE_MAX = 65535;
|
||||
|
||||
// Hybrid Log Gamma constant values
|
||||
private static final float R = 0.5f;
|
||||
private static final float A = 0.17883277f;
|
||||
private static final float B = 0.28466892f;
|
||||
private static final float C = 0.55991073f;
|
||||
|
||||
/**
|
||||
* A function for converting from the gamma space that the slider works in to the
|
||||
* linear space that the setting works in.
|
||||
* <p>
|
||||
* The gamma space effectively provides us a way to make linear changes to the slider that
|
||||
* result in linear changes in perception. If we made changes to the slider in the linear space
|
||||
* then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).
|
||||
* <p>
|
||||
* Internally, this implements the Hybrid Log Gamma electro-optical transfer function, which is
|
||||
* a slight improvement to the typical gamma transfer function for displays whose max
|
||||
* brightness exceeds the 120 nit reference point, but doesn't set a specific reference
|
||||
* brightness like the PQ function does.
|
||||
* <p>
|
||||
* Note that this transfer function is only valid if the display's backlight value is a linear
|
||||
* control. If it's calibrated to be something non-linear, then a different transfer function
|
||||
* should be used.
|
||||
*
|
||||
* @param val The slider value.
|
||||
* @param min The minimum acceptable value for the setting.
|
||||
* @param max The maximum acceptable value for the setting.
|
||||
* @return The corresponding setting value.
|
||||
*/
|
||||
public static final int convertGammaToLinear(int val, int min, int max) {
|
||||
final float normalizedVal = MathUtils.norm(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, val);
|
||||
final float ret;
|
||||
if (normalizedVal <= R) {
|
||||
ret = MathUtils.sq(normalizedVal / R);
|
||||
} else {
|
||||
ret = MathUtils.exp((normalizedVal - C) / A) + B;
|
||||
}
|
||||
|
||||
// HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1]
|
||||
// in order to derive the correct setting value.
|
||||
return Math.round(MathUtils.lerp(min, max, ret / 12));
|
||||
}
|
||||
|
||||
/**
|
||||
* Version of {@link #convertGammaToLinear} that takes and returns float values.
|
||||
* TODO(flc): refactor Android Auto to use float version
|
||||
*
|
||||
* @param val The slider value.
|
||||
* @param min The minimum acceptable value for the setting.
|
||||
* @param max The maximum acceptable value for the setting.
|
||||
* @return The corresponding setting value.
|
||||
*/
|
||||
public static final float convertGammaToLinearFloat(int val, float min, float max) {
|
||||
final float normalizedVal = MathUtils.norm(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, val);
|
||||
final float ret;
|
||||
if (normalizedVal <= R) {
|
||||
ret = MathUtils.sq(normalizedVal / R);
|
||||
} else {
|
||||
ret = MathUtils.exp((normalizedVal - C) / A) + B;
|
||||
}
|
||||
|
||||
// HLG is normalized to the range [0, 12], ensure that value is within that range,
|
||||
// it shouldn't be out of bounds.
|
||||
final float normalizedRet = MathUtils.constrain(ret, 0, 12);
|
||||
|
||||
// Re-normalize to the range [0, 1]
|
||||
// in order to derive the correct setting value.
|
||||
return MathUtils.lerp(min, max, normalizedRet / 12);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function for converting from the linear space that the setting works in to the
|
||||
* gamma space that the slider works in.
|
||||
* <p>
|
||||
* The gamma space effectively provides us a way to make linear changes to the slider that
|
||||
* result in linear changes in perception. If we made changes to the slider in the linear space
|
||||
* then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law).
|
||||
* <p>
|
||||
* Internally, this implements the Hybrid Log Gamma opto-electronic transfer function, which is
|
||||
* a slight improvement to the typical gamma transfer function for displays whose max
|
||||
* brightness exceeds the 120 nit reference point, but doesn't set a specific reference
|
||||
* brightness like the PQ function does.
|
||||
* <p>
|
||||
* Note that this transfer function is only valid if the display's backlight value is a linear
|
||||
* control. If it's calibrated to be something non-linear, then a different transfer function
|
||||
* should be used.
|
||||
*
|
||||
* @param val The brightness setting value.
|
||||
* @param min The minimum acceptable value for the setting.
|
||||
* @param max The maximum acceptable value for the setting.
|
||||
* @return The corresponding slider value
|
||||
*/
|
||||
public static final int convertLinearToGamma(int val, int min, int max) {
|
||||
return convertLinearToGammaFloat((float) val, (float) min, (float) max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Version of {@link #convertLinearToGamma} that takes float values.
|
||||
* TODO: brightnessfloat merge with above method(?)
|
||||
*
|
||||
* @param val The brightness setting value.
|
||||
* @param min The minimum acceptable value for the setting.
|
||||
* @param max The maximum acceptable value for the setting.
|
||||
* @return The corresponding slider value
|
||||
*/
|
||||
public static final int convertLinearToGammaFloat(float val, float min, float max) {
|
||||
// For some reason, HLG normalizes to the range [0, 12] rather than [0, 1]
|
||||
final float normalizedVal = MathUtils.norm(min, max, val) * 12;
|
||||
final float ret;
|
||||
if (normalizedVal <= 1f) {
|
||||
ret = MathUtils.sqrt(normalizedVal) * R;
|
||||
} else {
|
||||
ret = A * MathUtils.log(normalizedVal - B) + C;
|
||||
}
|
||||
|
||||
return Math.round(MathUtils.lerp(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, ret));
|
||||
}
|
||||
}
|
||||
103
app/src/main/java/com/vscool/os/utils/CmdUtil.java
Normal file
103
app/src/main/java/com/vscool/os/utils/CmdUtil.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class CmdUtil {
|
||||
private static final String TAG = "CmdUtil";
|
||||
|
||||
private static final String COMMAND_SH = "sh";
|
||||
private static final String COMMAND_EXIT = "exit\n";
|
||||
private static final String COMMAND_LINE_END = "\n";
|
||||
|
||||
|
||||
/**
|
||||
* 运行命令
|
||||
*
|
||||
* @param command 命令
|
||||
* @return 结果
|
||||
*/
|
||||
public static Result execute(String command) {
|
||||
Log.i(TAG, "execute() command = " + command);
|
||||
Result result = new Result();
|
||||
|
||||
if (TextUtils.isEmpty(command)) {
|
||||
Log.w(TAG, "WARNING: command should not be null or empty");
|
||||
return result;
|
||||
}
|
||||
|
||||
Process process = null;
|
||||
DataOutputStream dos = null;
|
||||
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(COMMAND_SH);
|
||||
dos = new DataOutputStream(process.getOutputStream());
|
||||
dos.write(command.trim().getBytes());
|
||||
dos.writeBytes(COMMAND_LINE_END);
|
||||
dos.flush();
|
||||
dos.writeBytes(COMMAND_EXIT);
|
||||
dos.flush();
|
||||
result.code = process.waitFor();
|
||||
result.success = readBuffer(new BufferedReader(new InputStreamReader(process.getInputStream())));
|
||||
result.error = readBuffer(new BufferedReader(new InputStreamReader(process.getErrorStream())));
|
||||
Log.i(TAG, "result = " + result);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
Log.e(TAG, ioe.getMessage());
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
Log.e(TAG, ie.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (null != dos) {
|
||||
dos.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
Log.e(TAG, ioe.getMessage());
|
||||
}
|
||||
if (null != process) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String readBuffer(BufferedReader bufferedReader) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s;
|
||||
while ((s = bufferedReader.readLine()) != null) {
|
||||
sb.append(s);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Command执行结果
|
||||
*/
|
||||
public static final class Result {
|
||||
|
||||
public static final int SUCCESS = 0;
|
||||
public static final int ERROR = -1;
|
||||
|
||||
public int code = ERROR;
|
||||
public String error;
|
||||
public String success;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Result{" +
|
||||
"code=" + code +
|
||||
", error='" + error + '\'' +
|
||||
", success='" + success + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
391
app/src/main/java/com/vscool/os/utils/ContactsUtils.java
Normal file
391
app/src/main/java/com/vscool/os/utils/ContactsUtils.java
Normal file
@@ -0,0 +1,391 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.vscool.os.R;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.bean.ContactId;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class ContactsUtils {
|
||||
private static final String TAG = "ContactsUtils";
|
||||
|
||||
|
||||
public static void saveContactPhone(Context context, List<Contact> contactList) {
|
||||
Log.e(TAG, "saveContactPhone: ");
|
||||
// List<ContactId> contactIdList = ContactsUtils.getLocalContacts(context);
|
||||
Observable.create(new ObservableOnSubscribe<Long>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
|
||||
for (Contact contact : contactList) {
|
||||
if (TextUtils.isEmpty(contact.getMobile())) {
|
||||
continue;
|
||||
}
|
||||
if (ContactsUtils.isExist(context, contact.getMobile())) {
|
||||
long rawContactId = ContactsUtils.getContactId(context, contact.getMobile());
|
||||
Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues nameValues = new ContentValues();
|
||||
//add Name
|
||||
nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
|
||||
nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
|
||||
resolver.update(ContactsContract.Data.CONTENT_URI, nameValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID});
|
||||
|
||||
ContentValues photoValues = new ContentValues();
|
||||
photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
resource.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
|
||||
photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
|
||||
resolver.update(ContactsContract.Data.CONTENT_URI, photoValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID});
|
||||
|
||||
ContentValues phoneValues = new ContentValues();
|
||||
phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile());
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
|
||||
resolver.update(ContactsContract.Data.CONTENT_URI, phoneValues, "raw_contact_id=?" + rawContactId, new String[]{ContactsContract.Data.CONTACT_ID});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ContentValues values = new ContentValues();
|
||||
long rawContactId = ContentUris.parseId(context.getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values));
|
||||
Glide.with(context).asBitmap().load(contact.getAvatar()).override(200, 200).into(new SimpleTarget<Bitmap>() {
|
||||
@Override
|
||||
public void onResourceReady(@androidx.annotation.NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
ContentValues nameValues = new ContentValues();
|
||||
//add Name
|
||||
nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
|
||||
nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues);
|
||||
|
||||
ContentValues photoValues = new ContentValues();
|
||||
photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
resource.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
|
||||
photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, photoValues);
|
||||
|
||||
ContentValues phoneValues = new ContentValues();
|
||||
phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobile());
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, phoneValues);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
emitter.onNext(1L);
|
||||
}
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Long>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("saveContactPhone", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull Long aLong) {
|
||||
Log.e("saveContactPhone", "onNext: " + aLong);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("saveContactPhone", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("saveContactPhone", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加联系人信息
|
||||
*/
|
||||
public static void insertConstacts(Context context, String name, String phone, List<String> list) {
|
||||
long contactId = getContactId(context, name);
|
||||
if (contactId == -1) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
|
||||
//插入raw_contacts表,并获取_id属性
|
||||
ContentValues nameValues = new ContentValues();
|
||||
long rawContactId = ContentUris.parseId(resolver.insert(ContactsContract.RawContacts.CONTENT_URI, nameValues));
|
||||
|
||||
//插入data表
|
||||
//add Name
|
||||
nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
nameValues.put(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/name");
|
||||
nameValues.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name);
|
||||
resolver.insert(ContactsContract.Data.CONTENT_URI, nameValues);
|
||||
|
||||
|
||||
try {
|
||||
//写入头像
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_avatar);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
|
||||
ContentValues photoValues = new ContentValues();
|
||||
photoValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
photoValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
|
||||
photoValues.put(ContactsContract.CommonDataKinds.Photo.PHOTO, out.toByteArray());
|
||||
context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, photoValues);
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ContentValues phoneValues = new ContentValues();
|
||||
//写入手机号码
|
||||
phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
|
||||
phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
|
||||
phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
|
||||
//插入data表
|
||||
context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, phoneValues);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断某个手机号是否存在
|
||||
*/
|
||||
public static boolean isThePhoneExist(Context context, String phoneNum) {
|
||||
//uri= content://com.android.contacts/data/phones/filter/#
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
cursor = resolver.query(uri, new String[]{ContactsContract.Data.DISPLAY_NAME},
|
||||
null, null, null); //从raw_contact表中返回display_name
|
||||
for (String columnName : cursor.getColumnNames()) {
|
||||
Log.e("isThePhoneExist: ", columnName);
|
||||
}
|
||||
while (cursor.moveToNext()) {
|
||||
for (String columnName : cursor.getColumnNames()) {
|
||||
Log.e("isThePhoneExist: ", columnName);
|
||||
Log.e("isThePhoneExist: ", cursor.getColumnIndex(columnName) + "");
|
||||
if (cursor.getColumnIndex(columnName) != -1) {
|
||||
Log.e("isThePhoneExist: getString = ", " - " + cursor.getString(cursor.getColumnIndex(columnName)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cursor.moveToFirst()) {
|
||||
//Log.i(TAG, "name=" + cursor.getString(0) + " , phoneNum = " + phoneNum);
|
||||
cursor.close();
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//Log.i(TAG, "163 e =" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有联系人信息
|
||||
*/
|
||||
// public static List<SysContactsListBean> getAllSysContacts(Context context) {
|
||||
// List<SysContactsListBean> list = new ArrayList<>();
|
||||
// try {
|
||||
// ContentResolver resolver = context.getContentResolver();
|
||||
// SysContactsListBean sysContactsListBean;
|
||||
// Uri uri = Uri.parse("content://com.android.contacts/data/phones");
|
||||
//
|
||||
// Cursor cursor1 = resolver.query(uri,
|
||||
// new String[]{ContactsContract.Data.RAW_CONTACT_ID,
|
||||
// ContactsContract.Data.DISPLAY_NAME,
|
||||
// ContactsContract.CommonDataKinds.Phone.NUMBER},
|
||||
// null, null, null);
|
||||
//
|
||||
// while (cursor1.moveToNext()) {
|
||||
// sysContactsListBean = new SysContactsListBean();
|
||||
// sysContactsListBean.setCustomerId(cursor1.getLong(0));
|
||||
// sysContactsListBean.setCustomerName(cursor1.getString(1));
|
||||
// sysContactsListBean.setPhoneNumber(cursor1.getString(2));
|
||||
// list.add(sysContactsListBean);
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// if (!CollectorUtils.isEmpty(list)) {
|
||||
// Collections.sort(list, new Comparator<SysContactsListBean>() {
|
||||
// @Override
|
||||
// public int compare(SysContactsListBean o1, SysContactsListBean o2) {
|
||||
// return o2.getCustomerName().compareTo(o1.getCustomerName());
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// return list;
|
||||
// }
|
||||
public static void getContacts(Context context) {
|
||||
//https://blog.csdn.net/luofeixiongsix/article/details/48849511
|
||||
//查询raw_contacts表获得联系人
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
// Uri uri = ContactsContract.Data.CONTENT_URI;//content://com.android.contacts/data 有电话+86
|
||||
// Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;//content://com.android.contacts/data/phones 有电话+86
|
||||
// Uri uri = ContactsContract.RawContacts.CONTENT_URI;//content://com.android.contacts/raw_contacts 无电话
|
||||
Uri uri = ContactsContract.Contacts.CONTENT_URI;//content://com.android.contacts/contacts 无电话
|
||||
|
||||
Log.e(TAG, "getContacts: " + uri.toString());
|
||||
//查询联系人
|
||||
Cursor cursor1 = resolver.query(ContactsContract.Data.CONTENT_URI, null, null, null, null);
|
||||
Log.e("getContacts: cursor1 = ", Arrays.toString(cursor1.getColumnNames()));
|
||||
Cursor cursor2 = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
|
||||
Log.e("getContacts: cursor2 = ", Arrays.toString(cursor1.getColumnNames()));
|
||||
Cursor cursor3 = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, null, null, null);
|
||||
Log.e("getContacts: cursor3 = ", Arrays.toString(cursor1.getColumnNames()));
|
||||
Cursor cursor4 = resolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
|
||||
Log.e("getContacts: cursor4 = ", Arrays.toString(cursor1.getColumnNames()));
|
||||
|
||||
// while (cursor.moveToNext()) {
|
||||
// String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
|
||||
// String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
|
||||
// Log.e(TAG, "getContacts: 联系人:" + name);
|
||||
// Log.e(TAG, "getContacts: 电话:" + number);
|
||||
// }
|
||||
// for (String columnName : cursor.getColumnNames()) {
|
||||
// Log.e("getContacts: ", columnName);
|
||||
// }
|
||||
// while (cursor.moveToNext()) {
|
||||
// for (String columnName : cursor.getColumnNames()) {
|
||||
// Log.e("getContacts: ", cursor.getColumnIndex(columnName) + "\t" + columnName);
|
||||
// if (cursor.getColumnIndex(columnName) != -1) {
|
||||
// Log.e("getContacts: getString =", " " + cursor.getString(cursor.getColumnIndex(columnName)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// cursor.close();
|
||||
}
|
||||
|
||||
public static List<ContactId> getLocalContacts(Context context) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
Uri uri = ContactsContract.Contacts.CONTENT_URI;
|
||||
Cursor cursor = resolver.query(uri, null, null, null, null);
|
||||
List<ContactId> contactIds = new ArrayList<>();
|
||||
while (cursor.moveToNext()) {
|
||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow("name_raw_contact_id"));
|
||||
int in_phone = cursor.getInt(cursor.getColumnIndexOrThrow("indicate_phone_or_sim_contact"));
|
||||
String display_name = cursor.getString(cursor.getColumnIndexOrThrow("display_name"));
|
||||
String photo_uri = cursor.getString(cursor.getColumnIndexOrThrow("photo_uri"));
|
||||
|
||||
ContactId contactId = new ContactId(id, in_phone, display_name, photo_uri);
|
||||
contactIds.add(contactId);
|
||||
}
|
||||
cursor.close();
|
||||
List<ContactId> filter = contactIds.stream().filter(new Predicate<ContactId>() {
|
||||
@Override
|
||||
public boolean test(ContactId contactId) {
|
||||
return contactId.getInPhone() == -1;
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
Log.e(TAG, "getLocalContacts: " + filter);
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断某个手机号是否存在
|
||||
*/
|
||||
public static boolean isExist(Context context, String phoneNum) {
|
||||
//uri= content://com.android.contacts/data/phones/filter/#
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
cursor = resolver.query(uri, new String[]{ContactsContract.Data.DISPLAY_NAME},
|
||||
null, null, null); //从raw_contact表中返回display_name
|
||||
if (cursor.moveToFirst()) {
|
||||
cursor.close();
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param phoneNum
|
||||
* @return 获取联系人id
|
||||
*/
|
||||
public static long getContactId(Context context, String phoneNum) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + phoneNum);
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
cursor = resolver.query(uri, null, null, null, null); //从raw_contact表中返回display_name
|
||||
if (cursor.moveToFirst()) {
|
||||
for (String columnName : cursor.getColumnNames()) {
|
||||
Log.e("getContactId: ", cursor.getColumnIndex(columnName) + "\t" + columnName);
|
||||
if (cursor.getColumnIndex(columnName) != -1) {
|
||||
Log.e("getContactId: getString =", " " + cursor.getString(cursor.getColumnIndex(columnName)));
|
||||
}
|
||||
}
|
||||
return cursor.getLong(cursor.getColumnIndexOrThrow(ContactsContract.Data.CONTACT_ID));
|
||||
}
|
||||
cursor.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
42
app/src/main/java/com/vscool/os/utils/DataUtil.java
Normal file
42
app/src/main/java/com/vscool/os/utils/DataUtil.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 作者 mjsheng
|
||||
* 日期 2018/8/31 09:50
|
||||
* 邮箱 501802639@qq.com
|
||||
* 来自:
|
||||
*/
|
||||
|
||||
public class DataUtil {
|
||||
private static SimpleDateFormat day = new SimpleDateFormat("MM月dd日");
|
||||
private static SimpleDateFormat hour = new SimpleDateFormat("HH:mm");
|
||||
private static SimpleDateFormat minute = new SimpleDateFormat("mm");
|
||||
|
||||
/**
|
||||
* 格式化日期(精确到天)
|
||||
*/
|
||||
public static String formatDateDay() {
|
||||
return day.format(new Date());
|
||||
}
|
||||
|
||||
public static String formatDateTime() {
|
||||
return hour.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期(hour)
|
||||
*/
|
||||
public static String formatDateHour() {
|
||||
return hour.format(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期(minute)
|
||||
*/
|
||||
public static String formatDateMinute() {
|
||||
return minute.format(new Date());
|
||||
}
|
||||
}
|
||||
29
app/src/main/java/com/vscool/os/utils/DayUtils.java
Normal file
29
app/src/main/java/com/vscool/os/utils/DayUtils.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class DayUtils {
|
||||
public static boolean isNight() {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
int hour = calendar.get(Calendar.HOUR_OF_DAY);
|
||||
int minute = calendar.get(Calendar.MINUTE);
|
||||
int second = calendar.get(Calendar.SECOND);
|
||||
return hour >= 16 && minute >= 30;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 根据日期取得星期几
|
||||
*/
|
||||
public static String getWeek() {
|
||||
Date date = new Date();
|
||||
String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int weekIndex = cal.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if (weekIndex < 0) {
|
||||
weekIndex = 0;
|
||||
}
|
||||
return weeks[weekIndex];
|
||||
}
|
||||
}
|
||||
56
app/src/main/java/com/vscool/os/utils/FFmpegUtils.java
Normal file
56
app/src/main/java/com/vscool/os/utils/FFmpegUtils.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import wseemann.media.FFmpegMediaMetadataRetriever;
|
||||
|
||||
public class FFmpegUtils {
|
||||
/**
|
||||
* 获取在线音频时间长度
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
public static void getDurationInMilliseconds(String url, Observer<Integer> observer) {
|
||||
Observable.create(new ObservableOnSubscribe<Integer>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
|
||||
long time = System.currentTimeMillis();
|
||||
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
|
||||
mmr.setDataSource(url);
|
||||
int duration = Integer.parseInt(mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
|
||||
Log.e("AudioUtils", "getDurationInMilliseconds: " + (System.currentTimeMillis() - time));
|
||||
mmr.release();//释放资源
|
||||
emitter.onNext(duration / 1000);
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(observer);
|
||||
}
|
||||
|
||||
public static void loadVideoScreenshot(String url, Observer<Bitmap> observer) {
|
||||
Observable.create(new ObservableOnSubscribe<Bitmap>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Bitmap> emitter) throws Throwable {
|
||||
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
|
||||
mmr.setDataSource(url);
|
||||
mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
|
||||
mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
|
||||
Bitmap b = mmr.getFrameAtTime(2000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST); // frame at 2 seconds
|
||||
byte[] artwork = mmr.getEmbeddedPicture();
|
||||
mmr.release();
|
||||
emitter.onNext(b);
|
||||
}
|
||||
}).subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(observer);
|
||||
}
|
||||
}
|
||||
172
app/src/main/java/com/vscool/os/utils/FileUtil.java
Normal file
172
app/src/main/java/com/vscool/os/utils/FileUtil.java
Normal file
@@ -0,0 +1,172 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class FileUtil {
|
||||
public static String getFileType(String url) {
|
||||
if (url.indexOf("/") == -1) {
|
||||
return url.substring(url.indexOf("."), url.length());
|
||||
} else {
|
||||
String fileName = url.substring(url.lastIndexOf("/"));
|
||||
return fileName.substring(fileName.indexOf("."), fileName.length());
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isLocalPath(String path) {
|
||||
return path.startsWith(File.separator);
|
||||
}
|
||||
|
||||
private static HashSet<String> videoFormat = new HashSet<String>() {{
|
||||
this.add(".mp4");
|
||||
this.add(".avi");
|
||||
this.add(".nkv");
|
||||
this.add(".flv");
|
||||
}};
|
||||
private static HashSet<String> pictureFormat = new HashSet<String>() {{
|
||||
this.add(".png");
|
||||
this.add(".jpg");
|
||||
this.add(".jpeg");
|
||||
this.add(".bmp");
|
||||
}};
|
||||
|
||||
public static boolean isVideoFile(String fileName) {
|
||||
if (TextUtils.isEmpty(fileName)) {
|
||||
return false;
|
||||
} else {
|
||||
if (!fileName.startsWith(".")) {
|
||||
return videoFormat.contains(getFileType(fileName));
|
||||
} else {
|
||||
return videoFormat.contains(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPictureFile(String fileName) {
|
||||
if (TextUtils.isEmpty(fileName)) {
|
||||
return false;
|
||||
} else {
|
||||
if (!fileName.startsWith(".")) {
|
||||
return pictureFormat.contains(getFileType(fileName));
|
||||
} else {
|
||||
return pictureFormat.contains(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static File uriToFile(Uri uri, Context context) {
|
||||
String path = null;
|
||||
if ("file".equals(uri.getScheme())) {
|
||||
path = uri.getEncodedPath();
|
||||
if (path != null) {
|
||||
path = Uri.decode(path);
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
StringBuffer buff = new StringBuffer();
|
||||
buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=").append("'" + path + "'").append(")");
|
||||
Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA}, buff.toString(), null, null);
|
||||
int index = 0;
|
||||
int dataIdx = 0;
|
||||
for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
|
||||
index = cur.getColumnIndex(MediaStore.Images.ImageColumns._ID);
|
||||
index = cur.getInt(index);
|
||||
dataIdx = cur.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
|
||||
path = cur.getString(dataIdx);
|
||||
}
|
||||
cur.close();
|
||||
if (index == 0) {
|
||||
} else {
|
||||
Uri u = Uri.parse("content://media/external/images/media/" + index);
|
||||
System.out.println("temp uri is :" + u);
|
||||
}
|
||||
}
|
||||
if (path != null) {
|
||||
return new File(path);
|
||||
}
|
||||
} else if ("content".equals(uri.getScheme())) {
|
||||
// 4.2.2以后
|
||||
String[] proj = {MediaStore.Images.Media.DATA};
|
||||
Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
|
||||
if (cursor.moveToFirst()) {
|
||||
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||
path = cursor.getString(columnIndex);
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
return new File(path);
|
||||
} else {
|
||||
//Log.i(TAG, "Uri Scheme:" + uri.getScheme());
|
||||
return new File(uri.toString());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* drawable转为file
|
||||
*
|
||||
* @param drawableId drawable的ID
|
||||
* @param fileName 转换后的文件名
|
||||
* @return
|
||||
*/
|
||||
public static File drawableToFile(Context context, int drawableId, String fileName) {
|
||||
// InputStream is = view.getContext().getResources().openRawResource(R.drawable.logo);
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableId);
|
||||
// Bitmap bitmap = BitmapFactory.decodeStream(is);
|
||||
String defaultPath = context.getFilesDir().getAbsolutePath() + "/defaultGoodInfo";
|
||||
File file = new File(defaultPath);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
String defaultImgPath = defaultPath + "/" + fileName;
|
||||
file = new File(defaultImgPath);
|
||||
try {
|
||||
file.createNewFile();
|
||||
FileOutputStream fOut = new FileOutputStream(file);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
|
||||
// is.close();
|
||||
fOut.flush();
|
||||
fOut.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* bitmap
|
||||
*
|
||||
* @param bitmap bitmap
|
||||
* @param fileName 转换后的文件名
|
||||
* @return
|
||||
*/
|
||||
public static File bitmapToFile(Context context, Bitmap bitmap, String fileName) {
|
||||
String defaultPath = context.getFilesDir().getAbsolutePath() + "/defaultGoodInfo";
|
||||
File file = new File(defaultPath);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
String defaultImgPath = defaultPath + "/" + fileName;
|
||||
file = new File(defaultImgPath);
|
||||
try {
|
||||
file.createNewFile();
|
||||
FileOutputStream fOut = new FileOutputStream(file);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
|
||||
// is.close();
|
||||
fOut.flush();
|
||||
fOut.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
||||
116
app/src/main/java/com/vscool/os/utils/ForegroundAppUtil.java
Normal file
116
app/src/main/java/com/vscool/os/utils/ForegroundAppUtil.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ForegroundAppUtil {
|
||||
|
||||
private static final long END_TIME = System.currentTimeMillis();
|
||||
private static final long TIME_INTERVAL = 7 * 24 * 60 * 60 * 1000L;
|
||||
private static final long START_TIME = END_TIME - TIME_INTERVAL;
|
||||
|
||||
public static final String TOPAPP_KEY = "TOP_ALWAYS_SHOW_APP_NAME";
|
||||
private static String TAG = "ForegroundAppUtil";
|
||||
|
||||
public static String getForegroundPackageName(Context context) {
|
||||
//系统应用可以直接获取
|
||||
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningTaskInfo> runningTaskInfos = mActivityManager.getRunningTasks(1);
|
||||
return runningTaskInfos.get(0).topActivity.getPackageName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取栈顶的应用包名
|
||||
*/
|
||||
public static String getForegroundActivityName(Context context) {
|
||||
String currentClassName = "";
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
|
||||
currentClassName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();
|
||||
} else {
|
||||
UsageStats initStat = getForegroundUsageStats(context, START_TIME, END_TIME);
|
||||
if (initStat != null) {
|
||||
currentClassName = initStat.getPackageName();
|
||||
}
|
||||
}
|
||||
return currentClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前应用是否在前台
|
||||
*/
|
||||
public static boolean isForegroundApp(Context context) {
|
||||
return TextUtils.equals(getForegroundActivityName(context), context.getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间段内,
|
||||
*/
|
||||
public static long getTotleForegroundTime(Context context) {
|
||||
UsageStats usageStats = getCurrentUsageStats(context, START_TIME, END_TIME);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
return usageStats != null ? usageStats.getTotalTimeInForeground() : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取记录前台应用的UsageStats对象
|
||||
*/
|
||||
private static UsageStats getForegroundUsageStats(Context context, long startTime, long endTime) {
|
||||
UsageStats usageStatsResult = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
List<UsageStats> usageStatses = getUsageStatsList(context, startTime, endTime);
|
||||
if (usageStatses == null || usageStatses.isEmpty()) return null;
|
||||
for (UsageStats usageStats : usageStatses) {
|
||||
if (usageStatsResult == null || usageStatsResult.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
|
||||
usageStatsResult = usageStats;
|
||||
}
|
||||
}
|
||||
}
|
||||
return usageStatsResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取记录当前应用的UsageStats对象
|
||||
*/
|
||||
public static UsageStats getCurrentUsageStats(Context context, long startTime, long endTime) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
List<UsageStats> usageStatses = getUsageStatsList(context, startTime, endTime);
|
||||
if (usageStatses == null || usageStatses.isEmpty()) return null;
|
||||
for (UsageStats usageStats : usageStatses) {
|
||||
if (TextUtils.equals(usageStats.getPackageName(), context.getPackageName())) {
|
||||
return usageStats;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过UsageStatsManager获取List<UsageStats>集合
|
||||
*/
|
||||
public static List<UsageStats> getUsageStatsList(Context context, long startTime, long endTime) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
UsageStatsManager manager = (UsageStatsManager) context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
//UsageStatsManager.INTERVAL_WEEKLY,UsageStatsManager的参数定义了5个,具体查阅源码
|
||||
List<UsageStats> usageStatses = manager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);
|
||||
if (usageStatses == null || usageStatses.size() == 0) {// 没有权限,获取不到数据
|
||||
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.getApplicationContext().startActivity(intent);
|
||||
return null;
|
||||
}
|
||||
return usageStatses;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
122
app/src/main/java/com/vscool/os/utils/GlideLoadUtils.java
Normal file
122
app/src/main/java/com/vscool/os/utils/GlideLoadUtils.java
Normal file
@@ -0,0 +1,122 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.engine.GlideException;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Glide 加载 简单判空封装 防止异步加载数据时调用Glide 抛出异常
|
||||
* Created by Li_Xavier on 2017/6/20 0020.
|
||||
*/
|
||||
public class GlideLoadUtils {
|
||||
private String TAG = "ImageLoader";
|
||||
|
||||
/**
|
||||
* 借助内部类 实现线程安全的单例模式
|
||||
* 属于懒汉式单例,因为Java机制规定,内部类SingletonHolder只有在getInstance()
|
||||
* 方法第一次调用的时候才会被加载(实现了lazy),而且其加载过程是线程安全的。
|
||||
* 内部类加载的时候实例化一次instance。
|
||||
*/
|
||||
public GlideLoadUtils() {
|
||||
}
|
||||
|
||||
private static class GlideLoadUtilsHolder {
|
||||
private final static GlideLoadUtils INSTANCE = new GlideLoadUtils();
|
||||
}
|
||||
|
||||
public static GlideLoadUtils getInstance() {
|
||||
return GlideLoadUtilsHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Glide 加载 简单判空封装 防止异步加载数据时调用Glide 抛出异常
|
||||
*
|
||||
* @param context
|
||||
* @param url 加载图片的url地址 String
|
||||
* @param imageView 加载图片的ImageView 控件
|
||||
* @param defaultImage 图片展示错误的本地图片 id
|
||||
*/
|
||||
public void glideLoad(Context context, String url, ImageView imageView, int defaultImage) {
|
||||
if (context != null) {
|
||||
Glide.with(context).load(url).listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
|
||||
Log.e(TAG, "onLoadFailed: " + e.getMessage());
|
||||
Log.e(TAG, "onLoadFailed: " + url);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
}).error(defaultImage).into(imageView);
|
||||
} else {
|
||||
Log.i(TAG, "Picture loading failed,context is null");
|
||||
}
|
||||
}
|
||||
|
||||
public void glideLoad(Context context, int resId, ImageView imageView, int defaultImage) {
|
||||
if (context != null) {
|
||||
Glide.with(context).load(resId).centerCrop().error(defaultImage).into(imageView);
|
||||
} else {
|
||||
Log.i(TAG, "Picture loading failed,context is null");
|
||||
}
|
||||
}
|
||||
|
||||
public void glideLoad(Context context, String url, ImageView imageView) {
|
||||
if (context != null) {
|
||||
Glide.with(context).load(url).centerCrop().into(imageView);
|
||||
} else {
|
||||
Log.i(TAG, "Picture loading failed,context is null");
|
||||
}
|
||||
}
|
||||
|
||||
public void glideLoad(Context context, File file, ImageView imageView) {
|
||||
if (context != null) {
|
||||
Glide.with(context).load(file).centerCrop().into(imageView);
|
||||
} else {
|
||||
Log.i(TAG, "Picture loading failed,context is null");
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
public void glideLoad(Activity activity, String url, ImageView imageView, int default_image) {
|
||||
if (!activity.isDestroyed()) {
|
||||
Glide.with(activity).load(url).centerCrop().error(default_image).into(imageView);
|
||||
} else {
|
||||
Log.i(TAG, "Picture loading failed,activity is Destroyed");
|
||||
}
|
||||
}
|
||||
|
||||
public void glideLoad(Fragment fragment, String url, ImageView imageView, int default_image) {
|
||||
if (fragment != null && fragment.getActivity() != null) {
|
||||
Glide.with(fragment).load(url).centerCrop().error(default_image).into(imageView);
|
||||
} else {
|
||||
Log.i(TAG, "Picture loading failed,fragment is null");
|
||||
}
|
||||
}
|
||||
|
||||
public void glideLoad(android.app.Fragment fragment, String url, ImageView imageView, int default_image) {
|
||||
if (fragment != null && fragment.getActivity() != null) {
|
||||
Glide.with(fragment).load(url).centerCrop().error(default_image).into(imageView);
|
||||
} else {
|
||||
Log.i(TAG, "Picture loading failed,android.app.Fragment is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
86
app/src/main/java/com/vscool/os/utils/HomeWatcher.java
Normal file
86
app/src/main/java/com/vscool/os/utils/HomeWatcher.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
public class HomeWatcher{
|
||||
|
||||
private static final String TAG = "HomeWatcher";
|
||||
private Context mContext;
|
||||
private IntentFilter mFilter;
|
||||
private OnHomePressedListener mListener;
|
||||
private InnerRecevier mRecevier;
|
||||
|
||||
// 回调接口
|
||||
public interface OnHomePressedListener {
|
||||
public void onHomePressed();
|
||||
public void onHomeLongPressed();
|
||||
}
|
||||
|
||||
public HomeWatcher(Context context) {
|
||||
mContext = context;
|
||||
mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置监听
|
||||
*
|
||||
* @param listener
|
||||
*/
|
||||
public void setOnHomePressedListener(OnHomePressedListener listener) {
|
||||
mListener = listener;
|
||||
mRecevier = new InnerRecevier();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始监听,注册广播
|
||||
*/
|
||||
public void startWatch() {
|
||||
if (mRecevier != null) {
|
||||
mContext.registerReceiver(mRecevier, mFilter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止监听,注销广播
|
||||
*/
|
||||
public void stopWatch() {
|
||||
if (mRecevier != null) {
|
||||
mContext.unregisterReceiver(mRecevier);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 广播接收者
|
||||
*/
|
||||
class InnerRecevier extends BroadcastReceiver {
|
||||
final String SYSTEM_DIALOG_REASON_KEY = "reason";
|
||||
final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
|
||||
final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
|
||||
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent){
|
||||
String action = intent.getAction();
|
||||
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
|
||||
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
|
||||
if (reason != null) {
|
||||
LogUtils.i("action:" + action + ",reason:" + reason);
|
||||
if (mListener != null){
|
||||
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)){
|
||||
// 短按home键
|
||||
mListener.onHomePressed();
|
||||
}else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)){
|
||||
// 长按home键
|
||||
mListener.onHomeLongPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
app/src/main/java/com/vscool/os/utils/IconUtils.java
Normal file
130
app/src/main/java/com/vscool/os/utils/IconUtils.java
Normal file
@@ -0,0 +1,130 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IconUtils {
|
||||
public static List<String> appClassNameList = new ArrayList<String>() {{
|
||||
this.add("com.vscool.shbd");//设备信息
|
||||
this.add("com.vscool.store");//应用市场
|
||||
this.add("aios.appstore");//应用市场
|
||||
this.add("com.uiui.weather");//天气
|
||||
this.add("com.android.browser");//浏览器
|
||||
this.add("com.uiuios.browser");//浏览器
|
||||
this.add("com.aoleyun.browser");//浏览器
|
||||
this.add("com.android.calculator2");//计算器
|
||||
this.add("com.android.calendar");//日历
|
||||
this.add("com.android.camera");//相机
|
||||
this.add("com.mediatek.camera");//相机
|
||||
this.add("com.android.camera2");//相机
|
||||
this.add("com.android.contacts");//通讯录
|
||||
this.add("com.android.deskclock");//时钟
|
||||
this.add("com.android.dialer");//电话
|
||||
this.add("com.android.dialer");//电话
|
||||
this.add("com.android.gallery3d");//图库
|
||||
this.add("com.android.mms");//信息
|
||||
this.add("com.android.mms.ui");//信息
|
||||
this.add("com.android.messaging");//信息
|
||||
this.add("com.android.music");//音乐
|
||||
this.add("com.android.providers.downloads.ui");//下载
|
||||
this.add("com.android.quicksearchbox");//搜索
|
||||
this.add("com.android.settings");//设置
|
||||
this.add("com.android.soundrecorder");//录音机
|
||||
this.add("com.android.stk.StkMain");//sim卡
|
||||
this.add("com.android.stk");//sim卡
|
||||
this.add("com.android.vdieo");//视频
|
||||
this.add("com.mediatek.filemanager");//文件管理
|
||||
this.add("com.android.documentsui");//下载
|
||||
this.add("com.mediatek.fmradio");//收音机
|
||||
this.add("com.android.fmradio");//收音机
|
||||
this.add("com.android.email");//电子邮件
|
||||
// this.add("com.ss.android.ugc.aweme");//抖音
|
||||
// this.add("com.ss.android.article.news");//头条
|
||||
// this.add("com.tencent.mm");//微信
|
||||
}};
|
||||
|
||||
public static List<String> appIconList = new ArrayList<String>() {{
|
||||
this.add("com_uiui_sn");
|
||||
this.add("com_android_appstore");
|
||||
this.add("com_android_appstore");
|
||||
this.add("com_uiui_weather");
|
||||
this.add("com_android_browser");
|
||||
this.add("com_android_browser");
|
||||
this.add("com_android_browser");
|
||||
this.add("com_android_calculator2");
|
||||
this.add("com_android_calendar");
|
||||
this.add("com_android_camera");
|
||||
this.add("com_android_camera");
|
||||
this.add("com_android_camera");
|
||||
this.add("com_android_contacts");
|
||||
this.add("com_android_deskclock");
|
||||
this.add("com_android_dialer");
|
||||
this.add("com_android_dialer");
|
||||
this.add("com_android_gallery3d_app");
|
||||
this.add("com_android_mms_ui");
|
||||
this.add("com_android_mms_ui");
|
||||
this.add("com_android_mms_ui");
|
||||
this.add("com_android_music");
|
||||
this.add("com_android_providers_downloads_ui");
|
||||
this.add("com_android_quicksearchbox");
|
||||
this.add("com_android_settings");
|
||||
this.add("com_android_soundrecorder");
|
||||
this.add("com_android_stk_stkmain");
|
||||
this.add("com_android_stk_stkmain");
|
||||
this.add("com_android_vdieo");
|
||||
this.add("com_mediatek_filemanager");
|
||||
this.add("com_mediatek_filemanager");
|
||||
this.add("com_mediatek_fmradio");
|
||||
this.add("com_mediatek_fmradio");//收音机
|
||||
this.add("com_android_email");
|
||||
// this.add("com_android_aweme2");
|
||||
// this.add("com_android_news2");
|
||||
// this.add("com_tencent_mm2");
|
||||
}};
|
||||
|
||||
public static List<String> appIconList2 = new ArrayList<String>() {{
|
||||
this.add("com_uiui_sn2");
|
||||
this.add("com_android_appstore2");
|
||||
this.add("com_uiui_weather2");
|
||||
this.add("com_android_browser2");
|
||||
this.add("com_android_browser2");
|
||||
this.add("com_android_browser2");
|
||||
this.add("com_android_calculator2");
|
||||
this.add("com_android_calendar");
|
||||
this.add("com_android_camera2");
|
||||
this.add("com_android_camera2");
|
||||
this.add("com_android_camera2");
|
||||
this.add("com_android_contacts");
|
||||
this.add("com_android_deskclock");
|
||||
this.add("com_android_dialer2");
|
||||
this.add("com_android_dialer2");
|
||||
this.add("com_android_gallery3d_app2");
|
||||
this.add("com_android_mms_ui2");
|
||||
this.add("com_android_mms_ui2");
|
||||
this.add("com_android_mms_ui2");
|
||||
this.add("com_android_music");
|
||||
this.add("com_android_providers_downloads_ui");
|
||||
this.add("com_android_quicksearchbox");
|
||||
this.add("com_android_settings2");
|
||||
this.add("com_android_soundrecorder");
|
||||
this.add("com_android_stk_stkmain");
|
||||
this.add("com_android_stk_stkmain");
|
||||
this.add("com_android_vdieo");
|
||||
this.add("com_mediatek_filemanager");
|
||||
this.add("com_mediatek_filemanager");
|
||||
this.add("com_mediatek_fmradio");
|
||||
this.add("com_mediatek_fmradio");//收音机
|
||||
this.add("com_android_email");
|
||||
this.add("com_android_aweme2");
|
||||
this.add("com_android_news2");
|
||||
this.add("com_tencent_mm2");
|
||||
}};
|
||||
|
||||
static {
|
||||
Log.e("IconUtils", "appClassNameList size: " + appClassNameList.size());
|
||||
Log.e("IconUtils", "appIconList size: " + appIconList.size());
|
||||
Log.e("IconUtils", "appIconList2 size: " + appIconList2.size());
|
||||
}
|
||||
}
|
||||
84
app/src/main/java/com/vscool/os/utils/LocalContactUtils.java
Normal file
84
app/src/main/java/com/vscool/os/utils/LocalContactUtils.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.vscool.os.bean.Contact;
|
||||
import com.vscool.os.config.CommonConfig;
|
||||
import com.vscool.os.gson.GsonUtils;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class LocalContactUtils {
|
||||
private static final String TAG = "LocalContactUtils";
|
||||
|
||||
private static MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||
|
||||
|
||||
public static Set<Contact> getLocalContact() {
|
||||
Set<Contact> contacts = new HashSet<>();
|
||||
String jsonString = mMMKV.decodeString(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
return contacts;
|
||||
} else {
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<Set<Contact>>() {
|
||||
}.getType();
|
||||
try {
|
||||
contacts = gson.fromJson(jsonString, type);
|
||||
return contacts;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getLocalContact: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public static boolean addLocalContact(Contact contact) {
|
||||
String jsonString = mMMKV.decodeString(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
Set<Contact> contacts = new HashSet<>();
|
||||
contacts.add(contact);
|
||||
return mMMKV.encode(CommonConfig.CONTACT_LOCAL_CACHE_KEY, GsonUtils.toJSONString(contacts));
|
||||
} else {
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<Set<Contact>>() {
|
||||
}.getType();
|
||||
try {
|
||||
Set<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
if (contacts == null) {
|
||||
contacts = new HashSet<>();
|
||||
}
|
||||
contacts.add(contact);
|
||||
return mMMKV.encode(CommonConfig.CONTACT_LOCAL_CACHE_KEY, GsonUtils.toJSONString(contacts));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "addLocalContact: " + e.getMessage());
|
||||
mMMKV.encode(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static void delLocalContact(Contact contact) {
|
||||
String jsonString = mMMKV.decodeString(CommonConfig.CONTACT_LOCAL_CACHE_KEY, "");
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
return;
|
||||
}
|
||||
Gson gson = new Gson();
|
||||
Type type = new TypeToken<Set<Contact>>() {
|
||||
}.getType();
|
||||
try {
|
||||
Set<Contact> contacts = gson.fromJson(jsonString, type);
|
||||
contacts.remove(contact);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "getLocalContact: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
112
app/src/main/java/com/vscool/os/utils/MD5Util.java
Normal file
112
app/src/main/java/com/vscool/os/utils/MD5Util.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5Util {
|
||||
|
||||
public static String packetMD5(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString();
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static String getUpperMD5Str(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取16位的MD5 值得
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static String getUpperMD5Str16(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString().toUpperCase().substring(8, 24);
|
||||
}
|
||||
|
||||
}
|
||||
184
app/src/main/java/com/vscool/os/utils/MathUtils.java
Normal file
184
app/src/main/java/com/vscool/os/utils/MathUtils.java
Normal file
@@ -0,0 +1,184 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
public final class MathUtils {
|
||||
private static final float DEG_TO_RAD = 0.017453292F;
|
||||
private static final float RAD_TO_DEG = 57.295784F;
|
||||
|
||||
private MathUtils() {
|
||||
}
|
||||
|
||||
public static float abs(float v) {
|
||||
return v > 0.0F ? v : -v;
|
||||
}
|
||||
|
||||
public static int constrain(int amount, int low, int high) {
|
||||
return amount < low ? low : (amount > high ? high : amount);
|
||||
}
|
||||
|
||||
public static long constrain(long amount, long low, long high) {
|
||||
return amount < low ? low : (amount > high ? high : amount);
|
||||
}
|
||||
|
||||
public static float constrain(float amount, float low, float high) {
|
||||
return amount < low ? low : (amount > high ? high : amount);
|
||||
}
|
||||
|
||||
public static float log(float a) {
|
||||
return (float)Math.log((double)a);
|
||||
}
|
||||
|
||||
public static float exp(float a) {
|
||||
return (float)Math.exp((double)a);
|
||||
}
|
||||
|
||||
public static float pow(float a, float b) {
|
||||
return (float)Math.pow((double)a, (double)b);
|
||||
}
|
||||
|
||||
public static float sqrt(float a) {
|
||||
return (float)Math.sqrt((double)a);
|
||||
}
|
||||
|
||||
public static float max(float a, float b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
public static float max(int a, int b) {
|
||||
return a > b ? (float)a : (float)b;
|
||||
}
|
||||
|
||||
public static float max(float a, float b, float c) {
|
||||
return a > b ? (a > c ? a : c) : (b > c ? b : c);
|
||||
}
|
||||
|
||||
public static float max(int a, int b, int c) {
|
||||
return a > b ? (float)(a > c ? a : c) : (float)(b > c ? b : c);
|
||||
}
|
||||
|
||||
public static float min(float a, float b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
public static float min(int a, int b) {
|
||||
return a < b ? (float)a : (float)b;
|
||||
}
|
||||
|
||||
public static float min(float a, float b, float c) {
|
||||
return a < b ? (a < c ? a : c) : (b < c ? b : c);
|
||||
}
|
||||
|
||||
public static float min(int a, int b, int c) {
|
||||
return a < b ? (float)(a < c ? a : c) : (float)(b < c ? b : c);
|
||||
}
|
||||
|
||||
public static float dist(float x1, float y1, float x2, float y2) {
|
||||
float x = x2 - x1;
|
||||
float y = y2 - y1;
|
||||
return (float)Math.hypot((double)x, (double)y);
|
||||
}
|
||||
|
||||
public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) {
|
||||
float x = x2 - x1;
|
||||
float y = y2 - y1;
|
||||
float z = z2 - z1;
|
||||
return (float)Math.sqrt((double)(x * x + y * y + z * z));
|
||||
}
|
||||
|
||||
public static float mag(float a, float b) {
|
||||
return (float)Math.hypot((double)a, (double)b);
|
||||
}
|
||||
|
||||
public static float mag(float a, float b, float c) {
|
||||
return (float)Math.sqrt((double)(a * a + b * b + c * c));
|
||||
}
|
||||
|
||||
public static float sq(float v) {
|
||||
return v * v;
|
||||
}
|
||||
|
||||
public static float dot(float v1x, float v1y, float v2x, float v2y) {
|
||||
return v1x * v2x + v1y * v2y;
|
||||
}
|
||||
|
||||
public static float cross(float v1x, float v1y, float v2x, float v2y) {
|
||||
return v1x * v2y - v1y * v2x;
|
||||
}
|
||||
|
||||
public static float radians(float degrees) {
|
||||
return degrees * 0.017453292F;
|
||||
}
|
||||
|
||||
public static float degrees(float radians) {
|
||||
return radians * 57.295784F;
|
||||
}
|
||||
|
||||
public static float acos(float value) {
|
||||
return (float)Math.acos((double)value);
|
||||
}
|
||||
|
||||
public static float asin(float value) {
|
||||
return (float)Math.asin((double)value);
|
||||
}
|
||||
|
||||
public static float atan(float value) {
|
||||
return (float)Math.atan((double)value);
|
||||
}
|
||||
|
||||
public static float atan2(float a, float b) {
|
||||
return (float)Math.atan2((double)a, (double)b);
|
||||
}
|
||||
|
||||
public static float tan(float angle) {
|
||||
return (float)Math.tan((double)angle);
|
||||
}
|
||||
|
||||
public static float lerp(float start, float stop, float amount) {
|
||||
return start + (stop - start) * amount;
|
||||
}
|
||||
|
||||
public static float lerpInv(float a, float b, float value) {
|
||||
return a != b ? (value - a) / (b - a) : 0.0F;
|
||||
}
|
||||
|
||||
public static float saturate(float value) {
|
||||
return constrain(value, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
public static float lerpInvSat(float a, float b, float value) {
|
||||
return saturate(lerpInv(a, b, value));
|
||||
}
|
||||
|
||||
public static float lerpDeg(float start, float end, float amount) {
|
||||
float minAngle = (end - start + 180.0F) % 360.0F - 180.0F;
|
||||
return minAngle * amount + start;
|
||||
}
|
||||
|
||||
public static float norm(float start, float stop, float value) {
|
||||
return (value - start) / (stop - start);
|
||||
}
|
||||
|
||||
public static float map(float minStart, float minStop, float maxStart, float maxStop, float value) {
|
||||
return maxStart + (maxStop - maxStart) * ((value - minStart) / (minStop - minStart));
|
||||
}
|
||||
|
||||
public static float constrainedMap(float rangeMin, float rangeMax, float valueMin, float valueMax, float value) {
|
||||
return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value));
|
||||
}
|
||||
|
||||
public static float smoothStep(float start, float end, float x) {
|
||||
return constrain((x - start) / (end - start), 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
public static int addOrThrow(int a, int b) throws IllegalArgumentException {
|
||||
if (b == 0) {
|
||||
return a;
|
||||
} else if (b > 0 && a <= 2147483647 - b) {
|
||||
return a + b;
|
||||
} else if (b < 0 && a >= -2147483648 - b) {
|
||||
return a + b;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Addition overflow: " + a + " + " + b);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MobileNetworkUtils {
|
||||
public static CharSequence getCurrentCarrierNameForDisplay(Context context, int subId) {
|
||||
final SubscriptionManager sm = context.getSystemService(SubscriptionManager.class);
|
||||
if (sm != null) {
|
||||
final SubscriptionInfo subInfo = getSubscriptionInfo(sm, subId);
|
||||
if (subInfo != null) {
|
||||
return subInfo.getCarrierName();
|
||||
}
|
||||
}
|
||||
return getOperatorNameFromTelephonyManager(context);
|
||||
}
|
||||
|
||||
private static SubscriptionInfo getSubscriptionInfo(SubscriptionManager subManager,
|
||||
int subId) {
|
||||
List<SubscriptionInfo> subInfos = subManager.getAccessibleSubscriptionInfoList();
|
||||
if (subInfos == null) {
|
||||
subInfos = subManager.getActiveSubscriptionInfoList();
|
||||
}
|
||||
if (subInfos == null) {
|
||||
return null;
|
||||
}
|
||||
for (SubscriptionInfo subInfo : subInfos) {
|
||||
if (subInfo.getSubscriptionId() == subId) {
|
||||
return subInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getOperatorNameFromTelephonyManager(Context context) {
|
||||
final TelephonyManager tm =
|
||||
(TelephonyManager) context.getSystemService(TelephonyManager.class);
|
||||
if (tm == null) {
|
||||
return null;
|
||||
}
|
||||
return tm.getNetworkOperatorName();
|
||||
}
|
||||
}
|
||||
56
app/src/main/java/com/vscool/os/utils/MobileNumberUtils.java
Normal file
56
app/src/main/java/com/vscool/os/utils/MobileNumberUtils.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import com.google.i18n.phonenumbers.NumberParseException;
|
||||
import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
||||
import com.google.i18n.phonenumbers.Phonenumber;
|
||||
import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class MobileNumberUtils {
|
||||
private static final String TAG = "MobileNumberUtils";
|
||||
private static final String LANGUAGE = "CN";
|
||||
|
||||
//获取手机号码运营商
|
||||
public static String getCarrier(String phoneNumber) {
|
||||
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
|
||||
PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();
|
||||
Phonenumber.PhoneNumber referencePhonenumber = new Phonenumber.PhoneNumber();
|
||||
try {
|
||||
referencePhonenumber = phoneNumberUtil.parse(phoneNumber, LANGUAGE);
|
||||
} catch (NumberParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//返回结果只有英文,自己转成成中文
|
||||
String carrierEn = carrierMapper.getNameForNumber(referencePhonenumber, Locale.CHINA);
|
||||
// if (Locale.CHINA.getCountry().equals(Locale.getDefault().getCountry())) {
|
||||
// switch (carrierEn) {
|
||||
// case "China Mobile":
|
||||
// return "中国移动";
|
||||
// case "China Unicom":
|
||||
// return "中国联通";
|
||||
// case "China Telecom":
|
||||
// return "中国电信";
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
return carrierEn;
|
||||
}
|
||||
|
||||
//获取手机号码归属地
|
||||
public static String getGeo(String phoneNumber) {
|
||||
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
|
||||
PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();
|
||||
Phonenumber.PhoneNumber referencePhonenumber = null;
|
||||
try {
|
||||
referencePhonenumber = phoneNumberUtil.parse(phoneNumber, LANGUAGE);
|
||||
//手机号码归属城市 referenceRegion
|
||||
return geocoder.getDescriptionForNumber(referencePhonenumber, Locale.CHINA);
|
||||
} catch (NumberParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "未知";
|
||||
}
|
||||
}
|
||||
84
app/src/main/java/com/vscool/os/utils/NetStateUtils.java
Normal file
84
app/src/main/java/com/vscool/os/utils/NetStateUtils.java
Normal file
@@ -0,0 +1,84 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
public class NetStateUtils {
|
||||
|
||||
/**
|
||||
* 判断网络连接状态
|
||||
*
|
||||
* @param context
|
||||
* @return true:网络已链接, false:网络已断开连接
|
||||
*/
|
||||
public static boolean isNetworkConnected(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mNetworkInfo = mConnectivityManager
|
||||
.getActiveNetworkInfo();
|
||||
if (mNetworkInfo != null) {
|
||||
return mNetworkInfo.isAvailable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断wifi状态
|
||||
*
|
||||
* @param context
|
||||
* @return true:是wifi情况 ,false:非wifi情况
|
||||
*/
|
||||
public static boolean isWifiConnected(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mWiFiNetworkInfo = mConnectivityManager
|
||||
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
if (mWiFiNetworkInfo != null) {
|
||||
return mWiFiNetworkInfo.isAvailable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断移动网络
|
||||
*
|
||||
* @param context
|
||||
* @return true:是移动网络情况, false:非移动网络情况
|
||||
*/
|
||||
public static boolean isMobileConnected(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mMobileNetworkInfo = mConnectivityManager
|
||||
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
|
||||
if (mMobileNetworkInfo != null) {
|
||||
return mMobileNetworkInfo.isAvailable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接类型
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
public static int getConnectedType(Context context) {
|
||||
if (context != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mNetworkInfo = mConnectivityManager
|
||||
.getActiveNetworkInfo();
|
||||
if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
|
||||
return mNetworkInfo.getType();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
30
app/src/main/java/com/vscool/os/utils/SchemeUtils.java
Normal file
30
app/src/main/java/com/vscool/os/utils/SchemeUtils.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
public class SchemeUtils {
|
||||
private static String TAG = "SchemeUtils";
|
||||
|
||||
public static final String SCHEME_TONGUE = "uiuihealth://tongue";
|
||||
public static final String SCHEME_FACE = "uiuihealth://face";
|
||||
public static final String SCHEME_HAND = "uiuihealth://hand";
|
||||
|
||||
public static void openScheme(Activity context, String uri) {
|
||||
if (TextUtils.isEmpty(uri)) {
|
||||
return;
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "openScheme: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
21
app/src/main/java/com/vscool/os/utils/ScreenUtil.java
Normal file
21
app/src/main/java/com/vscool/os/utils/ScreenUtil.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class ScreenUtil {
|
||||
/**
|
||||
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
|
||||
*/
|
||||
public static int dip2px(Context context, float dpValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
|
||||
*/
|
||||
public static int px2dip(Context context, float pxValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (pxValue / scale + 0.5f);
|
||||
}
|
||||
}
|
||||
32
app/src/main/java/com/vscool/os/utils/ScreenUtils.java
Normal file
32
app/src/main/java/com/vscool/os/utils/ScreenUtils.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
public class ScreenUtils {
|
||||
/**
|
||||
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
|
||||
*/
|
||||
public static int dip2px(Context context, float dpValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
|
||||
*/
|
||||
public static int px2dip(Context context, float pxValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (pxValue / scale + 0.5f);
|
||||
}
|
||||
|
||||
public static int dp2px(Resources resources, float dp) {
|
||||
final float scale = resources.getDisplayMetrics().density;
|
||||
return (int) (dp * scale + 0.5f);
|
||||
}
|
||||
|
||||
public static int sp2px(Resources resources, float sp) {
|
||||
final float scale = resources.getDisplayMetrics().scaledDensity;
|
||||
return (int) (sp * scale);
|
||||
}
|
||||
}
|
||||
344
app/src/main/java/com/vscool/os/utils/StatusBarUtil.java
Normal file
344
app/src/main/java/com/vscool/os/utils/StatusBarUtil.java
Normal file
@@ -0,0 +1,344 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Properties;
|
||||
|
||||
public class StatusBarUtil {
|
||||
public static int screenWidth;
|
||||
public static int screenHeight;
|
||||
public static int navigationHeight = 0;
|
||||
|
||||
private static DisplayMetrics mMetrics;
|
||||
public static final String HOME_CURRENT_TAB_POSITION = "HOME_CURRENT_TAB_POSITION";
|
||||
|
||||
public static final String SYS_EMUI = "sys_emui";
|
||||
public static final String SYS_MIUI = "sys_miui";
|
||||
public static final String SYS_FLYME = "sys_flyme";
|
||||
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
|
||||
private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
|
||||
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
|
||||
private static final String KEY_EMUI_API_LEVEL = "ro.build.hw_emui_api_level";
|
||||
private static final String KEY_EMUI_VERSION = "ro.build.version.emui";
|
||||
private static final String KEY_EMUI_CONFIG_HW_SYS_VERSION = "ro.confg.hw_systemversion";
|
||||
|
||||
public static void init(Activity activity) {
|
||||
ViewGroup contentLayout = activity.getWindow().getDecorView().findViewById(Window.ID_ANDROID_CONTENT);
|
||||
StatusBarUtil.setStatusBar(activity, false, true);
|
||||
StatusBarUtil.setStatusTextColor(true, activity);
|
||||
StatusBarUtil.setStatusBarPadding(activity, contentLayout);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
activity.getWindow().setStatusBarColor(activity.getResources().getColor(android.R.color.transparent));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过反射的方式获取状态栏高度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int getStatusBarHeight(Context context) {
|
||||
try {
|
||||
Class<?> c = Class.forName("com.android.internal.R$dimen");
|
||||
Object obj = c.newInstance();
|
||||
Field field = c.getField("status_bar_height");
|
||||
int x = Integer.parseInt(field.get(obj).toString());
|
||||
return context.getResources().getDimensionPixelSize(x);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取底部导航栏高度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static int getNavigationBarHeight(Context context) {
|
||||
Resources resources = context.getResources();
|
||||
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
|
||||
//获取NavigationBar的高度
|
||||
navigationHeight = resources.getDimensionPixelSize(resourceId);
|
||||
return navigationHeight;
|
||||
}
|
||||
|
||||
//获取是否存在NavigationBar
|
||||
public static boolean checkDeviceHasNavigationBar(Context context) {
|
||||
boolean hasNavigationBar = false;
|
||||
Resources rs = context.getResources();
|
||||
int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
|
||||
if (id > 0) {
|
||||
hasNavigationBar = rs.getBoolean(id);
|
||||
}
|
||||
try {
|
||||
Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
|
||||
Method m = systemPropertiesClass.getMethod("get", String.class);
|
||||
String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
|
||||
if ("1".equals(navBarOverride)) {
|
||||
hasNavigationBar = false;
|
||||
} else if ("0".equals(navBarOverride)) {
|
||||
hasNavigationBar = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return hasNavigationBar;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activity
|
||||
* @param useThemestatusBarColor 是否要状态栏的颜色,不设置则为透明色
|
||||
* @param withoutUseStatusBarColor 是否不需要使用状态栏为暗色调
|
||||
*/
|
||||
public static void setStatusBar(Activity activity, boolean useThemestatusBarColor, boolean withoutUseStatusBarColor) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0及以上
|
||||
View decorView = activity.getWindow().getDecorView();
|
||||
int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
decorView.setSystemUiVisibility(option);
|
||||
if (useThemestatusBarColor) {
|
||||
activity.getWindow().setStatusBarColor(activity.getResources().getColor(android.R.color.white));
|
||||
} else {
|
||||
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4到5.0
|
||||
WindowManager.LayoutParams localLayoutParams = activity.getWindow().getAttributes();
|
||||
localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !withoutUseStatusBarColor) {
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reMeasure(Activity activity) {
|
||||
Display display = activity.getWindowManager().getDefaultDisplay();
|
||||
mMetrics = new DisplayMetrics();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
display.getRealMetrics(mMetrics);
|
||||
} else {
|
||||
display.getMetrics(mMetrics);
|
||||
}
|
||||
|
||||
screenWidth = mMetrics.widthPixels;
|
||||
screenHeight = mMetrics.heightPixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变魅族的状态栏字体为黑色,要求FlyMe4以上
|
||||
*/
|
||||
private static void processFlyMe(boolean isLightStatusBar, Activity activity) {
|
||||
WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
|
||||
try {
|
||||
Class<?> instance = Class.forName("android.view.WindowManager$LayoutParams");
|
||||
int value = instance.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON").getInt(lp);
|
||||
Field field = instance.getDeclaredField("meizuFlags");
|
||||
field.setAccessible(true);
|
||||
int origin = field.getInt(lp);
|
||||
if (isLightStatusBar) {
|
||||
field.set(lp, origin | value);
|
||||
} else {
|
||||
field.set(lp, (~value) & origin);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变小米的状态栏字体颜色为黑色, 要求MIUI6以上 lightStatusBar为真时表示黑色字体
|
||||
*/
|
||||
private static void processMIUI(boolean lightStatusBar, Activity activity) {
|
||||
Class<? extends Window> clazz = activity.getWindow().getClass();
|
||||
try {
|
||||
int darkModeFlag;
|
||||
Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
|
||||
Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
|
||||
darkModeFlag = field.getInt(layoutParams);
|
||||
Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
|
||||
extraFlagField.invoke(activity.getWindow(), lightStatusBar ? darkModeFlag : 0, darkModeFlag);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置OPPO手机状态栏字体为黑色(colorOS3.0,6.0以下部分手机)
|
||||
*
|
||||
* @param lightStatusBar
|
||||
* @param activity
|
||||
*/
|
||||
private static final int SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT = 0x00000010;
|
||||
|
||||
private static void setOPPOStatusTextColor(boolean lightStatusBar, Activity activity) {
|
||||
Window window = activity.getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
int vis = window.getDecorView().getSystemUiVisibility();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (lightStatusBar) {
|
||||
vis |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
} else {
|
||||
vis &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (lightStatusBar) {
|
||||
vis |= SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT;
|
||||
} else {
|
||||
vis &= ~SYSTEM_UI_FLAG_OP_STATUS_BAR_TINT;
|
||||
}
|
||||
}
|
||||
window.getDecorView().setSystemUiVisibility(vis);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 判断手机是否是小米
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMIUI() {
|
||||
return SYS_MIUI.equals(getSystem());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断手机是否是魅族
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static boolean isFlyme() {
|
||||
try {
|
||||
// Invoke Build.hasSmartBar()
|
||||
final Method method = Build.class.getMethod("hasSmartBar");
|
||||
return method != null;
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置状态栏文字色值为深色调
|
||||
*
|
||||
* @param useDart 是否使用深色调
|
||||
* @param activity
|
||||
*/
|
||||
public static void setStatusTextColor(boolean useDart, Activity activity) {
|
||||
if (isFlyme()) {
|
||||
processFlyMe(useDart, activity);
|
||||
} else if (isMIUI()) {
|
||||
processMIUI(useDart, activity);
|
||||
} else if (Build.MANUFACTURER.equalsIgnoreCase("OPPO")) {
|
||||
//OPPO
|
||||
setOPPOStatusTextColor(useDart, activity);
|
||||
} else {
|
||||
if (useDart) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
}
|
||||
} else {
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
}
|
||||
activity.getWindow().getDecorView().findViewById(android.R.id.content).setPadding(0, 0, 0, navigationHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 作者:Loyea
|
||||
* 链接:https://www.jianshu.com/p/abd021c22728
|
||||
* 來源:简书
|
||||
* 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
|
||||
*/
|
||||
public static void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {
|
||||
View decor = activity.getWindow().getDecorView();
|
||||
if (dark) {
|
||||
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
} else {
|
||||
// We want to change tint color to white again.
|
||||
// You can also record the flags in advance so that you can turn UI back completely if
|
||||
// you have set other flags before, such as translucent or full screen.
|
||||
decor.setSystemUiVisibility(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getSystem() {
|
||||
String SYS = "";
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
|
||||
if (!TextUtils.isEmpty(getSystemProperty(KEY_MIUI_VERSION_CODE, ""))
|
||||
|| !TextUtils.isEmpty(getSystemProperty(KEY_MIUI_VERSION_NAME, ""))
|
||||
|| !TextUtils.isEmpty(getSystemProperty(KEY_MIUI_INTERNAL_STORAGE, ""))) {
|
||||
SYS = SYS_MIUI;//小米
|
||||
} else if (!TextUtils.isEmpty(getSystemProperty(KEY_EMUI_API_LEVEL, ""))
|
||||
|| !TextUtils.isEmpty(getSystemProperty(KEY_EMUI_VERSION, ""))
|
||||
|| !TextUtils.isEmpty(getSystemProperty(KEY_EMUI_CONFIG_HW_SYS_VERSION, ""))) {
|
||||
SYS = SYS_EMUI;//华为
|
||||
} else if (getMeizuFlymeOSFlag().toLowerCase().contains("flyme")) {
|
||||
SYS = SYS_FLYME;//魅族
|
||||
}
|
||||
return SYS;
|
||||
} else {
|
||||
try {
|
||||
Properties prop = new Properties();
|
||||
prop.load(new FileInputStream(new File(Environment.getRootDirectory(), "build.prop")));
|
||||
if (prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
|
||||
|| prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
|
||||
|| prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null) {
|
||||
SYS = SYS_MIUI;//小米
|
||||
} else if (prop.getProperty(KEY_EMUI_API_LEVEL, null) != null
|
||||
|| prop.getProperty(KEY_EMUI_VERSION, null) != null
|
||||
|| prop.getProperty(KEY_EMUI_CONFIG_HW_SYS_VERSION, null) != null) {
|
||||
SYS = SYS_EMUI;//华为
|
||||
} else if (getMeizuFlymeOSFlag().toLowerCase().contains("flyme")) {
|
||||
SYS = SYS_FLYME;//魅族
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return SYS;
|
||||
} finally {
|
||||
return SYS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getSystemProperty(String key, String defaultValue) {
|
||||
try {
|
||||
Class<?> clz = Class.forName("android.os.SystemProperties");
|
||||
Method get = clz.getMethod("get", String.class, String.class);
|
||||
return (String) get.invoke(clz, key, defaultValue);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static String getMeizuFlymeOSFlag() {
|
||||
return getSystemProperty("ro.build.display.id", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 全屏模式下 针对刘海屏向下移动view
|
||||
*
|
||||
* @param context
|
||||
* @param view 需要设置padding的view
|
||||
*/
|
||||
public static void setStatusBarPadding(Context context, View view) {
|
||||
if (view != null) {
|
||||
view.setPadding(0, getStatusBarHeight(context), 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
app/src/main/java/com/vscool/os/utils/TimeUtils.java
Normal file
72
app/src/main/java/com/vscool/os/utils/TimeUtils.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
|
||||
public class TimeUtils {
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public static boolean isTodayTime(long timeStamp) {
|
||||
String time = transferLongToDate(timeStamp);
|
||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
LocalDateTime localTime = LocalDateTime.parse(time, dtf);
|
||||
LocalDateTime startTime = LocalDate.now().atTime(0, 0, 0);
|
||||
LocalDateTime endTime = LocalDate.now().atTime(23, 59, 59);
|
||||
return localTime.isAfter(startTime) && localTime.isBefore(endTime);
|
||||
}
|
||||
|
||||
public static String transferLongToDate(Long millSec) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date date = new Date(millSec);
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static String transferSecondgToDate(long second) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date date = new Date(second * 1000);
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static String transferSecondgToHour(long second) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||
Date date = new Date(second * 1000);
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static String secToTime(int totalSecs) {
|
||||
int hours = totalSecs / 3600;
|
||||
int minutes = (totalSecs % 3600) / 60;
|
||||
int seconds = totalSecs % 60;
|
||||
String timeString = String.format("%02d:%02d:%02d", hours, minutes, seconds);
|
||||
return timeString;
|
||||
}
|
||||
|
||||
public static String getNowTime(Context context) {
|
||||
long time = System.currentTimeMillis();
|
||||
Date date = new Date(time);
|
||||
String timeFormatString = Settings.System.getString(context.getContentResolver(), Settings.System.TIME_12_24);
|
||||
SimpleDateFormat sdf;
|
||||
if ("24".equals(timeFormatString)) {
|
||||
sdf = new SimpleDateFormat("HH:mm");
|
||||
} else {
|
||||
sdf = new SimpleDateFormat("hh:mm");
|
||||
}
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static String getDateWeek() {
|
||||
long time = System.currentTimeMillis();
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("MM月-dd日");
|
||||
Date date2 = new Date(time);
|
||||
return sdf2.format(date2);
|
||||
}
|
||||
|
||||
}
|
||||
411
app/src/main/java/com/vscool/os/utils/Utils.java
Normal file
411
app/src/main/java/com/vscool/os/utils/Utils.java
Normal file
@@ -0,0 +1,411 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.role.RoleManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.UserHandle;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.vscool.os.BuildConfig;
|
||||
import com.vscool.os.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Utils {
|
||||
private static final String TAG = "Utils";
|
||||
|
||||
/**
|
||||
* 获取设备序列号
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
public static String getSerial() {
|
||||
String serial = "unknow";
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
|
||||
serial = Build.getSerial();
|
||||
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
|
||||
serial = Build.SERIAL;
|
||||
} else {//8.0-
|
||||
Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
Method get = c.getMethod("get", String.class);
|
||||
serial = (String) get.invoke(c, "ro.serialno");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("e", "读取设备序列号异常:" + e.toString());
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
// return "QNG2DKB00463";
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
||||
public static String getDeviceSN() {
|
||||
String serial = null;
|
||||
try {
|
||||
Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
Method get = c.getMethod("get", String.class);
|
||||
serial = (String) get.invoke(c, "persist.sys.hrSerial");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电量
|
||||
*
|
||||
* @param mContext
|
||||
* @return
|
||||
*/
|
||||
synchronized public static int getBatteryLevel(Context mContext) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return ((BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE)).getIntProperty(4);
|
||||
} else {
|
||||
Intent intent = (new ContextWrapper(mContext)).registerReceiver(null, new IntentFilter("android.intent.action.BATTERY_CHANGED"));
|
||||
return intent.getIntExtra("level", -1) * 100 / intent.getIntExtra("scale", -1);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDownLoadPath(Context context) {
|
||||
String path = ContextCompat.getExternalFilesDirs(context, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath();
|
||||
return path + File.separator;
|
||||
}
|
||||
|
||||
public static String getFileNamefromURL(String url) {
|
||||
int position = url.lastIndexOf("/");
|
||||
return url.substring(position + 1);
|
||||
}
|
||||
|
||||
public static void openLauncher3(Context context) {
|
||||
setDefaultDesktop(context, Launcher3, Launcher3Class);
|
||||
// ApkUtils.openPackage(mContext, Launcher3);
|
||||
gotoLauncher(context);
|
||||
}
|
||||
|
||||
public static void gotoLauncher(Context context) {
|
||||
Intent i = new Intent(Intent.ACTION_MAIN);
|
||||
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //android123提示如果是服务里调用,必须加入new task标识
|
||||
i.addCategory(Intent.CATEGORY_HOME);
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
private static final String Launcher3 = "com.android.launcher3";
|
||||
private static final String Launcher3Class = "com.android.launcher3.Launcher";
|
||||
|
||||
public static void setDefaultDesktop(Context context, String pkg, String className) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
setRoleHolderAsUser(context, pkg);
|
||||
Log.e(TAG, "setDefaultDesktop: setRoleHolderAsUser");
|
||||
} else {
|
||||
//爱华设置,暂时屏蔽
|
||||
// setDefaultLauncher(mContext, pkg, className);
|
||||
Log.e(TAG, "setDefaultDesktop: setDefaultLauncher");
|
||||
}
|
||||
// String oldDesktop = (String) SPUtils.get(mContext, "default_launcher", "");
|
||||
// if (Objects.equals(oldDesktop, pkg)) {
|
||||
// Log.e(TAG, "setDefaultDesktop: " + "数据一致");
|
||||
// return;
|
||||
// }
|
||||
Intent intent = new Intent("setDefaultLauncher");
|
||||
intent.putExtra("package", pkg);
|
||||
intent.putExtra("className", className);
|
||||
// if (JGYUtils.getInstance().checkAppPlatform() == MTKPlatform) {
|
||||
Log.e(TAG, "setDefaultDesktop: MTK");
|
||||
//爱华定制
|
||||
intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.AoleReceiver"));
|
||||
// TODO: 2022/7/6 有问题
|
||||
setDefaultLauncher(context, "com.android.transfer", "com.android.transfer.OldMainActivity");
|
||||
// SystemProperties.set("persist.sys.launcher.pkgname", pkg);
|
||||
// SystemProperties.set("persist.sys.launcher.classname", className);
|
||||
// }
|
||||
intent.setPackage("com.android.settings");
|
||||
context.sendBroadcast(intent);
|
||||
// ApkUtils.openPackage(mContext, pkg);
|
||||
Log.e(TAG, "setDefaultDesktop: " + pkg + ":" + className);
|
||||
// Log.e(TAG, "setDefaultDesktop: " + "persist.sys.launcher.pkgname = " + SystemProperties.get("persist.sys.launcher.pkgname"));
|
||||
// Log.e(TAG, "setDefaultDesktop: " + "persist.sys.launcher.classname = " + SystemProperties.get("persist.sys.launcher.classname"));
|
||||
}
|
||||
|
||||
public static void setDefaultLauncher(Context context, String defPackageName, String defClassName) {
|
||||
try {
|
||||
if (!TextUtils.isEmpty(defPackageName) && !TextUtils.isEmpty(defClassName)) {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction("android.intent.action.MAIN");
|
||||
filter.addCategory("android.intent.category.HOME");
|
||||
filter.addCategory("android.intent.category.DEFAULT");
|
||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
// 返回给定条件的所有ResolveInfo对象(本质上是Activity)
|
||||
List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
int bestMatch = 0;
|
||||
final int size = list.size();
|
||||
ComponentName[] set = new ComponentName[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
ResolveInfo ri = list.get(i);
|
||||
set[i] = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
|
||||
if (ri.match > bestMatch) {
|
||||
bestMatch = ri.match;
|
||||
}
|
||||
}
|
||||
ComponentName preActivity = new ComponentName(defPackageName, defClassName);
|
||||
context.getPackageManager().addPreferredActivity(filter, bestMatch, set, preActivity);
|
||||
}
|
||||
} catch (java.lang.SecurityException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "setDefaultLauncher: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void setRoleHolderAsUser(Context context, String packageName) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
String roleName = "android.app.role.HOME";
|
||||
boolean add = true;
|
||||
int flags = 0;
|
||||
UserHandle user = android.os.Process.myUserHandle();
|
||||
Log.i("settingssssssstemf", (add ? "Adding" : "Removing") + " package as role holder, role: "
|
||||
+ roleName + ", package: " + packageName);
|
||||
// if (JGYUtils.getInstance().checkAppPlatform() != JGYUtils.MTKPlatform) {
|
||||
RoleManager roleManager = context.getSystemService(RoleManager.class);
|
||||
Executor executor = context.getMainExecutor();
|
||||
Consumer<Boolean> callback = successful -> {
|
||||
if (successful) {
|
||||
Log.d("settingssssssstemf", "Package " + (add ? "added" : "removed")
|
||||
+ " as role holder, role: " + roleName + ", package: " + packageName);
|
||||
} else {
|
||||
Log.d("settingssssssstemf", "Failed to " + (add ? "add" : "remove")
|
||||
+ " package as role holder, role: " + roleName + ", package: "
|
||||
+ packageName);
|
||||
}
|
||||
};
|
||||
// roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
|
||||
Log.i("settingssssssstemf", "addRoleHolderAsUser done");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public static Bitmap getRoundedBitmap(Bitmap mBitmap, Context context) {
|
||||
Bitmap bgBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);
|
||||
|
||||
Bitmap mask = BitmapFactory.decodeResource(context.getResources(), R.drawable.mask);
|
||||
int width = mask.getWidth();
|
||||
int height = mask.getHeight();
|
||||
Bitmap bitmapScale = Bitmap.createScaledBitmap(mBitmap, width, height, true);
|
||||
bitmapScale.setDensity(context.getResources().getDisplayMetrics().densityDpi);
|
||||
// Palette p = Palette.from(mBitmap).generate();
|
||||
// Palette.Swatch vibrant = p.getVibrantSwatch();//有活力的
|
||||
// int color = vibrant.getRgb(); //样本中的像素数量
|
||||
|
||||
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas();
|
||||
Paint paint = new Paint();
|
||||
|
||||
canvas.setBitmap(result);
|
||||
// canvas.drawColor(color);
|
||||
canvas.drawBitmap(mask, 0, 0, paint);
|
||||
// paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
canvas.drawBitmap(bitmapScale, 0, 0, paint);
|
||||
// return result;
|
||||
|
||||
Bitmap result2 = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas2 = new Canvas();
|
||||
Paint paint2 = new Paint();
|
||||
canvas2.setBitmap(result2);
|
||||
canvas2.drawBitmap(mask, 0, 0, paint2);
|
||||
paint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
canvas2.drawBitmap(result, 0, 0, paint2);
|
||||
return result2;
|
||||
|
||||
|
||||
// Canvas mCanvas = new Canvas();
|
||||
// mCanvas.setBitmap(bgBitmap);
|
||||
// Paint mPaint = new Paint();
|
||||
// RectF mRectM = new RectF(scaleM, scaleM, mBitmap.getWidth() - scaleM, mBitmap.getHeight() - scaleM); //设置剪裁圆角的区域
|
||||
// Rect mRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
|
||||
// RectF mRectF = mRectM;
|
||||
//
|
||||
// float roundPx = 15; //圆角半径
|
||||
// mPaint.setAntiAlias(true);
|
||||
// //Log.d("wy"+TAG,"mBitmap.getWidth()="+mBitmap.getWidth()+", mBitmap.getHeight()="+mBitmap.getHeight());
|
||||
// mCanvas.drawRoundRect(mRectF, roundPx, roundPx, mPaint);
|
||||
// mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
// mCanvas.drawBitmap(mBitmap, mRect, mRect, mPaint);
|
||||
// return bgBitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统配置信息
|
||||
*
|
||||
* @param key
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public static String getProperty(String key, String defaultValue) {
|
||||
String value = defaultValue;
|
||||
try {
|
||||
Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
Method get = c.getMethod("get", String.class, String.class);
|
||||
value = (String) (get.invoke(c, key, "unknown"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isTablet(Context context) {
|
||||
// return isPad();
|
||||
boolean isTablet = (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
|
||||
Log.e(TAG, "isTablet: " + isTablet);
|
||||
return isTablet;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isPad() {
|
||||
boolean result = false;
|
||||
String mDeviceType = getProperty("ro.build.characteristics", "default");
|
||||
Log.e(TAG, "isPad: " + mDeviceType);
|
||||
if (mDeviceType != null && mDeviceType.equalsIgnoreCase("tablet")) {
|
||||
result = true;
|
||||
}
|
||||
Log.d(TAG, "isPad:" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含SIM卡
|
||||
*
|
||||
* @return 状态
|
||||
*/
|
||||
public static boolean hasSimCard(Context context) {
|
||||
TelephonyManager telMgr = (TelephonyManager)
|
||||
context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
int simState = telMgr.getSimState();
|
||||
boolean result = true;
|
||||
switch (simState) {
|
||||
case TelephonyManager.SIM_STATE_ABSENT:
|
||||
result = false; // 没有SIM卡
|
||||
break;
|
||||
case TelephonyManager.SIM_STATE_UNKNOWN:
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
Log.d("try", result ? "有SIM卡" : "无SIM卡");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isMultiSim(Context context) {
|
||||
boolean result = false;
|
||||
TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
|
||||
if (telecomManager != null) {
|
||||
List<PhoneAccountHandle> phoneAccountHandleList = telecomManager.getCallCapablePhoneAccounts();
|
||||
result = phoneAccountHandleList.size() >= 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void call(Context context, int id, String telNum) {
|
||||
TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
|
||||
if (telecomManager != null) {
|
||||
List<PhoneAccountHandle> phoneAccountHandleList = telecomManager.getCallCapablePhoneAccounts();
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_CALL);
|
||||
intent.setData(Uri.parse("tel:" + telNum));
|
||||
intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandleList.get(id));
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("HardwareIds")
|
||||
public static String getIMEI(Context context, int slotIndex) {
|
||||
String imei;
|
||||
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
imei = tm.getImei(slotIndex);
|
||||
} else {
|
||||
imei = tm.getDeviceId(slotIndex);
|
||||
}
|
||||
if (TextUtils.isEmpty(imei)) {
|
||||
return "暂无数据";
|
||||
}
|
||||
return imei;
|
||||
}
|
||||
|
||||
public static String getEmid(Context context) {
|
||||
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
String meid = telephonyManager.getDeviceId();
|
||||
return meid;
|
||||
}
|
||||
|
||||
public static String getCacheDir(Context context) {
|
||||
String cachePath;
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|
||||
|| !Environment.isExternalStorageRemovable()) {
|
||||
if (context.getExternalCacheDir() != null) {
|
||||
cachePath = context.getExternalCacheDir().getPath();
|
||||
} else if (context.getExternalFilesDir("cache") != null) {
|
||||
cachePath = context.getExternalFilesDir("cache").getPath();
|
||||
} else {
|
||||
cachePath = context.getCacheDir().getPath();
|
||||
}
|
||||
} else {
|
||||
cachePath = context.getCacheDir().getPath();
|
||||
}
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
public static String getAndroiodScreenProperty(Context context) {
|
||||
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
wm.getDefaultDisplay().getRealMetrics(dm);
|
||||
int width = dm.widthPixels; // 屏幕宽度(像素)
|
||||
int height = dm.heightPixels; // 屏幕高度(像素)
|
||||
float density = dm.density; // 屏幕密度(0.75 / 1.0 / 1.5)
|
||||
int densityDpi = dm.densityDpi; // 屏幕密度dpi(120 / 160 / 240)
|
||||
// 屏幕宽度算法:屏幕宽度(像素)/屏幕密度
|
||||
int screenWidth = (int) (width / density); // 屏幕宽度(dp)
|
||||
int screenHeight = (int) (height / density);// 屏幕高度(dp)
|
||||
|
||||
Log.e("getAndroiodScreenProperty", "屏幕宽度(像素):" + width);
|
||||
Log.e("getAndroiodScreenProperty", "屏幕高度(像素):" + height);
|
||||
Log.e("getAndroiodScreenProperty", "屏幕密度(0.75 / 1.0 / 1.5):" + density);
|
||||
Log.e("getAndroiodScreenProperty", "屏幕密度dpi(120 / 160 / 240):" + densityDpi);
|
||||
Log.e("getAndroiodScreenProperty", "屏幕宽度(dp):" + screenWidth);
|
||||
Log.e("getAndroiodScreenProperty", "屏幕高度(dp):" + screenHeight);
|
||||
|
||||
Log.e("getAndroiodScreenProperty", "smallestScreenWidthDp: " + context.getResources().getConfiguration().smallestScreenWidthDp);
|
||||
return width + "×" + height;
|
||||
}
|
||||
}
|
||||
119
app/src/main/java/com/vscool/os/utils/WakeUpUtils.java
Normal file
119
app/src/main/java/com/vscool/os/utils/WakeUpUtils.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.KeyguardManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.PowerManager;
|
||||
import android.util.Log;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class WakeUpUtils {
|
||||
|
||||
/**
|
||||
* 唤醒手机屏幕并解锁
|
||||
*/
|
||||
public static void wakeUpAndUnlock(Activity activity) {
|
||||
// 获取电源管理器对象
|
||||
PowerManager pm = (PowerManager) activity.getApplicationContext()
|
||||
.getSystemService(Context.POWER_SERVICE);
|
||||
boolean screenOn = pm.isScreenOn();
|
||||
Log.d("WakeScreen0", "screenOn: " + screenOn);
|
||||
if (!screenOn) {
|
||||
// 获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是LogCat里用的Tag
|
||||
@SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wl = pm.newWakeLock(
|
||||
PowerManager.ACQUIRE_CAUSES_WAKEUP |
|
||||
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright");
|
||||
wl.acquire(10000); // 点亮屏幕
|
||||
wl.release(); // 释放
|
||||
}
|
||||
// 屏幕解锁
|
||||
KeyguardManager keyguardManager = (KeyguardManager) activity.getApplicationContext()
|
||||
.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("unLock");
|
||||
// 屏幕锁定
|
||||
// keyguardLock.reenableKeyguard();
|
||||
keyguardLock.disableKeyguard(); // 解锁
|
||||
unLockScreen(activity);
|
||||
}
|
||||
|
||||
private static void unLockScreen(Activity activity) {
|
||||
final Window win = activity.getWindow();
|
||||
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
|
||||
|
||||
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
|
||||
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
|
||||
}
|
||||
|
||||
/**
|
||||
* 唤醒手机屏幕并解锁
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public static void wakeUpAndUnlockScreen(Activity activity) {
|
||||
|
||||
Window win = activity.getWindow();
|
||||
win.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|
||||
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
|
||||
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||
|
||||
PowerManager pm = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
|
||||
@SuppressLint("InvalidWakeLockTag")
|
||||
PowerManager.WakeLock wakelock = pm.newWakeLock(
|
||||
PowerManager.FULL_WAKE_LOCK
|
||||
| PowerManager.ACQUIRE_CAUSES_WAKEUP, "xx");
|
||||
wakelock.acquire();
|
||||
wakelock.release();
|
||||
|
||||
KeyguardManager keyguardManager = (KeyguardManager) activity.getApplicationContext()
|
||||
.getSystemService(Context.KEYGUARD_SERVICE);
|
||||
|
||||
if (activity == null) return;
|
||||
keyguardManager.requestDismissKeyguard(activity, new KeyguardManager.KeyguardDismissCallback() {
|
||||
@Override
|
||||
public void onDismissError() {
|
||||
super.onDismissError();
|
||||
Log.d("xxx-->", "1 onDismissError");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissSucceeded() {
|
||||
super.onDismissSucceeded();
|
||||
Log.d("xxx-->", "1 onDismissSucceeded");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissCancelled() {
|
||||
super.onDismissCancelled();
|
||||
Log.d("xxx-->", "1 onDismissCancelled");
|
||||
}
|
||||
});
|
||||
|
||||
if (activity == null) return;
|
||||
keyguardManager.requestDismissKeyguard(activity, new KeyguardManager.KeyguardDismissCallback() {
|
||||
@Override
|
||||
public void onDismissError() {
|
||||
super.onDismissError();
|
||||
Log.d("xxx-->", "2 onDismissError");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissSucceeded() {
|
||||
super.onDismissSucceeded();
|
||||
Log.d("xxx-->", "2 onDismissSucceeded");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismissCancelled() {
|
||||
super.onDismissCancelled();
|
||||
Log.d("xxx-->", "2 onDismissCancelled");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
241
app/src/main/java/com/vscool/os/utils/WiFiUtils.java
Normal file
241
app/src/main/java/com/vscool/os/utils/WiFiUtils.java
Normal file
@@ -0,0 +1,241 @@
|
||||
package com.vscool.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author : fanhuitong
|
||||
* e-mail :
|
||||
* @date : 2021/10/25 10:20
|
||||
* desc :
|
||||
* version: 1.0
|
||||
*/
|
||||
public class WiFiUtils {
|
||||
private static WiFiUtils sInstance;
|
||||
private static WifiManager mWifiManager;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private Context mContext;
|
||||
private static String TAG = "WiFiUtils";
|
||||
|
||||
public WiFiUtils(Context context) {
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
if (sInstance == null) {
|
||||
Log.e(TAG, "init: ");
|
||||
sInstance = new WiFiUtils(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static WiFiUtils getInstance() {
|
||||
if (sInstance == null) {
|
||||
throw new IllegalStateException("You must be init WiFiUtils first");
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* wifi是否打开
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isWifiEnable() {
|
||||
boolean isEnable = false;
|
||||
if (mWifiManager != null) {
|
||||
if (mWifiManager.isWifiEnabled()) {
|
||||
isEnable = true;
|
||||
}
|
||||
}
|
||||
return isEnable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开WiFi
|
||||
*/
|
||||
public void openWifi() {
|
||||
if (mWifiManager != null && !isWifiEnable()) {
|
||||
mWifiManager.setWifiEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭WiFi
|
||||
*/
|
||||
public void closeWifi() {
|
||||
if (mWifiManager != null && isWifiEnable()) {
|
||||
mWifiManager.setWifiEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取WiFi列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<ScanResult> getWifiList() {
|
||||
List<ScanResult> resultList = new ArrayList<>();
|
||||
if (mWifiManager != null && isWifiEnable()) {
|
||||
resultList.addAll(mWifiManager.getScanResults());
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 有密码连接
|
||||
*
|
||||
* @param ssid
|
||||
* @param pws
|
||||
*/
|
||||
public static void connectWifiPws(String ssid, String pws) {
|
||||
// mWifiManager.disableNetwork(mWifiManager.getConnectionInfo().getNetworkId());
|
||||
mWifiManager.disconnect();
|
||||
int netId = mWifiManager.addNetwork(getWifiConfig(ssid, pws, true));
|
||||
mWifiManager.enableNetwork(netId, true);
|
||||
mWifiManager.reconnect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 无密码连接
|
||||
*
|
||||
* @param ssid
|
||||
*/
|
||||
public void connectWifiNoPws(String ssid) {
|
||||
// mWifiManager.disableNetwork(mWifiManager.getConnectionInfo().getNetworkId());
|
||||
int netId = mWifiManager.addNetwork(getWifiConfig(ssid, "", false));
|
||||
mWifiManager.enableNetwork(netId, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* wifi设置
|
||||
*
|
||||
* @param ssid
|
||||
* @param pws
|
||||
* @param isHasPws
|
||||
*/
|
||||
private static WifiConfiguration getWifiConfig(String ssid, String pws, boolean isHasPws) {
|
||||
WifiConfiguration config = new WifiConfiguration();
|
||||
config.allowedAuthAlgorithms.clear();
|
||||
config.allowedGroupCiphers.clear();
|
||||
config.allowedKeyManagement.clear();
|
||||
config.allowedPairwiseCiphers.clear();
|
||||
config.allowedProtocols.clear();
|
||||
config.SSID = "\"" + ssid + "\"";
|
||||
|
||||
WifiConfiguration tempConfig = isExist(ssid);
|
||||
if (tempConfig != null) {
|
||||
mWifiManager.removeNetwork(tempConfig.networkId);
|
||||
}
|
||||
if (isHasPws) {
|
||||
config.preSharedKey = "\"" + pws + "\"";
|
||||
config.hiddenSSID = true;
|
||||
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
|
||||
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
|
||||
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
|
||||
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
|
||||
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
|
||||
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
|
||||
config.status = WifiConfiguration.Status.ENABLED;
|
||||
} else {
|
||||
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到配置好的网络连接
|
||||
*
|
||||
* @param ssid
|
||||
* @return
|
||||
*/
|
||||
private static WifiConfiguration isExist(String ssid) {
|
||||
List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
|
||||
for (WifiConfiguration config : configs) {
|
||||
if (config.SSID.equals("\"" + ssid + "\"")) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addWiFiNetwork(String ssid, String passwd) {
|
||||
int netId;
|
||||
if (TextUtils.isEmpty(passwd)) {
|
||||
netId = mWifiManager.addNetwork(getWifiConfig(ssid, "", false));
|
||||
} else {
|
||||
netId = mWifiManager.addNetwork(getWifiConfig(ssid, passwd, true));
|
||||
}
|
||||
mWifiManager.enableNetwork(netId, true);
|
||||
}
|
||||
|
||||
public static void removeWiFiNetwork(String ssid) {
|
||||
WifiConfiguration tempConfig = isExist(ssid);
|
||||
int networkId = tempConfig.networkId;
|
||||
mWifiManager.removeNetwork(networkId);
|
||||
mWifiManager.saveConfiguration();
|
||||
}
|
||||
|
||||
synchronized private static boolean wifiSaved(String ssid) {
|
||||
// 获取已保存wifi配置链表
|
||||
List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
|
||||
boolean saved = false;
|
||||
for (WifiConfiguration configuration : configs) {
|
||||
if (ssid.equals(configuration.SSID)) {
|
||||
saved = true;
|
||||
}
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
//断判某个wifi是否是连接成功的那个wifi
|
||||
public boolean isConnectedWifi(Context context, String myssid) {
|
||||
WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
if (isWifiConnect(context)) {
|
||||
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
|
||||
String ssid = wifiInfo.getSSID();
|
||||
return ssid != null && ssid.contains(myssid);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//判断wifi是否连接
|
||||
public static boolean isWifiConnect(Context context) {
|
||||
ConnectivityManager connManager = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
@SuppressLint("MissingPermission")
|
||||
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
return mWifi.getState() == NetworkInfo.State.CONNECTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断网络连接状态
|
||||
*
|
||||
* @return true:网络已链接, false:网络已断开连接
|
||||
*/
|
||||
public boolean isNetworkConnected() {
|
||||
if (mContext != null) {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) mContext
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mNetworkInfo = mConnectivityManager
|
||||
.getActiveNetworkInfo();
|
||||
if (mNetworkInfo != null) {
|
||||
return mNetworkInfo.isAvailable();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user