首次提交
This commit is contained in:
17
nebula-sdk/src/main/java/com/android/api/CoreKeys.java
Normal file
17
nebula-sdk/src/main/java/com/android/api/CoreKeys.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.android.api;
|
||||
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class CoreKeys {
|
||||
|
||||
public static final String SESSIONID = "sessionid";
|
||||
public static final String CONFIGDATABEAN="ConfigDataBean";
|
||||
|
||||
public static String local_file = Environment.getExternalStorageDirectory()
|
||||
+ File.separator + Environment.DIRECTORY_DCIM
|
||||
+ File.separator + "Camera" + File.separator;
|
||||
public static String down_file = Environment.getExternalStorageDirectory().getAbsolutePath() + "/atv-ota/";
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
|
||||
|
||||
public class AESUtil {
|
||||
|
||||
|
||||
private static final String password="wwwwaaabbb";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dataStr
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String encryptVerification(String dataStr){
|
||||
|
||||
if(dataStr==null||"".equals(dataStr)){
|
||||
return "";
|
||||
}
|
||||
String headMsg="";
|
||||
String endMag="";
|
||||
String addendMag="";
|
||||
if(dataStr.length()>3) {
|
||||
headMsg = dataStr.substring(0,3);
|
||||
}
|
||||
if(dataStr.length()>4){
|
||||
endMag=dataStr.substring(dataStr.length()-4,dataStr.length());
|
||||
}
|
||||
if(dataStr.length()>7){
|
||||
addendMag=dataStr.substring(0,7);
|
||||
}
|
||||
String time=TimeUtil.getDateEND(System.currentTimeMillis());
|
||||
String tmp=headMsg+time+addendMag+endMag;
|
||||
String verification = MD5Utils.md5(tmp).substring(0,15);
|
||||
return UtilEncrypt.encrypt(password,verification);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * 测试
|
||||
// *
|
||||
// * @param args
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public static void main(String[] args) throws Exception {
|
||||
//// String test= encryptVerification("8618665362153","123456");
|
||||
//
|
||||
// String test=UtilEncrypt.encrypt("test","123456");
|
||||
// System.out.print(test);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* Created by jzm on 2016/7/18.
|
||||
*/
|
||||
public class MD5Utils {
|
||||
|
||||
/**
|
||||
* 使用md5的算法进行加密
|
||||
*/
|
||||
public static String md5(String encryptStr) {
|
||||
MessageDigest md5;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
byte[] md5Bytes = md5.digest(encryptStr.getBytes());
|
||||
StringBuffer hexValue = new StringBuffer();
|
||||
for (int i = 0; i < md5Bytes.length; i++) {
|
||||
int val = ((int) md5Bytes[i]) & 0xff;
|
||||
if (val < 16)
|
||||
hexValue.append("0");
|
||||
hexValue.append(Integer.toHexString(val));
|
||||
}
|
||||
encryptStr = hexValue.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return encryptStr.toLowerCase();
|
||||
}
|
||||
}
|
||||
551
nebula-sdk/src/main/java/com/android/api/encrytion/TimeUtil.java
Normal file
551
nebula-sdk/src/main/java/com/android/api/encrytion/TimeUtil.java
Normal file
@@ -0,0 +1,551 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* 时间转换工具
|
||||
*/
|
||||
public class TimeUtil {
|
||||
public static final long DAY_MILLSECONDS = 24 * 3600 * 1000;
|
||||
|
||||
private TimeUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间戳(毫秒)转换为时分秒格式(HH:mm:ss)
|
||||
*
|
||||
* @param milliseconds 时间戳(毫秒)
|
||||
* @return 格式化后的时间字符串(HH:mm:ss)
|
||||
*/
|
||||
public static String convertToHMS(long milliseconds) {
|
||||
// 确保时间戳为非负数
|
||||
if (milliseconds < 0) {
|
||||
throw new IllegalArgumentException("时间戳不能为负数");
|
||||
}
|
||||
|
||||
long hours = TimeUnit.MILLISECONDS.toHours(milliseconds);
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(milliseconds)
|
||||
- TimeUnit.HOURS.toMinutes(hours);
|
||||
long seconds = TimeUnit.MILLISECONDS.toSeconds(milliseconds)
|
||||
- TimeUnit.HOURS.toSeconds(hours)
|
||||
- TimeUnit.MINUTES.toSeconds(minutes);
|
||||
|
||||
// 格式化输出,确保两位数字
|
||||
return String.format("%02dh%02dm%02ds", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
public static String showMessageTime(long MessageTime) {
|
||||
SimpleDateFormat format;
|
||||
String showtimeString;
|
||||
long startTime = MessageTime * 1000;
|
||||
//获取当前年份
|
||||
int current_year = Integer.parseInt(getYear(System.currentTimeMillis()));
|
||||
//获取发消息的年份
|
||||
int year = Integer.parseInt(getYear(startTime));
|
||||
if (current_year > year) {
|
||||
//不在同一年 显示完整的年月日
|
||||
showtimeString = getDateEN(startTime);
|
||||
} else {
|
||||
if (newchajitian(startTime) == 0) {
|
||||
//同一天 显示时分
|
||||
format = new SimpleDateFormat("HH:mm");
|
||||
showtimeString = format.format(new Date(startTime));
|
||||
} else if (newchajitian(startTime) == 1) {
|
||||
//相差一天 显示昨天
|
||||
showtimeString = "昨天";
|
||||
} else if (newchajitian(startTime) > 1 && newchajitian(startTime) < 7) {
|
||||
//相差一天以上 七天之内 显示星期几
|
||||
showtimeString = getWeek(startTime);
|
||||
} else {
|
||||
format = new SimpleDateFormat("MM-dd");
|
||||
showtimeString = format.format(new Date(startTime));
|
||||
}
|
||||
|
||||
}
|
||||
return showtimeString;
|
||||
}
|
||||
|
||||
public static String getLastM(int total, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM");
|
||||
Date date = new Date();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - (total - value));
|
||||
date = calendar.getTime();
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户生日计算年龄
|
||||
*/
|
||||
public static String getAgeByBirthday(Date birthday) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
||||
if (cal.before(birthday)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The birthDay is before Now.It's unbelievable!");
|
||||
}
|
||||
|
||||
int yearNow = cal.get(Calendar.YEAR);
|
||||
int monthNow = cal.get(Calendar.MONTH) + 1;
|
||||
int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
cal.setTime(birthday);
|
||||
int yearBirth = cal.get(Calendar.YEAR);
|
||||
int monthBirth = cal.get(Calendar.MONTH) + 1;
|
||||
int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
int age = yearNow - yearBirth;
|
||||
|
||||
if (monthNow <= monthBirth) {
|
||||
if (monthNow == monthBirth) {
|
||||
// monthNow==monthBirth
|
||||
if (dayOfMonthNow < dayOfMonthBirth) {
|
||||
age--;
|
||||
}
|
||||
} else {
|
||||
// monthNow>monthBirth
|
||||
age--;
|
||||
}
|
||||
}
|
||||
return age + "岁";
|
||||
}
|
||||
//获取当前年月日生成的唯一标识码
|
||||
public static String getTimeNumber(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||
return format.format(new Date(time));// 2012-10-03-23-41-31
|
||||
}
|
||||
//显示完整的年月日 时分秒
|
||||
public static String getTime(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
//显示完整的年月日 时分秒
|
||||
public static String getMinute(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("mm:ss");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
//显示完整的月日 时分
|
||||
public static String getComTime(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
//显示完整的年月日
|
||||
public static String getDateEN(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
//显示完整的年月日
|
||||
public static String getDateEND(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
//显示完整的年月日
|
||||
public static String getDateMon(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("MM月dd日");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
// 获取当前年份
|
||||
public static String getYear(Long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy");
|
||||
return format.format(new Date(time));
|
||||
}
|
||||
|
||||
public static long getDate(String timeStr) {
|
||||
long time = 0;
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
Date date = format.parse(timeStr);
|
||||
time = date.getTime();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return time / 1000;
|
||||
}
|
||||
|
||||
public static long getDateByString(String timeStr) {
|
||||
long time = 0;
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
Date date = format.parse(timeStr);
|
||||
time = date.getTime();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
public static String getTimeByString(String timeStr) {
|
||||
|
||||
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddhhmmss");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf1.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
return sdf2.format(date);
|
||||
}
|
||||
|
||||
public static String getTimeByStr(String timeStr) {
|
||||
|
||||
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddhhmmss");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf1.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return sdf2.format(date);
|
||||
}
|
||||
|
||||
|
||||
public static String setTimeByString(String timeStr) {
|
||||
|
||||
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf1.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddhhmmss");
|
||||
return sdf2.format(date);
|
||||
}
|
||||
|
||||
// 获取上午、下午时间
|
||||
public static String getHour(Long time) {
|
||||
String str;
|
||||
final Calendar mCalendar = Calendar.getInstance();
|
||||
mCalendar.setTimeInMillis(time);
|
||||
int apm = mCalendar.get(Calendar.AM_PM);
|
||||
SimpleDateFormat format = new SimpleDateFormat("hh:mm");
|
||||
String hour = format.format(time);
|
||||
|
||||
if (apm == 0) {
|
||||
str = "上午 " + hour;
|
||||
} else {
|
||||
str = "下午 " + hour;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static long newchajitian(Long lstartTime) {
|
||||
Calendar c1 = Calendar.getInstance();
|
||||
int year = c1.get(Calendar.YEAR);
|
||||
int yue = c1.get(Calendar.MONTH);
|
||||
int ri = c1.get(Calendar.DATE);
|
||||
c1.set(year, yue + 1, ri, 0, 0);
|
||||
Calendar c2 = Calendar.getInstance();
|
||||
int year_ = Integer.parseInt((getYear(lstartTime)));
|
||||
int yue_ = getYue(lstartTime);
|
||||
int ri_ = getDay(lstartTime);
|
||||
c2.set(year_, yue_, ri_, 0, 0);
|
||||
return getAbsDayDiff(c2, c1);
|
||||
}
|
||||
|
||||
public static int getDay(long time) {
|
||||
SimpleDateFormat format1 = new SimpleDateFormat("dd");
|
||||
String date1 = format1.format(new Date(time));
|
||||
return Integer.parseInt(date1);// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
public static int getYue(long time) {
|
||||
SimpleDateFormat format1 = new SimpleDateFormat("MM");
|
||||
String date1 = format1.format(new Date(time));
|
||||
return Integer.parseInt(date1);// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
public static int getAbsDayDiff(Calendar calStart, Calendar calEnd) {
|
||||
Calendar start = (Calendar) calStart.clone();
|
||||
Calendar end = (Calendar) calEnd.clone();
|
||||
|
||||
start.set(start.get(Calendar.YEAR), start.get(Calendar.MONTH),
|
||||
start.get(Calendar.DATE), 0, 0, 0);
|
||||
start.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
end.set(end.get(Calendar.YEAR), end.get(Calendar.MONTH),
|
||||
end.get(Calendar.DATE), 0, 0, 0);
|
||||
end.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
return (int) ((end.getTimeInMillis() - start.getTimeInMillis()) / DAY_MILLSECONDS);
|
||||
}
|
||||
|
||||
//获取星期几
|
||||
public static String getWeek(long timeStamp) {
|
||||
int myDate;
|
||||
String week = null;
|
||||
Calendar cd = Calendar.getInstance();
|
||||
cd.setTime(new Date(timeStamp));
|
||||
myDate = cd.get(Calendar.DAY_OF_WEEK);
|
||||
// 获取指定日期转换成星期几
|
||||
if (myDate == 1) {
|
||||
week = "星期日";
|
||||
} else if (myDate == 2) {
|
||||
week = "星期一";
|
||||
} else if (myDate == 3) {
|
||||
week = "星期二";
|
||||
} else if (myDate == 4) {
|
||||
week = "星期三";
|
||||
} else if (myDate == 5) {
|
||||
week = "星期四";
|
||||
} else if (myDate == 6) {
|
||||
week = "星期五";
|
||||
} else if (myDate == 7) {
|
||||
week = "星期六";
|
||||
}
|
||||
return week;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间转化为显示字符串
|
||||
*
|
||||
* @param timeStamp 单位为秒
|
||||
*/
|
||||
public static String getTimeStr(long timeStamp) {
|
||||
if (timeStamp == 0) return "";
|
||||
Calendar inputTime = Calendar.getInstance();
|
||||
inputTime.setTimeInMillis(timeStamp * 1000);
|
||||
Date currenTimeZone = inputTime.getTime();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (calendar.before(inputTime)) {
|
||||
//当前时间在输入时间之前
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
if (calendar.before(inputTime)) {
|
||||
return "昨天";
|
||||
} else {
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar.set(Calendar.MONTH, Calendar.JANUARY);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
|
||||
return sdf.format(currenTimeZone);
|
||||
} else {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间转化为聊天界面显示字符串
|
||||
*
|
||||
* @param timeStamp 单位为秒
|
||||
*/
|
||||
public static String getChatTimeStr(long timeStamp) {
|
||||
if (timeStamp == 0) return "";
|
||||
Calendar inputTime = Calendar.getInstance();
|
||||
inputTime.setTimeInMillis(timeStamp * 1000);
|
||||
Date currenTimeZone = inputTime.getTime();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (calendar.before(inputTime)) {
|
||||
//当前时间在输入时间之前
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||
return "昨天 " + sdf.format(currenTimeZone);
|
||||
} else {
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar.set(Calendar.MONTH, Calendar.JANUARY);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("M月d日" + " HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
} else {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日" + " HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getYear() {
|
||||
return Calendar.getInstance().get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public static int getMonth() {
|
||||
return Calendar.getInstance().get(Calendar.MONTH) + 1;
|
||||
}
|
||||
|
||||
public static int getCurrentMonthDay() {
|
||||
return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串转为时间戳
|
||||
*/
|
||||
public static long getStringToDate(String time) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
|
||||
Date date = new Date();
|
||||
try {
|
||||
date = simpleDateFormat.parse(time);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return date.getTime();
|
||||
}
|
||||
|
||||
//获得当前日期与本周一相差的天数
|
||||
public static int getMondayPlus() {
|
||||
Calendar cd = Calendar.getInstance();
|
||||
// 获得今天是一周的第几天,星期日是第一天,星期二是第二天......
|
||||
int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
|
||||
if (dayOfWeek == 1) {
|
||||
return -6;
|
||||
} else {
|
||||
return 2 - dayOfWeek;
|
||||
}
|
||||
}
|
||||
|
||||
//获得本周星期一的日期
|
||||
public static Calendar getCurrentMonday() {
|
||||
int mondayPlus = getMondayPlus();
|
||||
GregorianCalendar currentDate = new GregorianCalendar();
|
||||
currentDate.add(GregorianCalendar.DATE, mondayPlus);
|
||||
Date monday = currentDate.getTime();
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(monday);
|
||||
return c;
|
||||
}
|
||||
|
||||
// 上/下 一月
|
||||
public static String getLastOrNextMonth(String timeStr, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月");
|
||||
Date date = new Date();
|
||||
if (!timeStr.equals("本月")) {
|
||||
try {
|
||||
date = dateFormat.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - value);
|
||||
date = calendar.getTime();
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
// 上/下 一周
|
||||
public static String getLastOrNextWeek(String timeStr, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年");
|
||||
Date date = new Date();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (!timeStr.equals("本周")) {
|
||||
try {
|
||||
date = dateFormat.parse(timeStr.substring(0, timeStr.indexOf("年") + 1));
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.WEEK_OF_YEAR, Integer.parseInt(timeStr
|
||||
.substring(timeStr.indexOf("年") + 1, timeStr.indexOf("周"))) - value);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) - value);
|
||||
}
|
||||
date = calendar.getTime();
|
||||
if (calendar.get(Calendar.WEEK_OF_YEAR) > 9) {
|
||||
return dateFormat.format(date) + calendar.get(Calendar.WEEK_OF_YEAR) + "周";
|
||||
} else {
|
||||
return dateFormat.format(date) + "0" + calendar.get(Calendar.WEEK_OF_YEAR) + "周";
|
||||
}
|
||||
}
|
||||
|
||||
// 上/下 一日
|
||||
public static String getLastOrNextDay(String timeStr, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = new Date();
|
||||
if (!timeStr.equals("今日")) {
|
||||
try {
|
||||
date = dateFormat.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - value);
|
||||
date = calendar.getTime();
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
// 是否是今日
|
||||
public static Boolean isToday(String timeStr) {
|
||||
return getDateEN(System.currentTimeMillis()).equals(timeStr);
|
||||
}
|
||||
//
|
||||
// // 是否是本周
|
||||
// public static Boolean isTswk(String timeStr) {
|
||||
//
|
||||
// Calendar calendar = Calendar.getInstance();
|
||||
// int year = Integer.parseInt(timeStr.substring(0, timeStr.indexOf("年")));
|
||||
// int week = Integer.parseInt(timeStr
|
||||
// .substring(timeStr.indexOf("年") + 1, timeStr.indexOf("周")));
|
||||
//
|
||||
// return calendar.get(Calendar.YEAR) == year && calendar.get(Calendar.WEEK_OF_YEAR) == week;
|
||||
// }
|
||||
|
||||
// 是否是本月
|
||||
public static Boolean isTsM(String timeStr) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月");
|
||||
String nowTime = dateFormat.format(new Date(System.currentTimeMillis()));
|
||||
|
||||
return timeStr.equals(nowTime);
|
||||
}
|
||||
|
||||
|
||||
public static String getDisparity(String timeStamp) {
|
||||
Long target = getDateByString(timeStamp);
|
||||
Long now = System.currentTimeMillis();
|
||||
if (target < now) {
|
||||
return "已截止";
|
||||
}
|
||||
Long l = target - now;
|
||||
long Minute = (l / (1000 * 60));
|
||||
long day = (l / (1000 * 60 * 60 * 24));
|
||||
long min = Minute - (day * 60 * 24);
|
||||
long hour = min / 60;
|
||||
long minute = min - (hour * 60);
|
||||
return day + "天" + hour + ":" + minute + "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.Key;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
public final class UtilEncrypt {
|
||||
|
||||
/**
|
||||
* 默认密钥,实际项目中可配置注入或数据库读取
|
||||
*/
|
||||
private final static String DEFAULT_KEY = "asla01slajf1ALlsdaf0987654321";
|
||||
|
||||
/**
|
||||
* 对字符串进行默认加密
|
||||
*/
|
||||
public static String encrypt(String str) {
|
||||
return encrypt(str, DEFAULT_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串加密
|
||||
*/
|
||||
public static String decrypt(String str) {
|
||||
return decrypt(str, DEFAULT_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串加密
|
||||
*/
|
||||
public static String encrypt(String plainText, String key) {
|
||||
|
||||
byte[] bytes = null;
|
||||
try {
|
||||
bytes = plainText.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
byte[] encryptedBytes = getCipher(Cipher.ENCRYPT_MODE, key).doFinal(bytes);
|
||||
return UtilHex.bytes2HexString(encryptedBytes);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串解密
|
||||
*/
|
||||
public static String decrypt(String encryptedText, String key) {
|
||||
byte[] arr = UtilHex.hexString2Bytes(encryptedText);
|
||||
try {
|
||||
byte[] decryptedBytes = getCipher(Cipher.DECRYPT_MODE, key).doFinal(arr);
|
||||
return new String(decryptedBytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Cipher getCipher(int mode, String key) {
|
||||
// Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
// Security.addProvider(new Provider.SunJCE());
|
||||
if (key == null) {
|
||||
key = DEFAULT_KEY;
|
||||
}
|
||||
byte[] arrBTmp = null;
|
||||
try {
|
||||
arrBTmp = key.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
// 创建一个空的length位字节数组(默认值为0)
|
||||
byte[] arrB = new byte[16];
|
||||
|
||||
// 将原始字节数组转换为8位
|
||||
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
|
||||
arrB[i] = arrBTmp[i];
|
||||
}
|
||||
// 生成密钥
|
||||
Key theKey = new javax.crypto.spec.SecretKeySpec(arrB, "AES");
|
||||
|
||||
// 生成Cipher对象,指定其支持的DES算法
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
cipher.init(mode, theKey);
|
||||
return cipher;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
//业务:business.akrdinfo.cn
|
||||
//心跳:heartbeat.akrdinfo.cn
|
||||
// String value = encrypt("heartbeat.akrdinfo.cn");
|
||||
String value = encrypt("rdnss.cloud");
|
||||
System.out.println(value);
|
||||
// System.out.println(decrypt("7ae044016890d6862e2e343f9b735db1464f0b63c251cce2e9855af9c3c7f6be"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
/**
|
||||
* 16进制转换工具
|
||||
*
|
||||
* @author wulh create on 2018/5/20.
|
||||
*/
|
||||
public final class UtilHex {
|
||||
|
||||
/**
|
||||
* 16进制字符串转为字节数组
|
||||
* @param hexStr 长度必须为偶数,每个字节用两个字符表达
|
||||
* @return 对应字节数组
|
||||
*/
|
||||
public static byte[] hexString2Bytes(String hexStr) {
|
||||
if(hexStr == null || hexStr.length() == 0 || hexStr.length() % 2 > 0) {
|
||||
throw new IllegalArgumentException("参数长度必须为偶数");
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[hexStr.length() / 2];
|
||||
for(int i = 0, len = bytes.length; i < len; i++) {
|
||||
bytes[i] = (byte) (0xFF & Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 16进制字符串转为字节数组
|
||||
* @param hexStr 长度必须为偶数,每个字节用两个字符表达
|
||||
* @return 对应字节数组
|
||||
*/
|
||||
public static String bytes2HexString(byte[] bytes) {
|
||||
if(bytes == null || bytes.length == 0) {
|
||||
throw new IllegalArgumentException("参数必须非空");
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(byte b : bytes) {
|
||||
String s = Integer.toHexString(0xFF & b);
|
||||
if(s.length() == 1) {
|
||||
s = "0" + s;
|
||||
}
|
||||
sb.append(s);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.android.database;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractDaoMannager<T> {
|
||||
abstract void insert(Class<T> tClass, T t);
|
||||
abstract Long inserteq(Class<T> tClass, T t);
|
||||
|
||||
abstract void insert(Class<T> tClass, List<T> list);
|
||||
abstract void insertnew(Class<T> tClass, List<T> list);
|
||||
|
||||
abstract void update(Class<T> tClass, T t);
|
||||
|
||||
abstract void update(Class<T> tClass, List<T> list);
|
||||
|
||||
abstract T query(Class<T> tClass, T key);
|
||||
|
||||
abstract List<T> queryList(Class<T> tClass);
|
||||
|
||||
abstract List<T> queryListIn(Class<T> tClass, String key, Object[] value);
|
||||
|
||||
abstract List<T> queryByKeyList(Class<T> tClass, String key, String value);
|
||||
|
||||
abstract List<T> queryByKeyListDesc(Class<T> tClass, String key, String value,String descStr);
|
||||
|
||||
abstract List<T> queryByKeyListAsc(Class<T> tClass, String key, String value,String ascStr);
|
||||
|
||||
abstract List<T> queryByValueList(Class<T> tClass, String[] key, String[] value);
|
||||
|
||||
abstract List<T> queryByValueListDesc(Class<T> tClass, String[] key, String[] value,String descStr);
|
||||
|
||||
abstract List<T> queryByValueListAsc(Class<T> tClass, String[] key, String[] value,String ascStr);
|
||||
|
||||
abstract List<T> queryByDateLt(Class<T> tClass, String key, long date);
|
||||
|
||||
|
||||
abstract void delete(Class<T> tClass, T t);
|
||||
|
||||
abstract void deleteAll(Class<T> tClass);
|
||||
|
||||
|
||||
abstract void deleteByKey(Class<T> tClass, Long keyValue);
|
||||
|
||||
abstract void deleteByList(Class<T> tClass, List<T> values);
|
||||
|
||||
}
|
||||
294
nebula-sdk/src/main/java/com/android/database/DaoManager.java
Normal file
294
nebula-sdk/src/main/java/com/android/database/DaoManager.java
Normal file
@@ -0,0 +1,294 @@
|
||||
package com.android.database;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import org.greenrobot.greendao.AbstractDao;
|
||||
import org.greenrobot.greendao.Property;
|
||||
import org.greenrobot.greendao.query.QueryBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DaoManager<T> extends AbstractDaoMannager<T> {
|
||||
private static DaoManager mInstance;
|
||||
private static DaoMaster mDaoMaster;
|
||||
|
||||
public static void initeDao(Context mContext) {
|
||||
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(mContext, "sofa-db", null);
|
||||
mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
|
||||
}
|
||||
|
||||
private DaoManager() {
|
||||
|
||||
}
|
||||
|
||||
public DaoMaster getMaster() {
|
||||
return mDaoMaster;
|
||||
}
|
||||
|
||||
|
||||
public static DaoManager getInstance() {
|
||||
if (mInstance == null) {
|
||||
mInstance = new DaoManager();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
private AbstractDao<T, T> getDao(Class<T> tClass) {
|
||||
try {
|
||||
return (AbstractDao<T, T>) mDaoMaster.newSession().getDao(tClass);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
// dao.delete(t);
|
||||
long id= dao.insertOrReplace(t);
|
||||
LogUtils.e( "postServerAppUpdate--->====insertOrReplace===>"+id);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Long inserteq(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
// dao.delete(t);
|
||||
long id= dao.insertOrReplace(t);
|
||||
LogUtils.e("postServerAppUpdate--->insertOrReplace===>"+id);
|
||||
return id;
|
||||
}
|
||||
|
||||
return -1L;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void insert(Class<T> tClass, List<T> list) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
dao.deleteAll();
|
||||
dao.insertOrReplaceInTx(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertnew(Class<T> tClass, List<T> list) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
dao.insertOrReplaceInTx(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
dao.update(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Class<T> tClass, List<T> list) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
dao.updateInTx(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T query(Class<T> tClass, T key) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
return dao.load(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryList(Class<T> tClass) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
return dao.loadAll();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryListIn(Class<T> tClass, String key,Object[] value) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.in(value)).build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByKeyList(Class<T> tClass, String key, String value) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.eq(value)).build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByKeyListDesc(Class<T> tClass, String key, String value, String descStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.eq(value)).orderRaw(descStr+" DESC").build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByKeyListAsc(Class<T> tClass, String key, String value, String ascStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.eq(value)).orderRaw(ascStr+" ASC").build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByValueList(Class<T> tClass, String[] key, String[] value) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
QueryBuilder queryBuilder =dao.queryBuilder();
|
||||
|
||||
for (Property property : properties) {
|
||||
for (int i=0;i<key.length; i++){
|
||||
if (property.name.equals(key[i])) {
|
||||
queryBuilder.where(property.eq(value[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return queryBuilder.build().list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByValueListDesc(Class<T> tClass, String[] key, String[] value, String descStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
QueryBuilder queryBuilder =dao.queryBuilder();
|
||||
|
||||
for (Property property : properties) {
|
||||
for (int i=0;i<key.length; i++){
|
||||
if (property.name.equals(key[i])) {
|
||||
queryBuilder.where(property.eq(value[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return queryBuilder.orderRaw(descStr+" DESC").build().list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByValueListAsc(Class<T> tClass, String[] key, String[] value, String ascStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
QueryBuilder queryBuilder =dao.queryBuilder();
|
||||
|
||||
for (Property property : properties) {
|
||||
for (int i=0;i<key.length; i++){
|
||||
if (property.name.equals(key[i])) {
|
||||
queryBuilder.where(property.eq(value[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return queryBuilder.orderRaw(ascStr+" ASC").build().list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByDateLt(Class<T> tClass, String key, long date) {
|
||||
|
||||
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.lt(date)).build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return;
|
||||
dao.delete(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(Class<T> tClass) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return;
|
||||
dao.deleteAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByKey(Class<T> tClass, Long keyValue) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return;
|
||||
dao.deleteByKey((T) keyValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByList(Class<T> tClass, List<T> values) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return ;
|
||||
dao.deleteInTx(values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.android.database.lib;
|
||||
|
||||
import org.greenrobot.greendao.annotation.Entity;
|
||||
import org.greenrobot.greendao.annotation.Generated;
|
||||
|
||||
@Entity
|
||||
public class DomainEntry {
|
||||
public String domains;
|
||||
public String type;
|
||||
|
||||
|
||||
@Generated(hash = 820333504)
|
||||
public DomainEntry(String domains, String type) {
|
||||
this.domains = domains;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Generated(hash = 2071904502)
|
||||
public DomainEntry() {
|
||||
}
|
||||
|
||||
|
||||
public String getDomains() {
|
||||
return domains;
|
||||
}
|
||||
|
||||
public void setDomains(String domains) {
|
||||
this.domains = domains;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package com.android.database.lib;
|
||||
|
||||
|
||||
import org.greenrobot.greendao.annotation.Entity;
|
||||
import org.greenrobot.greendao.annotation.Generated;
|
||||
import org.greenrobot.greendao.annotation.Id;
|
||||
import org.greenrobot.greendao.annotation.Transient;
|
||||
|
||||
@Entity
|
||||
public class DownLoadTaskBean {
|
||||
private String url;
|
||||
private long start;
|
||||
private long end;
|
||||
private long total;
|
||||
/**文件类型*/
|
||||
protected String minType;
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
private int taskType;
|
||||
|
||||
|
||||
/**taskid*/
|
||||
@Id(autoincrement = true)
|
||||
private Long taskId;
|
||||
private String fileName;
|
||||
private String path;
|
||||
private long currentProgress;
|
||||
private int status = 0;//-1、未下载;0、下载中;1、下载完成
|
||||
|
||||
//@Transient:表明这个字段不会被写入数据库,只是作为一个普通的java类字段,用来临时存储数据的,不会被持久化
|
||||
@Transient
|
||||
private DownLoad2Listener listener;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Generated(hash = 517545372)
|
||||
public DownLoadTaskBean(String url, long start, long end, long total,
|
||||
String minType, int taskType, Long taskId, String fileName, String path,
|
||||
long currentProgress, int status) {
|
||||
this.url = url;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.total = total;
|
||||
this.minType = minType;
|
||||
this.taskType = taskType;
|
||||
this.taskId = taskId;
|
||||
this.fileName = fileName;
|
||||
this.path = path;
|
||||
this.currentProgress = currentProgress;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
|
||||
public String getMinType() {
|
||||
return minType;
|
||||
}
|
||||
|
||||
public void setMinType(String minType) {
|
||||
this.minType = minType;
|
||||
}
|
||||
|
||||
@Generated(hash = 949446503)
|
||||
public DownLoadTaskBean() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public int getTaskType() {
|
||||
return taskType;
|
||||
}
|
||||
|
||||
public void setTaskType(int taskType) {
|
||||
this.taskType = taskType;
|
||||
}
|
||||
|
||||
|
||||
public String getUrl() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getStart() {
|
||||
return this.start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setStart(long start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getEnd() {
|
||||
return this.end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setEnd(long end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getTotal() {
|
||||
return this.total;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public Long getTaskId() {
|
||||
return this.taskId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setTaskId(Long taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public String getFileName() {
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getCurrentProgress() {
|
||||
return this.currentProgress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setCurrentProgress(long currentProgress) {
|
||||
this.currentProgress = currentProgress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public int getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public DownLoad2Listener getListener() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
public void setListener(DownLoad2Listener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
||||
public interface DownLoad2Listener {
|
||||
void onStart(long totalSize);
|
||||
|
||||
void onError(String error);
|
||||
|
||||
void onProgress(String fileName,long taskId,long progress);
|
||||
|
||||
void onFinish(String minType,String dowanloadUrl,String filePath, int taskType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.android.download;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Global executor pools for the whole application.
|
||||
* <p>
|
||||
* Grouping tasks like this avoids the effects of task starvation (e.g. disk reads don't wait behind
|
||||
* webservice requests).
|
||||
*/
|
||||
public class AppExecutors {
|
||||
private static AppExecutors appExecutors;
|
||||
private final Executor diskIO;
|
||||
|
||||
private final Executor networkIO;
|
||||
|
||||
private final Executor mainThread;
|
||||
|
||||
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
|
||||
this.diskIO = diskIO;
|
||||
this.networkIO = networkIO;
|
||||
this.mainThread = mainThread;
|
||||
}
|
||||
|
||||
private AppExecutors() {
|
||||
this(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3),
|
||||
new MainThreadExecutor());
|
||||
}
|
||||
|
||||
public static AppExecutors getAppExecutors() {
|
||||
if (appExecutors == null)
|
||||
return new AppExecutors();
|
||||
else
|
||||
return appExecutors;
|
||||
}
|
||||
|
||||
public Executor diskIO() {
|
||||
return diskIO;
|
||||
}
|
||||
|
||||
public Executor networkIO() {
|
||||
return networkIO;
|
||||
}
|
||||
|
||||
public Executor mainThread() {
|
||||
return mainThread;
|
||||
}
|
||||
|
||||
private static class MainThreadExecutor implements Executor {
|
||||
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
mainThreadHandler.post(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
package com.android.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.database.DaoManager;
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.android.util.GsonUtil;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class DownLoadManeger {
|
||||
|
||||
private static DownLoadManeger instance;
|
||||
private boolean isAuto = false;
|
||||
|
||||
private DownloadListener mDownloadListener;
|
||||
|
||||
/**
|
||||
* 网络异常码
|
||||
*/
|
||||
protected static final int ERROR_CODE_NETWORK = -1;
|
||||
/**
|
||||
* 读写异常码
|
||||
*/
|
||||
protected static final int ERROR_CODE_WRITE = -2;
|
||||
/**
|
||||
* 存储空间不够异常码
|
||||
*/
|
||||
protected static final int ERROR_CODE_STORAGE_ENOUGH = -3;
|
||||
/**
|
||||
* URL格式异常
|
||||
*/
|
||||
protected static final int ERROR_CODE_MALFORMEDURL = -4;
|
||||
|
||||
|
||||
public void registerDownloadListener(DownloadListener downloadListener) {
|
||||
this.mDownloadListener = downloadListener;
|
||||
}
|
||||
|
||||
public void unRegisterDownloadListener(DownloadListener downloadListener) {
|
||||
this.mDownloadListener = null;
|
||||
}
|
||||
|
||||
private DownLoadManeger(Context context) {
|
||||
DaoManager.initeDao(context);
|
||||
}
|
||||
|
||||
public static DownLoadManeger init(Context context) {
|
||||
if (instance == null)
|
||||
instance = new DownLoadManeger(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static DownLoadManeger getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加新的下载任务
|
||||
*/
|
||||
public void addDownloadTask(DownloadBuilder builder) {
|
||||
if (TextUtils.isEmpty(builder.url)) {
|
||||
return;
|
||||
}
|
||||
DownLoadTaskBean downLoadTaskBean = null;
|
||||
if (!isExistTask(builder.url)) {
|
||||
downLoadTaskBean = createTaskBean(builder);
|
||||
LogUtils.e("postServerAppUpdate--->新下载任务");
|
||||
} else {
|
||||
File file = new File(builder.path, builder.name + ".tmp");
|
||||
if (file.exists()) {
|
||||
if (file.length() == builder.total) {
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在并下载完成");
|
||||
return;
|
||||
} else {
|
||||
downLoadTaskBean = createTaskBean(builder);
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在但未完成,当前进度:" + file.length() + "--->" + builder.total);
|
||||
}
|
||||
} else {
|
||||
downLoadTaskBean = createTaskBean(builder);
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在并下载完成");
|
||||
}
|
||||
}
|
||||
//添加下载任务队列
|
||||
if (!TaskQueue.getInstance().isExistTask(downLoadTaskBean)) {
|
||||
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中
|
||||
} else {
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在:" + GsonUtil.GsonString(downLoadTaskBean));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载没有完成的任务管理
|
||||
*/
|
||||
public void restDownloadTask() {
|
||||
List<DownLoadTaskBean> list = DaoManager.getInstance().queryList(DownLoadTaskBean.class); //未完成下载的任务
|
||||
|
||||
LogUtils.e("postServerAppUpdate--->restDownloadTask DownloadTask:" + GsonUtil.GsonString(list));
|
||||
if (list.size() > 0) {
|
||||
LogUtils.e("postServerAppUpdate--->start download");
|
||||
for (DownLoadTaskBean downLoadTaskBean : list) {
|
||||
//添加下载任务队列
|
||||
if (!TaskQueue.getInstance().isExistTask(downLoadTaskBean)) {
|
||||
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("postServerAppUpdate--->no download task");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除任务队列
|
||||
*/
|
||||
public void clear() {
|
||||
TaskQueue.getInstance().clear();
|
||||
}
|
||||
|
||||
public boolean isExistTask(String url) {//判断是否存在下载任务
|
||||
List<DownLoadTaskBean> downLoadTaskBeans = DaoManager.getInstance().queryByKeyList(DownLoadTaskBean.class, "url", url);
|
||||
if (downLoadTaskBeans != null && downLoadTaskBeans.size() == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private DownLoadTaskBean createTaskBean(DownloadBuilder builder) {//创建下载任务bean和创建下载任务
|
||||
DownLoadTaskBean bean = new DownLoadTaskBean();
|
||||
bean.setFileName(builder.name);
|
||||
bean.setPath(builder.path);
|
||||
bean.setUrl(builder.url);
|
||||
bean.setTaskId(System.currentTimeMillis());
|
||||
bean.setListener(builder.listener);
|
||||
bean.setTotal(builder.total);
|
||||
bean.setMinType(builder.minType);
|
||||
bean.setTaskType(builder.taskType);
|
||||
DownLoadTaskThread task = new DownLoadTaskThread(bean, observer);
|
||||
DaoManager.getInstance().insert(DownLoadTaskBean.class, bean);//保存到数据库
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
//自动下载
|
||||
public void setAutoDownLoad(boolean isAuto) {
|
||||
this.isAuto = isAuto;
|
||||
}
|
||||
|
||||
public void pauseAll() {//全部暂停
|
||||
TaskQueue.getInstance().pause();
|
||||
}
|
||||
|
||||
|
||||
public static class DownloadBuilder {//构造器
|
||||
protected String url;//下载地址
|
||||
protected String path;//下载路径
|
||||
protected String name;//文件名字
|
||||
protected long total;//现在总进度
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
protected String minType;
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
protected int taskType;
|
||||
protected DownLoadTaskBean.DownLoad2Listener listener;//下载监听
|
||||
|
||||
|
||||
public DownloadBuilder setMinType(String minType) {
|
||||
this.minType = minType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder url(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder filePath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder listener(DownLoadTaskBean.DownLoad2Listener listener) {
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder fileName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder taskType(int taskType) {
|
||||
this.taskType = taskType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder fileTotal(long fileSize) {
|
||||
this.total = fileSize;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface DownloadListener {
|
||||
public void onStart(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
public void onError(DownLoadTaskBean bean, long taskId, String erroMsg);
|
||||
|
||||
public void onProgress(DownLoadTaskBean bean, long taskId, long progress, long total);
|
||||
|
||||
public void onFinish(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//下载线程的观察者
|
||||
private DownLoadTaskThread.DownloadTaskObserver observer = new DownLoadTaskThread.DownloadTaskObserver() {
|
||||
@Override
|
||||
protected void onStart(DownLoadTaskBean bean, long taskId) {//下载开始,回调总进度给监听,方便设置进度大小
|
||||
LogUtils.e("postServerAppUpdate--->taskId=" + taskId + ">>>>>" + bean.getTotal());
|
||||
bean.setStatus(0);
|
||||
AppExecutors.getAppExecutors().mainThread().execute(() -> {//切换到主线程
|
||||
if (bean.getListener() != null) {
|
||||
bean.getListener().onStart(bean.getTotal());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgress(DownLoadTaskBean bean, long taskId, long progress, long total) {//进度调用
|
||||
synchronized (this) {//这里必须加同步代码块,因为这共用进度等变量
|
||||
|
||||
if (mDownloadListener != null) {
|
||||
mDownloadListener.onProgress(bean, taskId, progress, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish(DownLoadTaskBean bean, long taskId, long lastProgress) {
|
||||
synchronized (this) {
|
||||
TaskQueue.getInstance().remove(bean);//单个任务完成删除
|
||||
// DaoManager.getInstance().delete(DownLoadTaskBean.class, bean);
|
||||
if (mDownloadListener != null) {
|
||||
mDownloadListener.onFinish(bean, taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause(DownLoadTaskBean bean, long taskId, long currentProgress) {
|
||||
synchronized (this) {//暂停这里必须加上同步,不然会出现实际进度跟显示进度不一致问题,其实也就是缓存没存进去,第二个线程又来了
|
||||
// DaoManager.getInstance().update(DownLoadTaskBean.class, bean);//更新数据库,退出app再进来就不会从头下载
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onError(DownLoadTaskBean bean, long taskId, String erroMsg, int errorCode) {//错误提示
|
||||
TaskQueue.getInstance().remove(bean);
|
||||
switch (errorCode) {
|
||||
case ERROR_CODE_NETWORK:
|
||||
break;
|
||||
case ERROR_CODE_WRITE:
|
||||
case ERROR_CODE_MALFORMEDURL:
|
||||
case ERROR_CODE_STORAGE_ENOUGH:
|
||||
DaoManager.getInstance().delete(DownLoadTaskBean.class, bean);//删除数据库缓存
|
||||
File file = new File(bean.getPath(), bean.getFileName() + "-tmp"); //下载异常时删除临时文件
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LogUtils.e("postServerAppUpdate--->errmsg:" + erroMsg);
|
||||
if (mDownloadListener != null) {
|
||||
mDownloadListener.onError(bean, taskId, erroMsg);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package com.android.download;
|
||||
|
||||
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
|
||||
public class DownLoadTaskThread implements Runnable {
|
||||
private boolean pause;
|
||||
private DownLoadTaskBean bean;
|
||||
private long currentTotal = 0L;
|
||||
private DownloadTaskObserver observer;
|
||||
|
||||
public DownLoadTaskThread(DownLoadTaskBean bean, DownloadTaskObserver observer) {
|
||||
this.bean = bean;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
HttpURLConnection urlConnection = null;
|
||||
RandomAccessFile randomFile = null;
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
URL url = new URL(bean.getUrl());
|
||||
urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setConnectTimeout(20000); //设置连接超时事件为20秒
|
||||
urlConnection.setRequestMethod("GET"); //设置请求方式为GET
|
||||
//设置用户端可以接收的媒体类型
|
||||
urlConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, " +
|
||||
"image/pjpeg, application/x-shockwave-flash, application/xaml+xml, " +
|
||||
"application/vnd.ms-xpsdocument, application/x-ms-xbap," +
|
||||
" application/x-ms-application, application/vnd.ms-excel," +
|
||||
" application/vnd.ms-powerpoint, application/msword, */*");
|
||||
|
||||
urlConnection.setRequestProperty("Accept-Language", "zh-CN"); //设置用户语言
|
||||
urlConnection.setRequestProperty("Charset", "UTF-8"); //设置客户端编码
|
||||
// //设置用户代理
|
||||
urlConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; " +
|
||||
"Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727;" +
|
||||
" .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
|
||||
|
||||
File dataFile = new File(bean.getPath(), bean.getFileName());
|
||||
if (dataFile.exists() && dataFile.length() == bean.getTotal()) { //判断该文件已下载无需再下载
|
||||
observer.onFinish(bean, bean.getTaskId(), dataFile.length());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//设置文件写入位置
|
||||
File file = new File(bean.getPath(), bean.getFileName() + ".tmp");
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
currentTotal = file.length();
|
||||
LogUtils.e("postServerAppUpdate--->downloadFile:" + bean.getPath() + "---->" + bean.getFileName() + "|" + bean.getStart()
|
||||
+ "start------" + currentTotal + ">>>>" + bean.getTotal());
|
||||
if (currentTotal == bean.getTotal()) {
|
||||
LogUtils.e("postServerAppUpdate--->下载完成");
|
||||
File targFile = new File(bean.getPath(), bean.getFileName());
|
||||
file.renameTo(targFile);//重命名
|
||||
file.delete();//删除临时文件
|
||||
observer.onFinish(bean, bean.getTaskId(), currentTotal);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentTotal > bean.getTotal()) {
|
||||
observer.onError(bean, bean.getTaskId(), "文件超出下载长度,下载异常", DownLoadManeger.ERROR_CODE_WRITE);
|
||||
return;
|
||||
}
|
||||
|
||||
long beginIndex = 0L;
|
||||
if (currentTotal == 0L) {
|
||||
beginIndex = 0L;
|
||||
} else {
|
||||
beginIndex = currentTotal - 1;
|
||||
}
|
||||
//设置下载位置
|
||||
urlConnection.setRequestProperty("Range", "bytes=" + beginIndex + "-" + (bean.getTotal() - 1));
|
||||
|
||||
randomFile = new RandomAccessFile(file, "rwd");
|
||||
LogUtils.e("postServerAppUpdate--->download onProgress:seek currentTotal--->" + beginIndex);
|
||||
randomFile.seek(beginIndex);
|
||||
|
||||
urlConnection.connect();
|
||||
if (observer != null) {
|
||||
observer.onStart(bean, bean.getTaskId());
|
||||
}
|
||||
|
||||
//获得文件流
|
||||
inputStream = urlConnection.getInputStream();
|
||||
byte[] buffer = new byte[1024 * 10];
|
||||
int len;
|
||||
long time = System.currentTimeMillis();
|
||||
while ((currentTotal != bean.getTotal()) && (len = inputStream.read(buffer)) != -1) {
|
||||
//写入文件
|
||||
randomFile.write(buffer, 0, len);
|
||||
currentTotal += len;
|
||||
//时间间隔大于500ms再发
|
||||
if (System.currentTimeMillis() - time > 5000) {
|
||||
time = System.currentTimeMillis();
|
||||
observer.onProgress(bean, bean.getTaskId(), currentTotal, bean.getTotal());
|
||||
}
|
||||
//判断是否是暂停状态.保存断点
|
||||
if (observer != null && pause) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
urlConnection.disconnect();
|
||||
urlConnection = null;
|
||||
randomFile.close();
|
||||
randomFile = null;
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
|
||||
observer.onProgress(bean, bean.getTaskId(), currentTotal, bean.getTotal());
|
||||
|
||||
if (observer != null && !pause) {
|
||||
if (currentTotal >= bean.getTotal()) {
|
||||
LogUtils.e("postServerAppUpdate--->下载完成");
|
||||
File targFile = new File(bean.getPath(), bean.getFileName());
|
||||
file.renameTo(targFile);//重命名
|
||||
file.delete();//删除临时文件
|
||||
observer.onFinish(bean, bean.getTaskId(), currentTotal);
|
||||
} else {
|
||||
LogUtils.e("postServerAppUpdate--->" + currentTotal + "|" + bean.getTotal() + "下载失败" + bean.getFileName());
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "下载失败,文件大小不一致", DownLoadManeger.ERROR_CODE_WRITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// LogUtils.loge("download Exception===>"+e.getMessage());
|
||||
// if (observer != null) {
|
||||
//// observer.onError(bean, bean.getTaskId(), e.getMessage());
|
||||
// }
|
||||
// }
|
||||
catch (FileNotFoundException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "文件无法创建或写入:" + e.getMessage(), DownLoadManeger.ERROR_CODE_WRITE);
|
||||
}
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "URL格式错误:" + e.getMessage(), DownLoadManeger.ERROR_CODE_MALFORMEDURL);
|
||||
}
|
||||
|
||||
} catch (SocketTimeoutException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "连接或读取超时:" + e.getMessage(), DownLoadManeger.ERROR_CODE_NETWORK);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "下载时IO 读写异常:" + e.getMessage(), DownLoadManeger.ERROR_CODE_NETWORK);//判定为网络异常,以便下次开机可以启动断点续传功能
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (urlConnection != null) {
|
||||
urlConnection.disconnect();
|
||||
urlConnection = null;
|
||||
}
|
||||
try {
|
||||
if (randomFile != null) {
|
||||
randomFile.close();
|
||||
randomFile = null;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DownLoadTaskBean getBean() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setBean(DownLoadTaskBean bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public void setPause(boolean pause) {
|
||||
this.pause = pause;
|
||||
}
|
||||
|
||||
|
||||
protected static abstract class DownloadTaskObserver {
|
||||
|
||||
protected abstract void onStart(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
protected abstract void onProgress(DownLoadTaskBean bean, long taskId, long progress, long total);
|
||||
|
||||
protected abstract void onFinish(DownLoadTaskBean bean, long taskId, long lastProgress);
|
||||
|
||||
protected abstract void onPause(DownLoadTaskBean bean, long taskId, long currentProgress);
|
||||
|
||||
protected abstract void onError(DownLoadTaskBean bean, long taskId, String erroMsg, int errorCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
package com.android.download;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.api.CoreKeys;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class DownloadService {
|
||||
|
||||
/**
|
||||
* 是否正在下载
|
||||
*/
|
||||
private boolean isDownloading = false;
|
||||
public static int progress;
|
||||
private String dowUrl = null;
|
||||
//下载状态
|
||||
private int status = -1;
|
||||
private int fileSize;
|
||||
private int readSize;
|
||||
private int downSize;
|
||||
private File downFile;
|
||||
private static DownloadService mInstance = null;
|
||||
private DownlaodProgressCallBack mDownlaodProgressCallBack;
|
||||
/**
|
||||
* 下载完成状态
|
||||
*/
|
||||
public static final int DOWNLOAD_COMPLETE = 0;
|
||||
/**
|
||||
* 下载完成状态
|
||||
*/
|
||||
public static final int DOWNLOAD_ERROR = -1;
|
||||
public static final String FEATURE_PATH = CoreKeys.down_file + "atv.apk";
|
||||
private Handler handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
super.handleMessage(msg);
|
||||
switch (msg.what) {
|
||||
case 0:
|
||||
// //更新下载进度
|
||||
if (mDownlaodProgressCallBack != null) {
|
||||
int progress = (int) ((double) downSize / (double) fileSize * 100);
|
||||
mDownlaodProgressCallBack.onDownlaodProgress(progress);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
//下载完成进度
|
||||
mDownlaodProgressCallBack.onDownlaodStatus(DOWNLOAD_COMPLETE);
|
||||
break;
|
||||
case 2:
|
||||
//下载异常
|
||||
mDownlaodProgressCallBack.onDownlaodStatus(DOWNLOAD_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private DownloadService() {
|
||||
}
|
||||
|
||||
public static DownloadService initDownloadService() {
|
||||
if (mInstance == null) {
|
||||
mInstance = new DownloadService();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public static DownloadService getInstance() {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public void initDownLoadUrl(String downloadUrl) {
|
||||
dowUrl = downloadUrl;
|
||||
}
|
||||
|
||||
public void setDownlaodProgressCallBack(DownlaodProgressCallBack downlaodProgressCallBack) {
|
||||
this.mDownlaodProgressCallBack = downlaodProgressCallBack;
|
||||
}
|
||||
|
||||
|
||||
public void startService() {
|
||||
if (isDownloading) {
|
||||
return;
|
||||
}
|
||||
new Thread(startDownload).start();
|
||||
}
|
||||
|
||||
public void stopService() {
|
||||
isDownloading = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载模块
|
||||
*/
|
||||
private Runnable startDownload = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
fileSize = 0;
|
||||
readSize = 0;
|
||||
downSize = 0;
|
||||
progress = 0;
|
||||
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
LogUtils.e("postServerAppUpdate--->downUrl:" + dowUrl);
|
||||
try {
|
||||
URL myURL = new URL(dowUrl);
|
||||
URLConnection conn = myURL.openConnection();
|
||||
conn.connect();
|
||||
fileSize = conn.getContentLength();
|
||||
is = conn.getInputStream();
|
||||
|
||||
if (is == null) {
|
||||
Log.d("tag", "error");
|
||||
throw new RuntimeException("stream is null");
|
||||
}
|
||||
|
||||
File dir = new File(CoreKeys.down_file);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
downFile = new File(FEATURE_PATH);
|
||||
fos = new FileOutputStream(downFile);
|
||||
byte buf[] = new byte[1024 * 1024];
|
||||
isDownloading = true;
|
||||
while ((readSize = is.read(buf)) > 0) {
|
||||
if (!isDownloading) {
|
||||
return;
|
||||
}
|
||||
fos.write(buf, 0, readSize);
|
||||
downSize += readSize;
|
||||
Log.e("downSize", downSize + "");
|
||||
sendMessage(0, downSize);
|
||||
}
|
||||
sendMessage(1);
|
||||
isDownloading = false;
|
||||
|
||||
} catch (Exception e) {
|
||||
sendMessage(2);
|
||||
} finally {
|
||||
try {
|
||||
if (null != fos) fos.close();
|
||||
if (null != is) is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private void sendMessage(int code) {
|
||||
handler.sendEmptyMessage(code);
|
||||
}
|
||||
|
||||
private void sendMessage(int code, int progress) {
|
||||
Message message = new Message();
|
||||
message.what = code;
|
||||
message.arg1 = progress;
|
||||
handler.sendMessage(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取进度
|
||||
*/
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public interface DownlaodProgressCallBack {
|
||||
|
||||
public void onDownlaodProgress(int progress);
|
||||
|
||||
public void onDownlaodStatus(int status);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
90
nebula-sdk/src/main/java/com/android/download/TaskQueue.java
Normal file
90
nebula-sdk/src/main/java/com/android/download/TaskQueue.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package com.android.download;
|
||||
|
||||
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.android.util.GsonUtil;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class TaskQueue {
|
||||
private static TaskQueue instance;
|
||||
private List<DownLoadTaskThread> mTaskQueue;
|
||||
private ExecutorService downloadThreadCache = Executors.newFixedThreadPool(3);//这里是写死最多5个线程
|
||||
|
||||
private TaskQueue() {
|
||||
mTaskQueue = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return mTaskQueue.size();
|
||||
}
|
||||
|
||||
public static TaskQueue getInstance() {
|
||||
if (instance == null)
|
||||
instance = new TaskQueue();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public List<DownLoadTaskThread> getAllTask() {
|
||||
return mTaskQueue;
|
||||
}
|
||||
|
||||
public void add(DownLoadTaskThread task) {
|
||||
mTaskQueue.add(task);
|
||||
downloadThreadCache.execute(task);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
mTaskQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void remove(DownLoadTaskBean p) {
|
||||
for (int i = 0; i < mTaskQueue.size(); i++) {
|
||||
DownLoadTaskThread task = mTaskQueue.get(i);
|
||||
if (task.getBean().getUrl().equals(p.getUrl())) {
|
||||
mTaskQueue.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExistTask(DownLoadTaskBean p) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
LogUtils.e("postServerAppUpdate--->isExistTask111:"+ GsonUtil.GsonString(task));
|
||||
LogUtils.e("postServerAppUpdate--->isExistTask222:"+ GsonUtil.GsonString(p));
|
||||
if (task.getBean().getUrl().equals(p.getUrl()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void pause(String url) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
if (task.getBean().getUrl().equals(url)) {
|
||||
task.setPause(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
task.setPause(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void start(String url) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
if (task.getBean().getUrl().equals(url)) {
|
||||
task.setPause(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
nebula-sdk/src/main/java/com/android/nebulasdk/DConfig.java
Normal file
16
nebula-sdk/src/main/java/com/android/nebulasdk/DConfig.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.android.nebulasdk;
|
||||
|
||||
public class DConfig {
|
||||
|
||||
|
||||
public static final String ALLWINNER_PLM="allwinner";
|
||||
public static final String RK_PLM="rockchip";
|
||||
public static final String ARMLOGIC_PLM="amlogic";
|
||||
|
||||
public static final int API_VERSION_CODE=105;
|
||||
// public static final int API_VERSION_CODE=47;
|
||||
public static String PLATFORM_TAG=RK_PLM;
|
||||
|
||||
/**请求密钥*/
|
||||
public static final String REQUEST_SINGKEY="jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47";
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class AppInfoBean extends BaseValue{
|
||||
private int infraFileId;
|
||||
private String url;
|
||||
private long size;
|
||||
private String packageName;
|
||||
private int versionCode;
|
||||
private String versionName;
|
||||
private String platform;
|
||||
|
||||
public int getInfraFileId() {
|
||||
return infraFileId;
|
||||
}
|
||||
|
||||
public void setInfraFileId(int infraFileId) {
|
||||
this.infraFileId = infraFileId;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public int getVersionCode() {
|
||||
return versionCode;
|
||||
}
|
||||
|
||||
public void setVersionCode(int versionCode) {
|
||||
this.versionCode = versionCode;
|
||||
}
|
||||
|
||||
public String getVersionName() {
|
||||
return versionName;
|
||||
}
|
||||
|
||||
public void setVersionName(String versionName) {
|
||||
this.versionName = versionName;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class AppUpdateResponse extends BaseBean{
|
||||
public String data;
|
||||
|
||||
public String getData(){
|
||||
return data;
|
||||
}
|
||||
public void setData(String data){
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
/**
|
||||
* Created by Administrator on 2018/5/11 0011.
|
||||
*/
|
||||
|
||||
public class BaseBean extends BaseValue {
|
||||
|
||||
public String msg;
|
||||
public int code;
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class BaseValue implements Serializable {
|
||||
|
||||
public BaseValue() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class DomainBean {
|
||||
private int type;
|
||||
private String domainNames;
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDomainNames() {
|
||||
return domainNames;
|
||||
}
|
||||
|
||||
public void setDomainNames(String domainNames) {
|
||||
this.domainNames = domainNames;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class TimeBean extends BaseBean{
|
||||
private long time;
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class TimeResponse extends BaseBean{
|
||||
private TimeBean data;
|
||||
|
||||
public TimeBean getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(TimeBean data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
138
nebula-sdk/src/main/java/com/android/util/BitmapUtils.java
Normal file
138
nebula-sdk/src/main/java/com/android/util/BitmapUtils.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class BitmapUtils {
|
||||
|
||||
|
||||
/**
|
||||
* drawable to bitmap
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap drawableToBitmap(Drawable drawable){
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
drawable.setBounds(0,0,width,height);
|
||||
|
||||
Bitmap.Config config = drawable.getOpacity()!= PixelFormat.OPAQUE?Bitmap.Config.ARGB_8888:Bitmap.Config.RGB_565;
|
||||
Bitmap bitmap =Bitmap.createBitmap(width,height,config);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.draw(canvas);
|
||||
|
||||
return setRoundCornerBitmap(bitmap,10);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* drawable to bitmap
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap drawableToBitmap(Drawable drawable,int mwidth, int mheight){
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
drawable.setBounds(0,0,width,height);
|
||||
|
||||
Bitmap.Config config = drawable.getOpacity()!= PixelFormat.OPAQUE?Bitmap.Config.ARGB_8888:Bitmap.Config.RGB_565;
|
||||
Bitmap bitmap =Bitmap.createBitmap(mwidth,mheight,config);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.draw(canvas);
|
||||
|
||||
return setRoundCornerBitmap(bitmap,10);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* drawable to bitmap
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getWidthCircleBitmapbg(){
|
||||
|
||||
Bitmap dest = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Canvas c = new Canvas(dest);
|
||||
|
||||
PaintFlagsDrawFilter pfd = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); //画图片时设置画布抗锯齿
|
||||
c.setDrawFilter(pfd);
|
||||
|
||||
Paint paint = new Paint();
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
paint.setColor(Color.GREEN);
|
||||
|
||||
c.drawCircle(50/2,50/2, 50/2, paint);
|
||||
|
||||
return new BitmapDrawable(dest);
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap setRoundCornerBitmap(Bitmap bitmap,float roundPx){
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
|
||||
Bitmap outmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(outmap);
|
||||
final int color = 0xff424242;
|
||||
final Paint paint = new Paint();
|
||||
final Rect rect = new Rect(0,0,width,height);
|
||||
final RectF rectf = new RectF(rect);
|
||||
paint.setAntiAlias(true);
|
||||
canvas.drawARGB(0,0,0,0);
|
||||
paint.setColor(color);
|
||||
canvas.drawRoundRect(rectf,roundPx,roundPx,paint);
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
canvas.drawBitmap(bitmap,rect,rect,paint);
|
||||
return outmap;
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap getIconByPackageName(Context mContext,String packageName){
|
||||
|
||||
try {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);
|
||||
Drawable iconDrawable = applicationInfo.loadIcon(pm);//应用图标
|
||||
return BitmapUtils.drawableToBitmap(iconDrawable);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Bitmap getIconByPackageName(Context mContext,String packageName,int mwidth, int mheight){
|
||||
|
||||
try {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);
|
||||
Drawable iconDrawable = applicationInfo.loadIcon(pm);//应用图标
|
||||
return BitmapUtils.drawableToBitmap(iconDrawable, mwidth, mheight);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
20
nebula-sdk/src/main/java/com/android/util/CommonUtils.java
Normal file
20
nebula-sdk/src/main/java/com/android/util/CommonUtils.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
|
||||
public class CommonUtils {
|
||||
|
||||
public static boolean isServiceRunning(Context context,Class<?> serviceClass) {
|
||||
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
assert manager != null;
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||
if (serviceClass.getName().equals(service.service.getClassName())) {
|
||||
return true; // 服务已存在
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
21
nebula-sdk/src/main/java/com/android/util/DConfig.java
Normal file
21
nebula-sdk/src/main/java/com/android/util/DConfig.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.android.util;
|
||||
|
||||
public class DConfig {
|
||||
|
||||
|
||||
public static final String ALLWINNER_PLM = "allwinner";
|
||||
public static final String RK_PLM = "rk";
|
||||
public static final String ARMLOGIC_PLM = "armlogic";
|
||||
|
||||
/**
|
||||
* 当版本为47时,singKey为jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47,encryptionKey为1234567887654347;
|
||||
* 版本为48时,singKey为jdh2dh7hdbhu3hbfcyHvdhf87NFH67b48,encryptionKey为1234567887654348
|
||||
*/
|
||||
public static final String API_VERSION_CODE = "47";
|
||||
|
||||
/**
|
||||
* 默认域名
|
||||
*/
|
||||
public static final String DOMAIN_HOST = "api.yudao.iocoder.cn";
|
||||
public static String PLATFORM_TAG = RK_PLM;
|
||||
}
|
||||
423
nebula-sdk/src/main/java/com/android/util/DateUtil.java
Normal file
423
nebula-sdk/src/main/java/com/android/util/DateUtil.java
Normal file
@@ -0,0 +1,423 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class DateUtil {
|
||||
/**
|
||||
* 预设不同的时间格式
|
||||
*/
|
||||
//精确到年月日(英文) eg:2019-12-31
|
||||
public static String FORMAT_LONOGRAM = "yyyy-MM-dd";
|
||||
|
||||
public static String FORMAT_LONOGRAM01 = "yyyyMMdd";
|
||||
|
||||
//精确到时分秒的完整时间(英文) eg:2010-11-11 12:12:12
|
||||
public static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
|
||||
//精确到毫秒完整时间(英文) eg:2019-11-11 12:12:12.55
|
||||
public static String FORMAT_LONOGRAM_MILL = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
//精确到年月日(中文)eg:2019年11月11日
|
||||
public static String FORMAT_LONOGRAM_CN = "yyyy年MM月dd日";
|
||||
//精确到时分秒的完整时间(中文)eg:2019年11月11日 12时12分12秒
|
||||
public static String FORMAT_FULL_CN = "yyyy年MM月dd日 HH时MM分SS秒";
|
||||
//精确到毫秒完整时间(中文)
|
||||
public static String FORMAT_LONOGRAM_MILL_CN = "yyyy年MM月dd日HH时MM分SS秒SSS毫秒";
|
||||
/**
|
||||
* 预设默认的时间格式
|
||||
*/
|
||||
public static String getDefaultFormat() {
|
||||
return FORMAT_FULL;
|
||||
}
|
||||
/**
|
||||
* 预设格式格式化日期
|
||||
*/
|
||||
public static String format(Date date) {
|
||||
return format(date,getDefaultFormat());
|
||||
}
|
||||
/**
|
||||
* 自定义格式格式化日期
|
||||
*/
|
||||
public static String format(Date date, String format) {
|
||||
String value = "";
|
||||
if(date != null) {
|
||||
TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
sdf.setTimeZone(timeZone);
|
||||
value = sdf.format(date);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 根据预设默认格式,返回当前日期
|
||||
*/
|
||||
public static String getNow() {
|
||||
return format(new Date());
|
||||
}
|
||||
/**
|
||||
* 自定义时间格式,返回当前日期
|
||||
*/
|
||||
public static String getNow(String format) {
|
||||
return format(new Date(),format);
|
||||
}
|
||||
/**
|
||||
*根据预设默认时间 String->Date
|
||||
*/
|
||||
public static Date parse(String strDate) {
|
||||
return parse(strDate,getDefaultFormat());
|
||||
}
|
||||
|
||||
|
||||
public static String getNowTime() {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
return simpleDateFormat.format(date);
|
||||
}
|
||||
public static String getNowDate() {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM");
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
return simpleDateFormat.format(date);
|
||||
}
|
||||
public static String getNowWeek() {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE");
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
return simpleDateFormat.format(date);
|
||||
}
|
||||
|
||||
public static String getAm() {
|
||||
String am="";
|
||||
long time = System.currentTimeMillis();
|
||||
final Calendar mCalendar = Calendar.getInstance();
|
||||
mCalendar.setTimeInMillis(time);
|
||||
int apm = mCalendar.get(Calendar.AM_PM);
|
||||
if (apm == 0) {
|
||||
am="AM";
|
||||
} else if (apm == 1) {
|
||||
am="PM";
|
||||
}
|
||||
Log.d("getam","am value"+am);
|
||||
return am;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 自定义时间格式:Stirng->Date
|
||||
*/
|
||||
public static Date parse(String strDate,String format) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
try {
|
||||
TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
|
||||
sdf.setTimeZone(timeZone);
|
||||
return sdf.parse(strDate);
|
||||
}catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加年
|
||||
* @param num 正数往后推,负数往前移
|
||||
* Calendar:它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR
|
||||
* 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
|
||||
*/
|
||||
public static Date addYear(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.YEAR, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加整月
|
||||
* @param date
|
||||
* @param num 整数往后推,负数往前移
|
||||
* @return
|
||||
*/
|
||||
public static Date addMonth(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.MONTH, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加天数
|
||||
* @param date
|
||||
* @param num 整数往后推,负数往前移
|
||||
* @return
|
||||
*/
|
||||
public static Date addDay(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.DATE, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加分钟
|
||||
* @param date
|
||||
* @param num 整数往后推,负数往前移
|
||||
* @return
|
||||
*/
|
||||
public static Date addMinute(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.MINUTE, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 获取时间戳 eg:yyyy-MM-dd HH:mm:ss.S
|
||||
* @return
|
||||
*/
|
||||
public static String getTimeStamp() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_LONOGRAM_MILL);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
return sdf.format(cal.getTime());
|
||||
}
|
||||
/**
|
||||
* 获取日期的年份
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getYear(Date date) {
|
||||
return format(date).substring(0,4);
|
||||
}
|
||||
/**
|
||||
* 获取年份+月
|
||||
*/
|
||||
public static String getYearMonth(Date date) {
|
||||
return format(date).substring(0, 7);
|
||||
}
|
||||
/**
|
||||
*获取日期的小时数
|
||||
*/
|
||||
public static int getHour(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
return cal.get(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
/**
|
||||
* 自定义时间格式字符串距离今天的天数
|
||||
* @param strDate
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static int countDays(String strDate,String format) {
|
||||
long time = Calendar.getInstance().getTime().getTime();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(parse(strDate,format));
|
||||
long diff = cal.getTime().getTime();
|
||||
long a = time/1000;
|
||||
long b = diff/1000;
|
||||
return (int) (a - b)/3600/24;
|
||||
}
|
||||
/**
|
||||
* 预设格式的字符串距离今天的天数
|
||||
* @param strDate
|
||||
* @return
|
||||
*/
|
||||
public static int countDays(String strDate) {
|
||||
return countDays(strDate,getDefaultFormat());
|
||||
}
|
||||
/**
|
||||
* 获取天数差值(依赖时间)
|
||||
* @param date1
|
||||
* @param date2
|
||||
* @return
|
||||
*/
|
||||
public static int diffDays(Date date1,Date date2) {
|
||||
if(date1 == null || date2 == null) {
|
||||
return 0;
|
||||
}
|
||||
return (int) (Math.abs(date1.getTime() - date2.getTime()) / (60 * 60 * 24 * 1000));
|
||||
}
|
||||
/**
|
||||
* 获取年份差值
|
||||
* @param year1
|
||||
* @param year2
|
||||
* @return
|
||||
*/
|
||||
public static int diffYear(Date year1,Date year2) {
|
||||
return diffDays(year1,year2) / 365;
|
||||
}
|
||||
/**
|
||||
* 获取天数差值(依赖Date类型的日期)
|
||||
* @param d1
|
||||
* @param d2
|
||||
* @return
|
||||
*/
|
||||
public static int diffByDays(Date d1,Date d2) {
|
||||
Date s1 = parse(format(d1,FORMAT_LONOGRAM),FORMAT_LONOGRAM);
|
||||
Date s2 = parse(format(d2,FORMAT_LONOGRAM),FORMAT_LONOGRAM);
|
||||
return diffDays(s1,s2);
|
||||
}
|
||||
// /**
|
||||
// * 获取时间分割集合
|
||||
// *
|
||||
// * @param date 查询日期
|
||||
// * @param strs 带拆分的时间点
|
||||
// * @return
|
||||
// */
|
||||
// public static List<Date> collectTimes(Date date, String[] strs){
|
||||
// List<Date> result = new ArrayList<Date>();
|
||||
// List<String> times = Arrays.asList(strs);
|
||||
// String dateStr = format(date,FORMAT_LONOGRAM);
|
||||
// String pattern = FORMAT_LONOGRAM + "K";
|
||||
// if(times.size() > 0 ) {
|
||||
// times.stream().forEach(t -> {
|
||||
// result.add(parse(date +" "+ t,pattern));
|
||||
// });
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 根据日期查询当前为周几
|
||||
* @param dt
|
||||
* @return
|
||||
*/
|
||||
public static String getWeekOfDate(Date dt) {
|
||||
String[] weekDays = {"7","1","2","3","4","5","6"};
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(dt);
|
||||
int w = cal.get(Calendar.DAY_OF_WEEK); //1--7的值,对应:星期日,星期一,星期二,星期三....星期六
|
||||
//System.out.println(w);
|
||||
return weekDays[w-1];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间转换成汉字
|
||||
* @param hour
|
||||
* @return
|
||||
*/
|
||||
public static String hourToCn(String hour) {
|
||||
String[] timeArray = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
|
||||
String[] hourArray = hour.split(":");
|
||||
int hourInt = Integer.parseInt(hourArray[0]);
|
||||
int minute = Integer.parseInt(hourArray[1]);
|
||||
String result = intToCn(hourInt,timeArray) + "点\n" + intToCn(minute,timeArray) + "分";
|
||||
return result;
|
||||
}
|
||||
private static String intToCn(int hourInt, String[] timeArray) {
|
||||
String result = "";
|
||||
if(hourInt >= 0 && hourInt <= 10) {
|
||||
result += timeArray[hourInt] + "\n";
|
||||
} else if (hourInt >= 11 && hourInt <= 19) {
|
||||
result += (timeArray[10] + "\n" + timeArray[hourInt % 10]) + "\n";
|
||||
}else {
|
||||
result += (timeArray[hourInt / 10] + "\n" + timeArray[10]) + "\n" + (hourInt % 10 == 0 ? "" : timeArray[hourInt % 10] + "\n");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 获取当前日期后的一周时间,并返回LinkedHashMap<String, Date>
|
||||
* @param startTime
|
||||
* @return
|
||||
*/
|
||||
public static LinkedHashMap<String, Date> dateAfterWeek(String startTime) {
|
||||
LinkedHashMap<String, Date> result = new LinkedHashMap<>();
|
||||
try {
|
||||
Date date = parse(startTime,FORMAT_LONOGRAM);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(calendar.DATE, i); //把日期往后增加一天,整数往后推,负数往前移动 时间戳转时间
|
||||
Date newDate = calendar.getTime();
|
||||
String str = new SimpleDateFormat("yyyy-MM-dd").format(newDate);
|
||||
result.put(str, newDate);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 获取当前日期 后的一周时间,并返回yyyy-MM-dd字符串数组
|
||||
* @param startTime
|
||||
* @return
|
||||
*/
|
||||
public static String[] dateAfterWeekArray(String startTime) {
|
||||
String weekArray[] = new String[7];
|
||||
try {
|
||||
Date date = parse(startTime,FORMAT_LONOGRAM);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(calendar.DATE, i);//把日期往后增加一天,整数往后推,负数往前移动 时间戳转时间
|
||||
Date newDate = calendar.getTime();
|
||||
weekArray[i] = new SimpleDateFormat("yyyy-MM-dd").format(newDate);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return weekArray;
|
||||
}
|
||||
/**
|
||||
* 根据传入的时间获取本周开始(0-表示本周,1-表示下周,-1-表示上周 )
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getMonDayToDate(String date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(parse(date, "yyyy-MM-dd"));
|
||||
// N:0-表示本周,1-表示下周,-1-表示上周
|
||||
cal.add(Calendar.DATE, 0 * 7);
|
||||
// Calendar.MONDAY 表示获取周一的日期; Calendar.WEDNESDAY:表示周三的日期
|
||||
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||
return format(cal.getTime());
|
||||
}
|
||||
|
||||
|
||||
public static String getYesterDayDate(){
|
||||
|
||||
//获取当前日期
|
||||
Calendar calendar= Calendar.getInstance();
|
||||
// 将日期减一天
|
||||
calendar.add(Calendar.DAY_OF_MONTH,-1);
|
||||
return format(calendar.getTime(),FORMAT_LONOGRAM01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
//String time = format(new Date());
|
||||
//String weekOfDate = getWeekOfDate(new Date());
|
||||
//int countDays = countDays("2019-12-22",FORMAT_LONOGRAM);
|
||||
//Calendar cal = Calendar.getInstance();
|
||||
// long time = cal.getTime().getTime();
|
||||
// System.out.println("星期:"+weekOfDate);
|
||||
// String hourToCn = hourToCn(format(new Date()).substring(11, 19));
|
||||
// System.out.print(hourToCn);
|
||||
// String[] dateAfterWeekArray = dateAfterWeekArray(format(new Date()));
|
||||
// for (int i = 0; i < dateAfterWeekArray.length; i++) {
|
||||
// System.out.println(dateAfterWeekArray[i]);
|
||||
// }
|
||||
String monDayToDate = getMonDayToDate(format(new Date()));
|
||||
System.out.println(monDayToDate);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// public static String getDeviceName( NodeInfo nodeInfo) {
|
||||
// DevicTypeModelBean deviceType = TelinkMeshApplication.mDeviceModel.getDeviceModel(nodeInfo.deviceModleType.toLowerCase());
|
||||
// if (deviceType != null) {
|
||||
// nodeInfo.deviceName = deviceType.getType() + "-" + nodeInfo.macAddress.replace(":", "");
|
||||
// }
|
||||
// return nodeInfo.deviceName;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
472
nebula-sdk/src/main/java/com/android/util/DeviceUtil.java
Normal file
472
nebula-sdk/src/main/java/com/android/util/DeviceUtil.java
Normal file
@@ -0,0 +1,472 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class DeviceUtil {
|
||||
|
||||
public static String getDeviceId() {
|
||||
// String uuid =null;
|
||||
// TelephonyManager TelephonyMgr = (TelephonyManager) activity.getSystemService(TELEPHONY_SERVICE);
|
||||
// if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED) {
|
||||
// PermissionChecker.getInstance().requestReadPhoneState(activity);
|
||||
// return uuid;
|
||||
// }
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// /* LogUtils.e("$$$$$$$$------Build.getSerial()="+Build.getSerial());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getSimSerialNumber()="+TelephonyMgr.getSimSerialNumber());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getImei()="+TelephonyMgr.getImei());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getSubscriberId()="+TelephonyMgr.getSubscriberId());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getLine1Number()="+TelephonyMgr.getLine1Number());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getDeviceId()="+TelephonyMgr.getDeviceId());
|
||||
// LogUtils.e("$$$$$$$$------UUID="+UUID.randomUUID().toString());*/
|
||||
// uuid = Build.getSerial();//序列号
|
||||
// if(isEmpty(uuid)){//IMEI:国际移动设备识别码
|
||||
// uuid = TelephonyMgr.getImei();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//IMEI:国际移动设备识别码
|
||||
// uuid = TelephonyMgr.getDeviceId();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//ICCID:集成电路卡识别码(固化在手机SIM 卡中)
|
||||
// uuid = TelephonyMgr.getSimSerialNumber();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//IMSI:国际移动用户识别码(sim卡运营商信息)
|
||||
// uuid = TelephonyMgr.getSubscriberId();
|
||||
// }
|
||||
// if(isEmpty(uuid)){
|
||||
// uuid = TelephonyMgr.getLine1Number();
|
||||
// }
|
||||
// //UUID.randomUUID().toString();
|
||||
// }else {
|
||||
// Class<?> c = null;
|
||||
// try {
|
||||
// c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// uuid = (String) get.invoke(c, "ro.serialno");
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (NoSuchMethodException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalAccessException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// if (isEmpty(uuid)){
|
||||
// UUID.randomUUID().toString();
|
||||
// }
|
||||
return "";
|
||||
}
|
||||
|
||||
// public static String getSerialNumber(){
|
||||
// String serial = null;
|
||||
// try {
|
||||
// if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1){//7.11+
|
||||
// serial = Build.getSerial();
|
||||
// LogUtils.e("===========7.11+=======================");
|
||||
// }else{
|
||||
// Class<?> c;
|
||||
// c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// serial = (String) get.invoke(c, "ro.serialno");
|
||||
// LogUtils.e("===========7.11-======================");
|
||||
// }
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (NoSuchMethodException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (SecurityException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalAccessException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalArgumentException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if (serial == null){
|
||||
// //serial = "000000";
|
||||
// }
|
||||
// return serial;
|
||||
// }
|
||||
|
||||
|
||||
public static String getSerialNum(Context context) {
|
||||
String serial = null;
|
||||
// try {
|
||||
// Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// serial = (String) get.invoke(c, "ro.serialno");
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
|
||||
|
||||
// if (serial == null || serial.isEmpty() || serial.length() < 5) {
|
||||
// serial = getWifiMacAddress(context);
|
||||
// if (serial == null || serial.isEmpty()) serial = getBtMacAddress(context);
|
||||
// if (serial == null || serial.isEmpty()) serial = "serial No. error ";
|
||||
// }
|
||||
// return serial;
|
||||
return "BBBBBBBB";
|
||||
}
|
||||
|
||||
public static boolean isDeviceExist(Context context, String mac) {
|
||||
String deviceId = getEthernetMac();
|
||||
if (deviceId.equals(mac)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getEthernetMac() {
|
||||
String ethernetMac = null;
|
||||
try {
|
||||
NetworkInterface NIC = NetworkInterface.getByName("eth0");
|
||||
byte[] buf = NIC.getHardwareAddress();
|
||||
ethernetMac = byteHexString(buf);
|
||||
} catch (SocketException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// return "EC:2E:CC:81:0D:62"; //for test
|
||||
return ethernetMac;
|
||||
}
|
||||
|
||||
public static String getWifiMac(){
|
||||
String wifiMac = null;
|
||||
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/net/wlan0/address";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
wifiMac = line;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return wifiMac;
|
||||
}
|
||||
|
||||
/*
|
||||
* 字节数组转16进制字符串
|
||||
*/
|
||||
public static String byteHexString(byte[] array) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for(int i=0;i<array.length;i++){
|
||||
String hex = Integer.toHexString(array[i] & 0xFF);
|
||||
if (hex.length() == 1) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
if(i<array.length-1){
|
||||
builder.append(hex+":");
|
||||
}else {
|
||||
builder.append(hex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return builder.toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
public static String getBrand(){
|
||||
return Build.BRAND;
|
||||
}
|
||||
|
||||
public static String getBuild(){
|
||||
return Build.FINGERPRINT;
|
||||
}
|
||||
|
||||
public static String getDevice(){
|
||||
|
||||
return Build.DEVICE;
|
||||
}
|
||||
public static String getCpu(){
|
||||
String platform = getAllwinnerPlatform();
|
||||
if("sun8iw7".equals(platform)){
|
||||
return getH3CPUinfo();
|
||||
}
|
||||
return getH616And313CPUinfo();
|
||||
}
|
||||
|
||||
public static String getDdr(){
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getModel(){
|
||||
return Build.MODEL;
|
||||
}
|
||||
|
||||
public static String getPlatform(){
|
||||
return "allwinner";
|
||||
}
|
||||
|
||||
public static String getSystemVersion(){
|
||||
return Build.VERSION.RELEASE;
|
||||
}
|
||||
|
||||
|
||||
private static String getH3CPUinfo() {
|
||||
String cpuAddress = "";
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/sunxi_info/sys_info";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
if (line.contains("sunxi_chipid")) {
|
||||
String[] SerialStr = line.split(":");
|
||||
if (SerialStr.length == 2) {
|
||||
String mSerial = SerialStr[1];
|
||||
cpuAddress = mSerial.trim();
|
||||
return cpuAddress;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return cpuAddress;
|
||||
}
|
||||
|
||||
|
||||
private static String getH616And313CPUinfo() {
|
||||
String cpuAddress = "";
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/sunxi_info/sys_info";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
if (line.contains("sunxi_serial")) {
|
||||
String[] SerialStr = line.split(":");
|
||||
if (SerialStr.length == 2) {
|
||||
String mSerial = SerialStr[1];
|
||||
cpuAddress = mSerial.trim();
|
||||
return cpuAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return cpuAddress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static String getAllwinnerPlatform() {
|
||||
String platform = "";
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/sunxi_info/sys_info";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
if (line.contains("sunxi_platform")) {
|
||||
String[] SerialStr = line.split(":");
|
||||
if (SerialStr.length == 2) {
|
||||
String mSerial = SerialStr[1];
|
||||
platform = mSerial.trim();
|
||||
return platform;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统ram大小
|
||||
* @return
|
||||
*/
|
||||
public static String getSysteTotalMemorySize(Context context){
|
||||
//获得ActivityManager服务的对象
|
||||
ActivityManager mActivityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
//获得MemoryInfo对象
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo() ;
|
||||
//获得系统可用内存,保存在MemoryInfo对象上
|
||||
mActivityManager.getMemoryInfo(memoryInfo) ;
|
||||
long memSize = memoryInfo.totalMem ;
|
||||
//字符类型转换
|
||||
String availMemStr = formateFileSize(memSize,true);
|
||||
return availMemStr ;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 获取系统rom大小
|
||||
// * @return
|
||||
// */
|
||||
// @RequiresApi(api = Build.VERSION_CODES.O)
|
||||
// public static String getSysteTotalStorageSize(Context context){
|
||||
// //获得ActivityManager服务的对象
|
||||
// String availMemStr = null;
|
||||
// try {
|
||||
// StorageStatsManager storageManager = (StorageStatsManager)context.getSystemService(Context.STORAGE_STATS_SERVICE);
|
||||
// //字符类型转换
|
||||
// availMemStr = formateFileSize( storageManager.getTotalBytes(StorageManager.UUID_DEFAULT),true);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return availMemStr ;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统rom大小
|
||||
* @return
|
||||
*/
|
||||
public static String getSysteTotalStorageSize(Context context){
|
||||
//获得ActivityManager服务的对象
|
||||
String availMemStr = null;
|
||||
try {
|
||||
// final StorageManager storageManager = (StorageManager)context.getSystemService(Context.STORAGE_SERVICE);
|
||||
// storageManager.getStorageVolumes()
|
||||
|
||||
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
|
||||
long totalSize = statFs.getTotalBytes();
|
||||
//字符类型转换
|
||||
availMemStr = formateFileSize( totalSize,true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return availMemStr ;
|
||||
}
|
||||
|
||||
|
||||
// public static String getSysteTotalStorageSize(Context context) {
|
||||
// String dir = "/proc/meminfo";
|
||||
// try {
|
||||
// FileReader fr = new FileReader(dir);
|
||||
// BufferedReader br = new BufferedReader(fr, 2048);
|
||||
// String memoryLine = br.readLine();
|
||||
// String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
|
||||
// br.close();
|
||||
// return formateFileSize(Integer.parseInt(subMemoryLine.replaceAll("\\D+", "")) * 1024l,true);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return formateFileSize(0, true);
|
||||
// }
|
||||
|
||||
public static String formateFileSize(long size, boolean isInteger) {
|
||||
DecimalFormat df = isInteger ? new DecimalFormat("#0") : new DecimalFormat("#0.#");
|
||||
String fileSizeString = "0M";
|
||||
if (size < 1024 && size > 0) {
|
||||
fileSizeString = df.format((double) size) + "B";
|
||||
} else if (size < 1024 * 1024) {
|
||||
fileSizeString = df.format((double) size / 1024) + "K";
|
||||
} else if (size < 1024 * 1024 * 1024) {
|
||||
fileSizeString = df.format((double) size / (1024 * 1024)) + "M";
|
||||
} else {
|
||||
fileSizeString = df.format((double) size / (1024 * 1024 * 1024)) + "G";
|
||||
}
|
||||
return fileSizeString;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 获取本机默认的launcher
|
||||
* @return
|
||||
*/
|
||||
public static String getDefaultLauncherPackageName(Context context) {
|
||||
final UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
long time = System.currentTimeMillis();
|
||||
List<UsageStats> appList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time);
|
||||
|
||||
if (appList != null && appList.size() > 0) {
|
||||
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<>();
|
||||
for (UsageStats usageStats : appList) {
|
||||
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
|
||||
}
|
||||
if (mySortedMap != null && !mySortedMap.isEmpty()) {
|
||||
return mySortedMap.get(mySortedMap.lastKey()).getPackageName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getLauncherPackageName(Context context) {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
final List<ResolveInfo> resList = context.getPackageManager().queryIntentActivities(intent, 0);
|
||||
String tmp="";
|
||||
for (ResolveInfo res:resList) {
|
||||
if (res.activityInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if("com.android.settings".equals(res.activityInfo.packageName)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if("com.android.tv.settings".equals(res.activityInfo.packageName)){
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp+=res.activityInfo.packageName+",";
|
||||
}
|
||||
return "".equals(tmp)?null:tmp;
|
||||
}
|
||||
}
|
||||
22
nebula-sdk/src/main/java/com/android/util/DomainBean.java
Normal file
22
nebula-sdk/src/main/java/com/android/util/DomainBean.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.android.util;
|
||||
|
||||
public class DomainBean {
|
||||
private int type;
|
||||
private String domainNames;
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDomainNames() {
|
||||
return domainNames;
|
||||
}
|
||||
|
||||
public void setDomainNames(String domainNames) {
|
||||
this.domainNames = domainNames;
|
||||
}
|
||||
}
|
||||
165
nebula-sdk/src/main/java/com/android/util/EncryptionUtils.java
Normal file
165
nebula-sdk/src/main/java/com/android/util/EncryptionUtils.java
Normal file
@@ -0,0 +1,165 @@
|
||||
package com.android.util;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
/**
|
||||
* 类内容描述
|
||||
*
|
||||
* @author 杨崇顺
|
||||
* @since 2025-06-19 17:26
|
||||
*/
|
||||
public class EncryptionUtils {
|
||||
/**
|
||||
* MD5签名
|
||||
*
|
||||
* @param domain 发起请求时使用的域名。从设备端的host请求头获取,设备端在请求时一般不用设置,web请求框架自动带入的。 请求头示例:host=api.yudao.iocoder.cn
|
||||
* @param mac 设备mac。请求头示例: mac=A8:20:06:B7:C8:B9
|
||||
* @param cpu 设备cpu。请求头示例:cpu= 02c0008145f0462078a3840038350b53
|
||||
* @param time 13位时间戳。 服务器有个获取时间戳的接口,通过那个接口获取后后续请求带上来。请求头示例:time=1750324247858
|
||||
* @param salt 加密的盐值。建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @param sdkVersion sdk版本 ,从请求头获取。请求头示例: api-version=46
|
||||
* @return 签名结果
|
||||
*/
|
||||
public static String sign(String domain, String mac, String cpu, Long time, String salt, int sdkVersion) {
|
||||
String sign = domain + salt + "8622Nbdf52" + mac + salt + "2d6fndw" + cpu + salt + "3hd73bx6g" + time + salt + "23jhY6DGVhbd";
|
||||
return getMD5(sign);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证签名
|
||||
*
|
||||
* @param domain 发起请求时使用的域名。从设备端的host请求头获取,设备端在请求时一般不用设置,web请求框架自动带入的。 请求头示例:host=api.yudao.iocoder.cn
|
||||
* @param mac 设备mac。请求头示例: mac=A8:20:06:B7:C8:B9
|
||||
* @param cpu 设备cpu。请求头示例:cpu= 02c0008145f0462078a3840038350b53
|
||||
* @param time 13位时间戳。 服务器有个获取时间戳的接口,通过那个接口获取后后续请求带上来。请求头示例:time=1750324247858
|
||||
* @param salt 加密的盐值。建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @param sdkVersion sdk版本 ,从请求头获取。请求头示例: api-version=46
|
||||
* @param receivedSign 和字段带上来的签名结果
|
||||
* @return 验证结果(true=有效,false=无效)
|
||||
*/
|
||||
public static boolean verify(String domain, String mac, String cpu, Long time, String salt, int sdkVersion, String receivedSign) {
|
||||
// 重新生成签名并与接收的签名对比
|
||||
long nowTime = System.currentTimeMillis();
|
||||
long timeDiff = nowTime - time;
|
||||
if (timeDiff > 60000) {
|
||||
// 时间差超过60秒则判断验签失败,防止恶意请求
|
||||
return false;
|
||||
}
|
||||
String computedSign = sign(domain, mac, cpu, time, salt, sdkVersion);
|
||||
return computedSign.equals(receivedSign);
|
||||
}
|
||||
|
||||
public static String getMD5(String input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
// 关键修复:强制使用 UTF-8 编码
|
||||
md.update(input.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] digest = md.digest();
|
||||
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte b : digest) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) hexString.append('0');
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("MD5 algorithm not available", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
*
|
||||
* @param plainText 明文
|
||||
* @param secretKey 密钥。 建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @return 密文
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encrypt(String plainText, String secretKey) throws Exception {
|
||||
// 将密钥转换为字节数组并验证长度
|
||||
byte[] keyBytes = validateKey(secretKey);
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
|
||||
// 生成随机初始化向量(IV)
|
||||
byte[] ivBytes = new byte[16];
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
secureRandom.nextBytes(ivBytes);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
|
||||
|
||||
|
||||
// 初始化加密器
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
|
||||
|
||||
// 执行加密
|
||||
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
// 组合IV和密文(IV前置方案)
|
||||
byte[] combined = new byte[ivBytes.length + encryptedBytes.length];
|
||||
System.arraycopy(ivBytes, 0, combined, 0, ivBytes.length);
|
||||
System.arraycopy(encryptedBytes, 0, combined, ivBytes.length, encryptedBytes.length);
|
||||
|
||||
// 返回Base64编码的字符串
|
||||
return Base64.encode(combined, Base64.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
*
|
||||
* @param encryptedText 密文
|
||||
* @param secretKey 密钥。建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @return 明文
|
||||
* @throws Exception
|
||||
*/
|
||||
// 解密方法
|
||||
public static String decrypt(String encryptedText, String secretKey) throws Exception {
|
||||
// 将密钥转换为字节数组并验证长度
|
||||
byte[] keyBytes = validateKey(secretKey);
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
|
||||
// Base64解码
|
||||
byte[] combined = Base64.decode(encryptedText, Base64.DEFAULT);
|
||||
|
||||
// 分离IV和密文(前16字节是IV)
|
||||
byte[] ivBytes = new byte[16];
|
||||
byte[] encryptedBytes = new byte[combined.length - ivBytes.length];
|
||||
System.arraycopy(combined, 0, ivBytes, 0, ivBytes.length);
|
||||
System.arraycopy(combined, ivBytes.length, encryptedBytes, 0, encryptedBytes.length);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
|
||||
|
||||
// 初始化解密器
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
|
||||
|
||||
// 执行解密并返回UTF-8字符串
|
||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
// 密钥验证(支持128/192/256位)
|
||||
private static byte[] validateKey(String key) {
|
||||
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||
if (keyBytes.length != 16 && keyBytes.length != 24 && keyBytes.length != 32) {
|
||||
throw new IllegalArgumentException("密钥长度必须是16、24或32字节(对应128/192/256位)");
|
||||
}
|
||||
return keyBytes;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String sign = "12asbSDSHWEXSd7hdfh7AgdGS5kdg.mudhgAS";
|
||||
String md5 = getMD5(sign);
|
||||
System.out.println("md5=====" + md5);
|
||||
}
|
||||
}
|
||||
39
nebula-sdk/src/main/java/com/android/util/EventBusType.java
Normal file
39
nebula-sdk/src/main/java/com/android/util/EventBusType.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.android.util;
|
||||
|
||||
public class EventBusType{
|
||||
private Object mMessgae;
|
||||
private int mType;
|
||||
/**添加喜欢的应用到频道中去*/
|
||||
public static final int ADD_APP_TO_CHANNEL_TYPE=10;
|
||||
|
||||
/**频道设置关消息*/
|
||||
public static final int SWITCH_OFF_CHANNEL_TYPE=11;
|
||||
/**频道设置开消息*/
|
||||
public static final int SWITCH_ON_CHANNEL_TYPE=12;
|
||||
|
||||
|
||||
public static final int TYPE_USB_REMOVE=0;
|
||||
public static final int TYPE_SD_REMOVE=1;
|
||||
public static final int TYPE_SD_MOUNT=2;
|
||||
public static final int TYPE_USB_MOUNT=3;
|
||||
public static final int TYPE_ETHERNET=4;
|
||||
public static final int TYPE_WIFI=5;
|
||||
public static final int TYPE_NONET=6;
|
||||
public static final int TYPE_APP_REMOVE=7;
|
||||
public static final int TYPE_APP_INSTALL=8;
|
||||
/**app扫描完成*/
|
||||
public static final int SCANING_APP_COMPLETE =9;
|
||||
|
||||
|
||||
public EventBusType(int type,Object message){
|
||||
this.mType =type;
|
||||
this.mMessgae = message;
|
||||
};
|
||||
|
||||
public Object getMessgae() {
|
||||
return mMessgae;
|
||||
}
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
}
|
||||
352
nebula-sdk/src/main/java/com/android/util/FileSystem.java
Normal file
352
nebula-sdk/src/main/java/com/android/util/FileSystem.java
Normal file
@@ -0,0 +1,352 @@
|
||||
/********************************************************************************************************
|
||||
* @file FileSystem.java
|
||||
*
|
||||
* @brief for TLSR chips
|
||||
*
|
||||
* @author telink
|
||||
* @date Sep. 30, 2010
|
||||
*
|
||||
* @par Copyright (c) 2010, Telink Semiconductor (Shanghai) Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The information contained herein is confidential and proprietary property of Telink
|
||||
* Semiconductor (Shanghai) Co., Ltd. and is available under the terms
|
||||
* of Commercial License Agreement between Telink Semiconductor (Shanghai)
|
||||
* Co., Ltd. and the licensee in separate contract or the terms described here-in.
|
||||
* This heading MUST NOT be removed from this file.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information in this
|
||||
* file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
|
||||
*
|
||||
*******************************************************************************************************/
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
public class FileSystem {
|
||||
|
||||
public static boolean writeAsObject(Context context, String fileName, Object obj) {
|
||||
|
||||
File externalFilesDir = context.getExternalFilesDir(null);
|
||||
File file = new File(externalFilesDir, fileName);
|
||||
|
||||
FileOutputStream fos = null;
|
||||
ObjectOutputStream ops = null;
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
|
||||
fos = new FileOutputStream(file);
|
||||
ops = new ObjectOutputStream(fos);
|
||||
|
||||
ops.writeObject(obj);
|
||||
ops.flush();
|
||||
|
||||
success = true;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (ops != null)
|
||||
ops.close();
|
||||
if (ops != null)
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
public static boolean writeAsObject(Context context,String mkdir, String fileName, Object obj) {
|
||||
|
||||
File externalFilesDir = context.getExternalFilesDir(mkdir);
|
||||
File file = new File(externalFilesDir, fileName);
|
||||
|
||||
FileOutputStream fos = null;
|
||||
ObjectOutputStream ops = null;
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
|
||||
fos = new FileOutputStream(file);
|
||||
ops = new ObjectOutputStream(fos);
|
||||
|
||||
ops.writeObject(obj);
|
||||
ops.flush();
|
||||
|
||||
success = true;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (ops != null)
|
||||
ops.close();
|
||||
if (ops != null)
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Object readAsObject(Context context, String fileName) {
|
||||
|
||||
File dir = context.getExternalFilesDir(null);
|
||||
File file = new File(dir, fileName);
|
||||
|
||||
if (!file.exists())
|
||||
return null;
|
||||
|
||||
FileInputStream fis = null;
|
||||
ObjectInputStream ois = null;
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
|
||||
fis = new FileInputStream(file);
|
||||
ois = new ObjectInputStream(fis);
|
||||
|
||||
result = ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.e("postServerAppUpdate--->read object error : " + e.toString());
|
||||
} finally {
|
||||
try {
|
||||
if (ois != null)
|
||||
ois.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static Object readAsObject(Context context, String mkdir,String fileName) {
|
||||
|
||||
File dir = context.getExternalFilesDir(mkdir);
|
||||
File file = new File(dir, fileName);
|
||||
|
||||
if (!file.exists())
|
||||
return null;
|
||||
|
||||
FileInputStream fis = null;
|
||||
ObjectInputStream ois = null;
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
|
||||
fis = new FileInputStream(file);
|
||||
ois = new ObjectInputStream(fis);
|
||||
|
||||
result = ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.e("postServerAppUpdate--->read object error : " + e.toString());
|
||||
} finally {
|
||||
try {
|
||||
if (ois != null)
|
||||
ois.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**获取指定目录下的所有文件*/
|
||||
public static File[] getListFileByMkdir(Context context,String mkdir){
|
||||
File dir = context.getExternalFilesDir(mkdir);
|
||||
if(dir.exists()){
|
||||
return dir.listFiles();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Object readTestAsObject(Context context, String filePath) {
|
||||
|
||||
// File dir = context.getFilesDir();
|
||||
File file = new File(filePath);
|
||||
|
||||
if (!file.exists())
|
||||
return null;
|
||||
|
||||
FileInputStream fis = null;
|
||||
ObjectInputStream ois = null;
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
|
||||
fis = new FileInputStream(file);
|
||||
ois = new ObjectInputStream(fis);
|
||||
|
||||
result = ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.e("postServerAppUpdate--->read object error : " + e.toString());
|
||||
} finally {
|
||||
try {
|
||||
if (ois != null)
|
||||
ois.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static File getSettingPath() {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
return new File(root.getAbsolutePath() + File.separator + "Godox-BleMesh");
|
||||
}
|
||||
|
||||
//
|
||||
public static File writeString(File dir, String filename, String content) {
|
||||
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
File file = new File(dir, filename);
|
||||
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
fos = new FileOutputStream(file);
|
||||
fos.write(content.getBytes());
|
||||
fos.flush();
|
||||
fos.close();
|
||||
return file;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String readString(File file) {
|
||||
if (!file.exists())
|
||||
return "";
|
||||
try {
|
||||
FileReader fr = new FileReader(file);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
String line = null;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while ((line = br.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
|
||||
br.close();
|
||||
fr.close();
|
||||
return sb.toString();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 跟新替换文件
|
||||
* @param filePath
|
||||
* @param newFilePath
|
||||
*/
|
||||
public static void copyFile(String filePath,String newFilePath){
|
||||
File file = new File(newFilePath);
|
||||
//复制到的位置
|
||||
File toFile = new File(filePath);
|
||||
try {
|
||||
copy(file,toFile);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void copy(File file,File toFile) throws Exception {
|
||||
byte[] b = new byte[1024];
|
||||
int a;
|
||||
FileInputStream fis;
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
if (file.isDirectory()) {
|
||||
String filepath = file.getAbsolutePath();
|
||||
filepath = filepath.replaceAll("\\\\", "/");
|
||||
String toFilepath = toFile.getAbsolutePath();
|
||||
toFilepath = toFilepath.replaceAll("\\\\", "/");
|
||||
int lastIndexOf = filepath.lastIndexOf("/");
|
||||
toFilepath = toFilepath + filepath.substring(lastIndexOf, filepath.length());
|
||||
File copy = new File(toFilepath);
|
||||
//复制文件夹
|
||||
if (!copy.exists()) {
|
||||
copy.mkdir();
|
||||
}
|
||||
//遍历文件夹
|
||||
for (File f : file.listFiles()) {
|
||||
copy(f, copy);
|
||||
}
|
||||
} else {
|
||||
if (toFile.isDirectory()) {
|
||||
String filepath = file.getAbsolutePath();
|
||||
filepath = filepath.replaceAll("\\\\", "/");
|
||||
String toFilepath = toFile.getAbsolutePath();
|
||||
toFilepath = toFilepath.replaceAll("\\\\", "/");
|
||||
int lastIndexOf = filepath.lastIndexOf("/");
|
||||
toFilepath = toFilepath + filepath.substring(lastIndexOf, filepath.length());
|
||||
|
||||
//写文件
|
||||
File newFile = new File(toFilepath);
|
||||
fis = new FileInputStream(file);
|
||||
fos = new FileOutputStream(newFile);
|
||||
while ((a = fis.read(b)) != -1) {
|
||||
fos.write(b,0, a);
|
||||
}
|
||||
} else {
|
||||
//写文件
|
||||
fis = new FileInputStream(file);
|
||||
fos = new FileOutputStream(toFile);
|
||||
while ((a = fis.read(b)) != -1) {
|
||||
fos.write(b,0, a);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
144
nebula-sdk/src/main/java/com/android/util/FileUtil.java
Normal file
144
nebula-sdk/src/main/java/com/android/util/FileUtil.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
|
||||
|
||||
public static final String ADVERT_DIR="ADVERT";
|
||||
public static final String APP_DIR="APP";
|
||||
public static final String LAUNCHER_DIR="LAUNCHER";
|
||||
|
||||
public static final String OTA_DIR="OTA";
|
||||
/**广告类型*/
|
||||
public static final int ADVERT_TYPE=0;
|
||||
/**app类型*/
|
||||
public static final int APP_TYPE=1;
|
||||
/**Launcher类型*/
|
||||
public static final int LAUNCHER_TYPE=2;
|
||||
|
||||
public static final int OTA_TYPE=3;
|
||||
public static String getBakPath(Context context,int type){
|
||||
|
||||
String bakDir = null;
|
||||
switch (type){
|
||||
case ADVERT_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+ADVERT_DIR;//获取跟目录
|
||||
break;
|
||||
case APP_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+APP_DIR;//获取跟目录
|
||||
break;
|
||||
case LAUNCHER_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+LAUNCHER_DIR;//获取跟目录
|
||||
break;
|
||||
case OTA_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+OTA_DIR;//获取跟目录
|
||||
break;
|
||||
}
|
||||
|
||||
File file=new File(bakDir);
|
||||
if(file.exists()){
|
||||
if(file.isFile()){
|
||||
file.delete();
|
||||
file.mkdir();
|
||||
}
|
||||
}else {
|
||||
file.mkdir();
|
||||
}
|
||||
return file.getPath();
|
||||
}
|
||||
|
||||
|
||||
public static String getLauncherBakPath(Context context){
|
||||
|
||||
return context.getExternalCacheDir().getPath()+File.separator+LAUNCHER_DIR;
|
||||
}
|
||||
public static String getAppBakPath(Context context){
|
||||
|
||||
return context.getExternalCacheDir().getPath()+File.separator+APP_DIR;
|
||||
}
|
||||
|
||||
public static String getAdvertBakPath(Context context){
|
||||
|
||||
return context.getExternalCacheDir().getPath()+File.separator+ADVERT_DIR;
|
||||
}
|
||||
|
||||
|
||||
public static void deleteFile(String filePath){
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
if(file.exists()){
|
||||
file.delete();
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy file
|
||||
* @param targetFile
|
||||
* @param sourceFile
|
||||
*/
|
||||
public static void copyFilesFromTo(File targetFile, File sourceFile,long targetFilePoint) {
|
||||
|
||||
try {
|
||||
if(!targetFile.exists()){
|
||||
return;
|
||||
}
|
||||
if(!sourceFile.exists()){
|
||||
return;
|
||||
}
|
||||
InputStream inputStream = new FileInputStream(sourceFile);
|
||||
// 1.建立通道对象
|
||||
RandomAccessFile randomFile = new RandomAccessFile(targetFile, "rwd");
|
||||
randomFile.seek(targetFilePoint);
|
||||
// 2.create read data buffer
|
||||
byte[] buffer = new byte[1024*1024*10];
|
||||
// 3.开始读文件
|
||||
int lenght = 0;
|
||||
long copyFileSize=0;
|
||||
while ((lenght = inputStream.read(buffer)) != -1) {// 循环从输入流读取buffer字节
|
||||
// 将Buffer中的数据写到outputStream对象中
|
||||
|
||||
randomFile.write(buffer, 0, lenght);
|
||||
copyFileSize+=lenght;
|
||||
}
|
||||
|
||||
LogUtils.e("postServerAppUpdate--->copyFileSize===:"+copyFileSize);
|
||||
// 4.关闭流
|
||||
randomFile.close();
|
||||
inputStream.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getFileName(String url){
|
||||
if(url!=null&&url.contains(".")){
|
||||
return url.substring(url.lastIndexOf("/"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
/**
|
||||
* Created by Administrator on 2018/5/24 0024.
|
||||
* 获取APP版本号
|
||||
*/
|
||||
|
||||
public class GetEditionCode {
|
||||
/**
|
||||
* 获取版本信息
|
||||
*
|
||||
* @throws PackageManager.NameNotFoundException
|
||||
*/
|
||||
public static String getVersionNameCode(Context context) {
|
||||
//获取包管理对象
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
//获取包信息
|
||||
PackageInfo packageInfo = null;
|
||||
try {
|
||||
packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return packageInfo.versionName; //获取版本码
|
||||
}
|
||||
}
|
||||
130
nebula-sdk/src/main/java/com/android/util/GsonUtil.java
Normal file
130
nebula-sdk/src/main/java/com/android/util/GsonUtil.java
Normal file
@@ -0,0 +1,130 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GsonUtil {
|
||||
|
||||
private static Gson gson = null;
|
||||
|
||||
static {
|
||||
if (gson == null) {
|
||||
gson = new Gson();
|
||||
}
|
||||
}
|
||||
|
||||
private GsonUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成json
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static String GsonString(Object object) {
|
||||
String gsonString = null;
|
||||
if (gson != null) {
|
||||
gsonString = gson.toJson(object);
|
||||
}
|
||||
return gsonString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成bean
|
||||
*
|
||||
* @param gsonString
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
public static <T> T GsonToBean(String gsonString, Class<T> cls) {
|
||||
T t = null;
|
||||
if (gson != null) {
|
||||
t = gson.fromJson(gsonString, cls);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成带list的bean
|
||||
*
|
||||
* @param gsonString
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
|
||||
public static <T> T GsonToListBean(String gsonString, Class<T> cls) {
|
||||
T t = null;
|
||||
if (gson != null) {
|
||||
t = gson.fromJson(gsonString, cls);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成list
|
||||
*
|
||||
* @param gsonString
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {
|
||||
ArrayList<T> mList = new ArrayList<>();
|
||||
JsonArray array = new JsonParser().parse(gsonString).getAsJsonArray();
|
||||
for (final JsonElement elem : array) {
|
||||
mList.add(gson.fromJson(elem, cls));
|
||||
}
|
||||
return mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成list中有map的
|
||||
*
|
||||
* @param gsonString
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
|
||||
List<Map<String, T>> list = null;
|
||||
if (gson != null) {
|
||||
list = gson.fromJson(gsonString,
|
||||
new TypeToken<List<Map<String, T>>>() {
|
||||
}.getType());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成map的
|
||||
*
|
||||
* @param gsonString
|
||||
* @return
|
||||
*/
|
||||
public static <T> Map<String, T> GsonToMaps(String gsonString) {
|
||||
Map<String, T> map = null;
|
||||
if (gson != null) {
|
||||
map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
|
||||
}.getType());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static boolean isJson(String content){
|
||||
try {
|
||||
JSONObject jsonStr= new JSONObject(content);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
238
nebula-sdk/src/main/java/com/android/util/LogManager.java
Normal file
238
nebula-sdk/src/main/java/com/android/util/LogManager.java
Normal file
@@ -0,0 +1,238 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
public class LogManager {
|
||||
|
||||
private Context mContext;
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private static final String FILE_NALE = "nebula_log.txt";
|
||||
/**
|
||||
* 文件路径
|
||||
*/
|
||||
private String LOG_FILE_PATH = null;
|
||||
private FileOutputStream mFileOutputStream;
|
||||
private FileInputStream mFileInputStream;
|
||||
private static LogManager mInstance = null;
|
||||
private ReadLogCallBack mReadLogCallBack;
|
||||
// private boolean isReadLog =false;
|
||||
private boolean isReadLog = true;
|
||||
|
||||
private static final String LOGCONFIG = "/system/logconfig.json";
|
||||
|
||||
private LogManager(Context context) {
|
||||
this.mContext = context;
|
||||
this.LOG_FILE_PATH = context.getExternalCacheDir().getPath() + File.separator + FILE_NALE;
|
||||
mFileOutputStream = createWriterStream();
|
||||
mFileInputStream = createReadStream();
|
||||
isReadLog = getLogSwitch();
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
if (mInstance == null) {
|
||||
mInstance = new LogManager(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static LogManager getmInstance() {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public boolean isReadLog() {
|
||||
return isReadLog;
|
||||
// return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean getLogSwitch() {
|
||||
String json = getAssertData(mContext, LOGCONFIG);
|
||||
if (json == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Map<String, Boolean> logConfigMap = GsonUtil.GsonToMaps(json);
|
||||
logConfigMap.get("Logswitch");
|
||||
return logConfigMap.get("Logswitch");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String getAssertData(Context context, String filepath) {
|
||||
File file = new File(filepath);
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
// InputStream is = context.getResources().openRawResource(R.raw.setting_system_update);
|
||||
|
||||
// if (Build.MODEL.equals("Z10Plus")||Build.MODEL.equals("Z10Pro")){
|
||||
// is = context.getResources().openRawResource(R.raw.setting_system_update_z10pro);
|
||||
// }
|
||||
String resultString = "";
|
||||
try {
|
||||
InputStream is = new FileInputStream(file);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
|
||||
String jsonString = "";
|
||||
while ((jsonString = bufferedReader.readLine()) != null) {
|
||||
|
||||
resultString += jsonString;
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return resultString;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 写日志
|
||||
*/
|
||||
public void logWriterMsg(String logMsg) {
|
||||
try {
|
||||
|
||||
if (!isReadLog) {
|
||||
return;
|
||||
}
|
||||
|
||||
logMsg = DateUtil.format(new Date()) + ": " + logMsg + "\n";
|
||||
if (mReadLogCallBack != null) {
|
||||
mReadLogCallBack.onLogMsg(logMsg);
|
||||
}
|
||||
if (mFileOutputStream != null) {
|
||||
|
||||
mFileOutputStream.write(logMsg.getBytes());
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
mFileOutputStream.close();
|
||||
} catch (IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
mFileOutputStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读日志
|
||||
*/
|
||||
public void logReadMsg(ReadLogCallBack readLogCallBack) {
|
||||
mReadLogCallBack = readLogCallBack;
|
||||
isReadLog = true;
|
||||
}
|
||||
|
||||
public void stopRecordLogMsg() {
|
||||
isReadLog = false;
|
||||
}
|
||||
|
||||
|
||||
private FileOutputStream createWriterStream() {
|
||||
try {
|
||||
File file = new File(LOG_FILE_PATH);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
mFileOutputStream = new FileOutputStream(LOG_FILE_PATH);
|
||||
return mFileOutputStream;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private FileInputStream createReadStream() {
|
||||
try {
|
||||
mFileInputStream = new FileInputStream(LOG_FILE_PATH);
|
||||
return mFileInputStream;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public interface ReadLogCallBack {
|
||||
public void onLogMsg(String msg);
|
||||
}
|
||||
|
||||
|
||||
// class ReadMsgThread extends Thread{
|
||||
//
|
||||
//
|
||||
// private boolean isRuning=false;
|
||||
// private ReadLogCallBack mReadLogCallBack;
|
||||
//
|
||||
// public ReadMsgThread(ReadLogCallBack readLogCallBack){
|
||||
// this.mReadLogCallBack = readLogCallBack;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// super.run();
|
||||
// isRuning =true;
|
||||
// byte[] bytes = new byte[1024];
|
||||
// try {
|
||||
// while (isRuning){
|
||||
// int len= mFileInputStream.read(bytes);
|
||||
// if(len>0) {
|
||||
// if (mReadLogCallBack != null) {
|
||||
// String msg = new String(bytes, "utf-8");
|
||||
// mReadLogCallBack.onLogMsg(msg);
|
||||
// }
|
||||
// try {
|
||||
// sleep(500);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }else {
|
||||
// try {
|
||||
// sleep(3000);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public void stopThread(){
|
||||
// isRuning = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.EditText;
|
||||
|
||||
/*
|
||||
* 监听输入内容是否超出最大长度,并设置光标位置
|
||||
* */
|
||||
public class MaxLengthWatcher implements TextWatcher {
|
||||
|
||||
private int maxLen = 0;
|
||||
private EditText editText = null;
|
||||
|
||||
|
||||
public MaxLengthWatcher(int maxLen, EditText editText) {
|
||||
this.maxLen = maxLen;
|
||||
this.editText = editText;
|
||||
}
|
||||
|
||||
public MaxLengthWatcher() {
|
||||
|
||||
}
|
||||
|
||||
public void afterTextChanged(Editable arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
|
||||
int arg3) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
|
||||
// TODO Auto-generated method stub
|
||||
Editable editable = editText.getText();
|
||||
int len = editable.length();
|
||||
|
||||
if(len > maxLen)
|
||||
{
|
||||
int selEndIndex = Selection.getSelectionEnd(editable);
|
||||
String str = editable.toString();
|
||||
//截取新字符串
|
||||
String newStr = str.substring(0,maxLen);
|
||||
editText.setText(newStr);
|
||||
editable = editText.getText();
|
||||
|
||||
//新字符串的长度
|
||||
int newLen = editable.length();
|
||||
//旧光标位置超过字符串长度
|
||||
if(selEndIndex > newLen)
|
||||
{
|
||||
selEndIndex = editable.length();
|
||||
}
|
||||
//设置新光标所在的位置
|
||||
Selection.setSelection(editable, selEndIndex);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
113
nebula-sdk/src/main/java/com/android/util/MimeType.java
Normal file
113
nebula-sdk/src/main/java/com/android/util/MimeType.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package com.android.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MimeType {
|
||||
|
||||
public static final int VIDEO_MIME_TYPE=0x01;
|
||||
public static final int IMAGE_MIME_TYPE=0x02;
|
||||
public static final int APP_MIME_TYPE=0x03;
|
||||
public static final int UNKNOWN_MIME_TYPE=0x04;
|
||||
private static Map<String,String> map=new HashMap<>();
|
||||
static final String[][] MIME_MapTable={
|
||||
//{后缀名, MIME类型}
|
||||
{".3gp", "video/3gpp"},
|
||||
{".apk", "application/vnd.android.package-archive"},
|
||||
{".asf", "video/x-ms-asf"},
|
||||
{".avi", "video/x-msvideo"},
|
||||
{".bin", "application/octet-stream"},
|
||||
{".bmp", "image/bmp"},
|
||||
{".c", "text/plain"},
|
||||
{".class", "application/octet-stream"},
|
||||
{".conf", "text/plain"},
|
||||
{".cpp", "text/plain"},
|
||||
{".doc", "application/msword"},
|
||||
{".exe", "application/octet-stream"},
|
||||
{".gif", "image/gif"},
|
||||
{".gtar", "application/x-gtar"},
|
||||
{".gz", "application/x-gzip"},
|
||||
{".h", "text/plain"},
|
||||
{".htm", "text/html"},
|
||||
{".html", "text/html"},
|
||||
{".jar", "application/java-archive"},
|
||||
{".java", "text/plain"},
|
||||
{".jpeg", "image/jpeg"},
|
||||
{".jpg", "image/jpeg"},
|
||||
{".js", "application/x-javascript"},
|
||||
{".log", "text/plain"},
|
||||
{".m3u", "audio/x-mpegurl"},
|
||||
{".m4a", "audio/mp4a-latm"},
|
||||
{".m4b", "audio/mp4a-latm"},
|
||||
{".m4p", "audio/mp4a-latm"},
|
||||
{".m4u", "video/vnd.mpegurl"},
|
||||
{".m4v", "video/x-m4v"},
|
||||
{".mov", "video/quicktime"},
|
||||
{".mp2", "audio/x-mpeg"},
|
||||
{".mp3", "audio/x-mpeg"},
|
||||
{".mp4", "video/mp4"},
|
||||
{".mpc", "application/vnd.mpohun.certificate"},
|
||||
{".mpe", "video/mpeg"},
|
||||
{".mpeg", "video/mpeg"},
|
||||
{".mpg", "video/mpeg"},
|
||||
{".mpg4", "video/mpg4"},
|
||||
{".mpga", "audio/mpeg"},
|
||||
{".msg", "application/vnd.ms-outlook"},
|
||||
{".ogg", "audio/ogg"},
|
||||
{".pdf", "application/pdf"},
|
||||
{".png", "image/png"},
|
||||
{".pps", "application/vnd.ms-powerpoint"},
|
||||
{".ppt", "application/vnd.ms-powerpoint"},
|
||||
{".prop", "text/plain"},
|
||||
{".rar", "application/x-rar-compressed"},
|
||||
{".rc", "text/plain"},
|
||||
{".rmvb", "audio/x-pn-realaudio"},
|
||||
{".rtf", "application/rtf"},
|
||||
{".sh", "text/plain"},
|
||||
{".tar", "application/x-tar"},
|
||||
{".tgz", "application/x-compressed"},
|
||||
{".txt", "text/plain"},
|
||||
{".wav", "audio/x-wav"},
|
||||
{".wma", "audio/x-ms-wma"},
|
||||
{".wmv", "audio/x-ms-wmv"},
|
||||
{".wps", "application/vnd.ms-works"},
|
||||
//{".xml", "text/xml"},
|
||||
{".xml", "text/plain"},
|
||||
{".z", "application/x-compress"},
|
||||
{".zip", "application/zip"},
|
||||
{"", "*/*"}
|
||||
};
|
||||
static{
|
||||
for (int i=0;i<MIME_MapTable.length;i++){
|
||||
String[] tmpArray= MIME_MapTable[i];
|
||||
map.put(tmpArray[1],tmpArray[0]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static String getMimeTypeSuffix(String mimeType){
|
||||
return map.get(mimeType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int checkFileMimeType(String mimeType){
|
||||
if(mimeType==null||"".equals(mimeType)){
|
||||
return UNKNOWN_MIME_TYPE;
|
||||
}
|
||||
if(mimeType.contains("video/")){
|
||||
return VIDEO_MIME_TYPE;
|
||||
}else if(mimeType.contains("image/")){
|
||||
return IMAGE_MIME_TYPE;
|
||||
}else if(mimeType.contains("application/")){
|
||||
return APP_MIME_TYPE;
|
||||
}else {
|
||||
return UNKNOWN_MIME_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
51
nebula-sdk/src/main/java/com/android/util/NetUtil.java
Normal file
51
nebula-sdk/src/main/java/com/android/util/NetUtil.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
/**
|
||||
* Created by hanbin on 2017/9/12.
|
||||
*/
|
||||
|
||||
public class NetUtil {
|
||||
/**
|
||||
* 没有网络
|
||||
*/
|
||||
public static final int NETWORK_NONE = -1;
|
||||
/**
|
||||
* 移动网络
|
||||
*/
|
||||
public static final int NETWORK_MOBILE = 0;
|
||||
/**
|
||||
* 无线网络
|
||||
*/
|
||||
public static final int NETWORK_WIFI = 1;
|
||||
/**
|
||||
* 以太网
|
||||
*/
|
||||
public static final int NETWORK_ETHERNET = 2;
|
||||
|
||||
public static int getNetWorkState(Context context) {
|
||||
//得到连接管理器对象
|
||||
ConnectivityManager connectivityManager = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
NetworkInfo activeNetworkInfo = connectivityManager
|
||||
.getActiveNetworkInfo();
|
||||
//如果网络连接,判断该网络类型
|
||||
if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
|
||||
if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_WIFI)) {
|
||||
return NETWORK_WIFI;//wifi
|
||||
} else if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_MOBILE)) {
|
||||
return NETWORK_MOBILE;//mobile
|
||||
}else if(activeNetworkInfo.getType() ==(ConnectivityManager.TYPE_ETHERNET) ){
|
||||
return NETWORK_ETHERNET;//ethernet
|
||||
}
|
||||
} else {
|
||||
//网络异常
|
||||
return NETWORK_NONE;
|
||||
}
|
||||
return NETWORK_NONE;
|
||||
}
|
||||
}
|
||||
22
nebula-sdk/src/main/java/com/android/util/NetworkType.java
Normal file
22
nebula-sdk/src/main/java/com/android/util/NetworkType.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.android.util;
|
||||
|
||||
public enum NetworkType {
|
||||
NETWORK_WIFI("WiFi"),
|
||||
NETWORK_4G("4G"),
|
||||
NETWORK_2G("2G"),
|
||||
NETWORK_3G("3G"),
|
||||
NETWORK_ETHERNET("Ethernet"),
|
||||
NETWORK_UNKNOWN("Unknown"),
|
||||
NETWORK_NO("No network");
|
||||
|
||||
private String desc;
|
||||
NetworkType(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
100
nebula-sdk/src/main/java/com/android/util/NetworkUtil.java
Normal file
100
nebula-sdk/src/main/java/com/android/util/NetworkUtil.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
public class NetworkUtil {
|
||||
private NetworkUtil() {
|
||||
throw new UnsupportedOperationException("u can't instantiate me...");
|
||||
}
|
||||
|
||||
private static NetworkInfo getActiveNetworkInfo(Context context) {
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
return cm.getActiveNetworkInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前网络类型
|
||||
* 需添加权限 {@code <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>}
|
||||
*/
|
||||
public static NetworkType getNetworkType(Context context) {
|
||||
NetworkType netType = NetworkType.NETWORK_NO;
|
||||
NetworkInfo info = getActiveNetworkInfo(context);
|
||||
if (info != null && info.isAvailable()) {
|
||||
|
||||
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
|
||||
netType = NetworkType.NETWORK_WIFI;
|
||||
} else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
|
||||
switch (info.getSubtype()) {
|
||||
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_A:
|
||||
case TelephonyManager.NETWORK_TYPE_UMTS:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_0:
|
||||
case TelephonyManager.NETWORK_TYPE_HSDPA:
|
||||
case TelephonyManager.NETWORK_TYPE_HSUPA:
|
||||
case TelephonyManager.NETWORK_TYPE_HSPA:
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_B:
|
||||
case TelephonyManager.NETWORK_TYPE_EHRPD:
|
||||
case TelephonyManager.NETWORK_TYPE_HSPAP:
|
||||
netType = NetworkType.NETWORK_3G;
|
||||
break;
|
||||
|
||||
case TelephonyManager.NETWORK_TYPE_LTE:
|
||||
case TelephonyManager.NETWORK_TYPE_IWLAN:
|
||||
netType = NetworkType.NETWORK_4G;
|
||||
break;
|
||||
|
||||
case TelephonyManager.NETWORK_TYPE_GSM:
|
||||
case TelephonyManager.NETWORK_TYPE_GPRS:
|
||||
case TelephonyManager.NETWORK_TYPE_CDMA:
|
||||
case TelephonyManager.NETWORK_TYPE_EDGE:
|
||||
case TelephonyManager.NETWORK_TYPE_1xRTT:
|
||||
case TelephonyManager.NETWORK_TYPE_IDEN:
|
||||
netType = NetworkType.NETWORK_2G;
|
||||
break;
|
||||
default:
|
||||
String subtypeName = info.getSubtypeName();
|
||||
if (subtypeName.equalsIgnoreCase("TD-SCDMA")
|
||||
|| subtypeName.equalsIgnoreCase("WCDMA")
|
||||
|| subtypeName.equalsIgnoreCase("CDMA2000")) {
|
||||
netType = NetworkType.NETWORK_3G;
|
||||
} else {
|
||||
netType = NetworkType.NETWORK_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if(info.getType()==ConnectivityManager.TYPE_ETHERNET){
|
||||
netType = NetworkType.NETWORK_ETHERNET;
|
||||
} else {
|
||||
netType = NetworkType.NETWORK_UNKNOWN;
|
||||
}
|
||||
}
|
||||
return netType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean isActive(Context context) {
|
||||
NetworkInfo info = getActiveNetworkInfo(context);
|
||||
if (info != null && info.isAvailable() && info.isConnected()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
530
nebula-sdk/src/main/java/com/android/util/PakageInstallUtil.java
Normal file
530
nebula-sdk/src/main/java/com/android/util/PakageInstallUtil.java
Normal file
@@ -0,0 +1,530 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageInstaller;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 执行系统更新
|
||||
*/
|
||||
public class PakageInstallUtil {
|
||||
|
||||
private static final String TAG = "INSTALL";
|
||||
|
||||
/**
|
||||
* 检测app是否安装
|
||||
*/
|
||||
public static boolean checkAppUpdate(Context context, String packageName, int versionCode) {
|
||||
|
||||
try {
|
||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||
|
||||
if (packageInfo != null) {
|
||||
if (packageInfo.versionCode < versionCode) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测app是否安装
|
||||
*/
|
||||
public static boolean checkAppUpdate(Context context, String packageName) {
|
||||
|
||||
try {
|
||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||
|
||||
if (packageInfo != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检测app是否需要更新
|
||||
*/
|
||||
public static boolean checkAppInstall(Context context, String packageName, int versionCode) {
|
||||
|
||||
try {
|
||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||
|
||||
if (packageInfo != null) {
|
||||
LogUtils.e("postServerAppUpdate--->checkAppInstall packageInfo is not null,versionCode:" + packageInfo.versionCode + "--->" + versionCode);
|
||||
if (packageInfo.versionCode >= versionCode) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("postServerAppUpdate--->checkAppInstall packageInfo is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
LogUtils.e("postServerAppUpdate--->checkAppInstall exception:" + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String runCommand(Context context, String apkPath) {
|
||||
Process process = null;
|
||||
String result = "";
|
||||
DataOutputStream os = null;
|
||||
DataInputStream is = null;
|
||||
//"pm", "install","-i","com.example.startservices", "-r", apkPath
|
||||
try {
|
||||
String packagename = context.getPackageName();
|
||||
process = Runtime.getRuntime().exec("su");
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
is = new DataInputStream(process.getInputStream());
|
||||
os.writeBytes("pm install -i " + packagename + " -r " + apkPath + "\n");
|
||||
os.writeBytes("exit\n");
|
||||
os.flush();
|
||||
String line = null;
|
||||
while ((line = is.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
process.waitFor();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static String runCommandSDK24(Context context, String filePath) {
|
||||
int result = -1;
|
||||
try {
|
||||
LogUtils.e("postServerAppUpdate--->AndroidSDKVersion runCommandSDK24:" + getAndroidSDKVersion());
|
||||
String[] args = {"pm", "install", "-i ", context.getPackageName(), "-r", filePath};
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(args);
|
||||
|
||||
Process process = null;
|
||||
BufferedReader successResult = null;
|
||||
BufferedReader errorResult = null;
|
||||
StringBuilder successMsg = new StringBuilder();
|
||||
StringBuilder errorMsg = new StringBuilder();
|
||||
|
||||
try {
|
||||
process = processBuilder.start();
|
||||
successResult = new BufferedReader(new InputStreamReader(
|
||||
process.getInputStream()));
|
||||
errorResult = new BufferedReader(new InputStreamReader(
|
||||
process.getErrorStream()));
|
||||
String s;
|
||||
|
||||
while ((s = successResult.readLine()) != null) {
|
||||
successMsg.append(s);
|
||||
}
|
||||
|
||||
while ((s = errorResult.readLine()) != null) {
|
||||
errorMsg.append(s);
|
||||
}
|
||||
Log.d(TAG, "s : " + s);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (successResult != null) {
|
||||
successResult.close();
|
||||
}
|
||||
if (errorResult != null) {
|
||||
errorResult.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
if (successMsg != null && (successMsg.toString().contains("Success")
|
||||
|| successMsg.toString().contains("success"))) {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return successMsg.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
public static String runKillCommand(Context context, String pid) {
|
||||
LogUtils.e("postServerAppUpdate--->AndroidSDKVersion runCommand:" + getAndroidSDKVersion());
|
||||
Process process = null;
|
||||
String result = "";
|
||||
DataOutputStream os = null;
|
||||
DataInputStream is = null;
|
||||
//"pm", "install","-i","com.example.startservices", "-r", apkPath
|
||||
try {
|
||||
process = Runtime.getRuntime().exec("su");
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
is = new DataInputStream(process.getInputStream());
|
||||
os.writeBytes("kill " + pid + "\n");
|
||||
os.writeBytes("exit\n");
|
||||
os.flush();
|
||||
String line = null;
|
||||
while ((line = is.readLine()) != null) {
|
||||
result += line;
|
||||
}
|
||||
process.waitFor();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// public static boolean executeAppInstall(Context context,String apkPath) {
|
||||
// boolean result = false;
|
||||
// StringBuilder successMsg = new StringBuilder();
|
||||
// String text = "";
|
||||
// if(getAndroidSDKVersion()>Build.VERSION_CODES.N){
|
||||
// text = runCommand(context, apkPath);
|
||||
// }else {
|
||||
// text = runCommandSDK24(context, apkPath);
|
||||
// }
|
||||
//
|
||||
// successMsg.append(text);
|
||||
// successMsg.append(" install msg");
|
||||
//
|
||||
// if(!"".equals(successMsg)&&successMsg.toString().toLowerCase().contains("success")){
|
||||
// //安装成功
|
||||
// result = true;
|
||||
// Log.e("install","install Success message is ==>" +successMsg.toString());
|
||||
// }else {
|
||||
// result = false;
|
||||
// Log.e("install","install fail message is ==>" +successMsg.toString());
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
|
||||
public static boolean silentInstall(Context context, String mApkFilePath) {
|
||||
File file = new File(mApkFilePath);
|
||||
try {
|
||||
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
|
||||
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
||||
params.setSize(file.length());
|
||||
int sessionId = packageInstaller.createSession(params);
|
||||
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
|
||||
InputStream in = new FileInputStream(file);
|
||||
OutputStream out = session.openWrite("CocosDemo", 0, file.length());
|
||||
byte[] buffer = new byte[65536];
|
||||
int c;
|
||||
while ((c = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, c);
|
||||
}
|
||||
session.fsync(out);
|
||||
in.close();
|
||||
out.close();
|
||||
|
||||
LogUtils.e("postServerAppUpdate--->android.os.Build.VERSION.SDK_INT:" + android.os.Build.VERSION.SDK_INT);
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
|
||||
session.commit(PendingIntent.getBroadcast(context, sessionId,
|
||||
new Intent("android.intent.action.PACKAGE_ADDED"), PendingIntent.FLAG_IMMUTABLE).getIntentSender());
|
||||
} else {
|
||||
session.commit(PendingIntent.getBroadcast(context, sessionId,
|
||||
new Intent("android.intent.action.PACKAGE_ADDED"), 0).getIntentSender());
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static boolean executeAppUnInstall(Context context ,String packageName){
|
||||
// boolean result = false;
|
||||
// Process process = null;
|
||||
// BufferedReader successResult = null;
|
||||
// BufferedReader errorResult = null;
|
||||
// StringBuilder successMsg = new StringBuilder();
|
||||
// StringBuilder errorMsg = new StringBuilder();
|
||||
// try {
|
||||
// Log.e("install","uninstall message is ==>" + packageName );
|
||||
// process = new ProcessBuilder("pm", "uninstall","-i",context.getPackageName(), "-k",packageName).start();
|
||||
// successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
// errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
// String s;
|
||||
// while ((s = successResult.readLine()) != null) {
|
||||
// successMsg.append(s);
|
||||
// }
|
||||
// while ((s = errorResult.readLine()) != null) {
|
||||
// errorMsg.append(s);
|
||||
// }
|
||||
//
|
||||
// if(!"".equals(successMsg)&&successMsg.toString().toLowerCase().contains("sucess")){
|
||||
// //安装成功
|
||||
// Log.e("install","uninstall successMsg is ==>" +successMsg.toString());
|
||||
// result = true;
|
||||
//
|
||||
// }else {
|
||||
// Log.e("install","uninstall failMsg is ==>" +errorMsg.toString());
|
||||
// result = false;
|
||||
// }
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
// public void deleteApp(Context context,String appPackage) {
|
||||
// PackageManager pm = context.getPackageManager();
|
||||
// try {
|
||||
// Class<?>[] uninstalltypes = new Class[] {String.class, IPackageDeleteObserver.class, int.class};
|
||||
// Method uninstallmethod = pm.getClass().getMethod("deletePackage", uninstalltypes);
|
||||
// uninstallmethod.invoke(pm, appPackage, new PackageDeletedObserver(), 0);
|
||||
// } catch (NoSuchMethodException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalAccessException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// public static boolean executeAppUnInstall(String packageName){
|
||||
// boolean result = false;
|
||||
// try {
|
||||
//
|
||||
// // 申请su权限
|
||||
// Runtime.getRuntime().exec("su");
|
||||
// // 执行pm install命令
|
||||
// String command = "pm uninstall -k " + packageName + "\n";
|
||||
// LogUtils.loge("executeAppUnInstall==>"+command);
|
||||
// Process process = Runtime.getRuntime().exec(command);
|
||||
// BufferedReader errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
// String msg = "";
|
||||
// String line;
|
||||
//
|
||||
// // 读取命令的执行结果
|
||||
// while ((line = errorStream.readLine()) != null) {
|
||||
// msg += line;
|
||||
// }
|
||||
// LogUtils.loge( "uninstall msg is " + msg);
|
||||
// // 如果执行结果中包含Failure字样就认为是安装失败,否则就认为安装成功
|
||||
// if (!msg.contains("Failure")) {
|
||||
// result = true;
|
||||
// }
|
||||
//
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// LogUtils.logd( "install msg is " + e.getMessage());
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
public static void executeAppUnInstall(Context context, String packageName) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
executeAppUnInstall29(context, packageName);
|
||||
} else {
|
||||
executeAppUnInstall24(context, packageName);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void executeAppUnInstall29(Context context, String packageName) {
|
||||
Log.i("----ik", "-------------------del-----");
|
||||
|
||||
try {
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
PendingIntent sender = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PackageInstaller mPackageInstaller = context.getPackageManager().getPackageInstaller();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
mPackageInstaller.uninstallExistingPackage(packageName, sender.getIntentSender());
|
||||
} else {
|
||||
mPackageInstaller.uninstall(packageName, sender.getIntentSender());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void executeAppUnInstall24(Context context, String packageName) {
|
||||
try {
|
||||
|
||||
PackageManager mPackageManager = context.getPackageManager();
|
||||
Method method = mPackageManager
|
||||
.getClass()
|
||||
.getMethod(
|
||||
"deletePackage",
|
||||
String.class,
|
||||
Class.forName("android.content.pm.IPackageDeleteObserver"),
|
||||
int.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(mPackageManager, packageName,
|
||||
null, 0x00000002);
|
||||
/**
|
||||
* 0x00000002 to indicate that you want the package
|
||||
* deleted for all users.
|
||||
*/
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void resetBoot() {
|
||||
try {
|
||||
|
||||
String command = "reboot " + "\n";
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int getAndroidSDKVersion() {
|
||||
int version = 0;
|
||||
try {
|
||||
version = Integer.valueOf(Build.VERSION.SDK);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("WrongConstant")
|
||||
public static List<Map<String, String>> findAllApps(Context context) {
|
||||
|
||||
PackageManager manager = context.getPackageManager();
|
||||
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
|
||||
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
|
||||
List<ResolveInfo> allApps = manager.queryIntentActivities(mainIntent, PackageManager.INSTALL_REASON_UNKNOWN);
|
||||
List<Map<String, String>> appInfoList = new ArrayList<>();
|
||||
for (int i = 0; i < allApps.size(); i++) {
|
||||
ResolveInfo info = allApps.get(i);
|
||||
// if((packageInfo.applicationInfo.flags& ApplicationInfo.FLAG_SYSTEM)<=0){
|
||||
Map<String, String> appMap = new HashMap<>();
|
||||
|
||||
try {
|
||||
String packageName = info.activityInfo.packageName;
|
||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||
String versionMessage = packageInfo.versionName + "-" + packageInfo.versionCode;
|
||||
String label = packageInfo.applicationInfo.loadLabel(context.getPackageManager()).toString();
|
||||
appMap.put("appName", label);
|
||||
appMap.put("packageName", info.activityInfo.packageName);
|
||||
appMap.put("versionInfo", versionMessage);
|
||||
appInfoList.add(appMap);
|
||||
LogUtils.e("postServerAppUpdate--->" + GsonUtil.GsonString(appMap));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
return appInfoList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
423
nebula-sdk/src/main/java/com/android/util/RKDeviceUtil.java
Normal file
423
nebula-sdk/src/main/java/com/android/util/RKDeviceUtil.java
Normal file
@@ -0,0 +1,423 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class RKDeviceUtil {
|
||||
|
||||
public static String getDeviceId() {
|
||||
// String uuid =null;
|
||||
// TelephonyManager TelephonyMgr = (TelephonyManager) activity.getSystemService(TELEPHONY_SERVICE);
|
||||
// if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED) {
|
||||
// PermissionChecker.getInstance().requestReadPhoneState(activity);
|
||||
// return uuid;
|
||||
// }
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// /* LogUtils.e("$$$$$$$$------Build.getSerial()="+Build.getSerial());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getSimSerialNumber()="+TelephonyMgr.getSimSerialNumber());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getImei()="+TelephonyMgr.getImei());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getSubscriberId()="+TelephonyMgr.getSubscriberId());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getLine1Number()="+TelephonyMgr.getLine1Number());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getDeviceId()="+TelephonyMgr.getDeviceId());
|
||||
// LogUtils.e("$$$$$$$$------UUID="+UUID.randomUUID().toString());*/
|
||||
// uuid = Build.getSerial();//序列号
|
||||
// if(isEmpty(uuid)){//IMEI:国际移动设备识别码
|
||||
// uuid = TelephonyMgr.getImei();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//IMEI:国际移动设备识别码
|
||||
// uuid = TelephonyMgr.getDeviceId();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//ICCID:集成电路卡识别码(固化在手机SIM 卡中)
|
||||
// uuid = TelephonyMgr.getSimSerialNumber();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//IMSI:国际移动用户识别码(sim卡运营商信息)
|
||||
// uuid = TelephonyMgr.getSubscriberId();
|
||||
// }
|
||||
// if(isEmpty(uuid)){
|
||||
// uuid = TelephonyMgr.getLine1Number();
|
||||
// }
|
||||
// //UUID.randomUUID().toString();
|
||||
// }else {
|
||||
// Class<?> c = null;
|
||||
// try {
|
||||
// c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// uuid = (String) get.invoke(c, "ro.serialno");
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (NoSuchMethodException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalAccessException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// if (isEmpty(uuid)){
|
||||
// UUID.randomUUID().toString();
|
||||
// }
|
||||
return "";
|
||||
}
|
||||
|
||||
// public static String getSerialNumber(){
|
||||
// String serial = null;
|
||||
// try {
|
||||
// if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1){//7.11+
|
||||
// serial = Build.getSerial();
|
||||
// LogUtils.e("===========7.11+=======================");
|
||||
// }else{
|
||||
// Class<?> c;
|
||||
// c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// serial = (String) get.invoke(c, "ro.serialno");
|
||||
// LogUtils.e("===========7.11-======================");
|
||||
// }
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (NoSuchMethodException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (SecurityException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalAccessException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalArgumentException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if (serial == null){
|
||||
// //serial = "000000";
|
||||
// }
|
||||
// return serial;
|
||||
// }
|
||||
|
||||
|
||||
public static String getSerialNum(Context context) {
|
||||
String serial = null;
|
||||
// try {
|
||||
// Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// serial = (String) get.invoke(c, "ro.serialno");
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
|
||||
|
||||
// if (serial == null || serial.isEmpty() || serial.length() < 5) {
|
||||
// serial = getWifiMacAddress(context);
|
||||
// if (serial == null || serial.isEmpty()) serial = getBtMacAddress(context);
|
||||
// if (serial == null || serial.isEmpty()) serial = "serial No. error ";
|
||||
// }
|
||||
// return serial;
|
||||
return "BBBBBBBB";
|
||||
}
|
||||
|
||||
public static boolean isDeviceExist(Context context, String mac) {
|
||||
String deviceId = getEthernetMac();
|
||||
if (deviceId.equals(mac)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getEthernetMac() {
|
||||
String ethernetMac = null;
|
||||
try {
|
||||
NetworkInterface NIC = NetworkInterface.getByName("eth0");
|
||||
byte[] buf = NIC.getHardwareAddress();
|
||||
ethernetMac = byteHexString(buf);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if(ethernetMac==null){ //获取不到以太网mac时就获取wifi mac
|
||||
ethernetMac = getWifiMac();
|
||||
}
|
||||
// return "EC:2E:CC:81:0D:62"; //for test
|
||||
return ethernetMac;
|
||||
}
|
||||
|
||||
|
||||
public static String getWifiMac(){
|
||||
String wifiMac = null;
|
||||
try {
|
||||
NetworkInterface NIC = NetworkInterface.getByName("wlan0");
|
||||
byte[] buf = NIC.getHardwareAddress();
|
||||
wifiMac = byteHexString(buf);
|
||||
} catch (SocketException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return wifiMac;
|
||||
}
|
||||
|
||||
// public static String getWifiMac(){
|
||||
// String wifiMac = null;
|
||||
//
|
||||
// String line = null;
|
||||
// String cmd = "cat /sys/class/net/wlan0/address";
|
||||
// try {
|
||||
// Process p = Runtime.getRuntime().exec(cmd);
|
||||
//// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
// BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
//// String error = null;
|
||||
//// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
//// Log.d("===========", "========error="+error);
|
||||
//// }
|
||||
// while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
// wifiMac = line;
|
||||
// }
|
||||
// } catch (IOException ioe) {
|
||||
// ioe.printStackTrace();
|
||||
// }
|
||||
// return wifiMac;
|
||||
// }
|
||||
|
||||
/*
|
||||
* 字节数组转16进制字符串
|
||||
*/
|
||||
public static String byteHexString(byte[] array) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for(int i=0;i<array.length;i++){
|
||||
String hex = Integer.toHexString(array[i] & 0xFF);
|
||||
if (hex.length() == 1) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
if(i<array.length-1){
|
||||
builder.append(hex+":");
|
||||
}else {
|
||||
builder.append(hex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return builder.toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
public static String getBrand(){
|
||||
return Build.BRAND;
|
||||
}
|
||||
|
||||
public static String getBuild(){
|
||||
return Build.FINGERPRINT;
|
||||
}
|
||||
|
||||
public static String getDevice(){
|
||||
|
||||
return Build.DEVICE;
|
||||
}
|
||||
public static String getCpu(){
|
||||
|
||||
return getCPUinfo();
|
||||
}
|
||||
|
||||
public static String getDevicecpuId(Context context){
|
||||
|
||||
// String cpuInfo =SharedPreferencesUtil.getSharePrefrencesString(context,SharedPreferencesUtil.DEVICE_CPUID);
|
||||
// if(cpuInfo==null||"".equals(cpuInfo)){
|
||||
// cpuInfo = getCpu();
|
||||
// }
|
||||
//
|
||||
// if(cpuInfo==null||"".equals(cpuInfo)){
|
||||
// cpuInfo = createUUID();
|
||||
// SharedPreferencesUtil.setSharePrefrencesString(context,SharedPreferencesUtil.DEVICE_CPUID,cpuInfo);
|
||||
// }
|
||||
return getCpu();
|
||||
}
|
||||
|
||||
public static String getDdr(){
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getModel(){
|
||||
return Build.MODEL;
|
||||
}
|
||||
|
||||
public static String getPlatform(){
|
||||
return "rockchip";
|
||||
}
|
||||
|
||||
public static String getSystemVersion(){
|
||||
return Build.VERSION.RELEASE;
|
||||
}
|
||||
|
||||
private static String getCPUinfo() {
|
||||
String cpuAddress = "";
|
||||
String line = null;
|
||||
String cmd = "cat /proc/cpuinfo";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
if (line.contains("Serial")) {
|
||||
String[] SerialStr = line.split(":");
|
||||
if (SerialStr.length == 2) {
|
||||
String mSerial = SerialStr[1];
|
||||
cpuAddress = mSerial.trim();
|
||||
return cpuAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return cpuAddress;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统ram大小
|
||||
* @return
|
||||
*/
|
||||
public static String getSysteTotalMemorySize(Context context){
|
||||
//获得ActivityManager服务的对象
|
||||
ActivityManager mActivityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
//获得MemoryInfo对象
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo() ;
|
||||
//获得系统可用内存,保存在MemoryInfo对象上
|
||||
mActivityManager.getMemoryInfo(memoryInfo) ;
|
||||
long memSize = memoryInfo.totalMem ;
|
||||
//字符类型转换
|
||||
String availMemStr = formateFileSize(memSize,true);
|
||||
return availMemStr ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统rom大小
|
||||
* @return
|
||||
*/
|
||||
public static String getSysteTotalStorageSize(Context context){
|
||||
//获得ActivityManager服务的对象
|
||||
String availMemStr = null;
|
||||
try {
|
||||
// final StorageManager storageManager = (StorageManager)context.getSystemService(Context.STORAGE_SERVICE);
|
||||
// storageManager.getStorageVolumes()
|
||||
|
||||
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
|
||||
long totalSize = statFs.getTotalBytes();
|
||||
//字符类型转换
|
||||
availMemStr = formateFileSize( totalSize,true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return availMemStr ;
|
||||
}
|
||||
|
||||
|
||||
// public static String getSysteTotalStorageSize(Context context) {
|
||||
// String dir = "/proc/meminfo";
|
||||
// try {
|
||||
// FileReader fr = new FileReader(dir);
|
||||
// BufferedReader br = new BufferedReader(fr, 2048);
|
||||
// String memoryLine = br.readLine();
|
||||
// String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
|
||||
// br.close();
|
||||
// return formateFileSize(Integer.parseInt(subMemoryLine.replaceAll("\\D+", "")) * 1024l,true);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return formateFileSize(0, true);
|
||||
// }
|
||||
|
||||
public static String formateFileSize(long size, boolean isInteger) {
|
||||
DecimalFormat df = isInteger ? new DecimalFormat("#0") : new DecimalFormat("#0.#");
|
||||
String fileSizeString = "0M";
|
||||
if (size < 1024 && size > 0) {
|
||||
fileSizeString = df.format((double) size) + "B";
|
||||
} else if (size < 1024 * 1024) {
|
||||
fileSizeString = df.format((double) size / 1024) + "K";
|
||||
} else if (size < 1024 * 1024 * 1024) {
|
||||
fileSizeString = df.format((double) size / (1024 * 1024)) + "M";
|
||||
} else {
|
||||
fileSizeString = df.format((double) size / (1024 * 1024 * 1024)) + "G";
|
||||
}
|
||||
return fileSizeString;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 获取本机默认的launcher
|
||||
* @return
|
||||
*/
|
||||
public static String getDefaultLauncherPackageName(Context context) {
|
||||
final UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
long time = System.currentTimeMillis();
|
||||
List<UsageStats> appList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time);
|
||||
|
||||
if (appList != null && appList.size() > 0) {
|
||||
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<>();
|
||||
for (UsageStats usageStats : appList) {
|
||||
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
|
||||
}
|
||||
if (mySortedMap != null && !mySortedMap.isEmpty()) {
|
||||
return mySortedMap.get(mySortedMap.lastKey()).getPackageName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getLauncherPackageName(Context context) {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
final List<ResolveInfo> resList = context.getPackageManager().queryIntentActivities(intent, 0);
|
||||
String tmp="";
|
||||
for (ResolveInfo res:resList) {
|
||||
if (res.activityInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if("com.android.settings".equals(res.activityInfo.packageName)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if("com.android.tv.settings".equals(res.activityInfo.packageName)){
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp+=res.activityInfo.packageName+",";
|
||||
}
|
||||
return "".equals(tmp)?null:tmp;
|
||||
}
|
||||
|
||||
|
||||
private static String createUUID(){
|
||||
String timems =System.currentTimeMillis()+"";
|
||||
String tmp = timems+"-"+ UUID.randomUUID().toString();
|
||||
return tmp.replace("-","").substring(0,31);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
public class SharedPreferencesUtil {
|
||||
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private static final String SHARE_NAME = "config";
|
||||
/**
|
||||
* 参数名 time
|
||||
*/
|
||||
public static final String CONFIG_PARAM_TIME = "config_param_time";
|
||||
public static final String CONFIG_PARAM_LAST_TIME = "CONFIG_PARAM_LAST_TIME";
|
||||
|
||||
/**
|
||||
* 域名
|
||||
*/
|
||||
public static final String CONFIG_DOMAINNAME = "CONFIG_DOMAINNAME";
|
||||
public static final String CONFIG_TEST_DOMAINNAME = "CONFIG_TEST_DOMAINNAME";
|
||||
|
||||
|
||||
public static String getSharePrefrencesString(Context context, String key) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
return sharedPreferences.getString(key, null);
|
||||
}
|
||||
|
||||
public static void setSharePrefrencesString(Context context, String key, String value) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putString(key, value);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static void setSharePrefrencesInteger(Context context, String key, int value) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putInt(key, value);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static void setSharePrefrencesLong(Context context, String key, Long value) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putLong(key, value);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static void setSharePrefrencesBoolean(Context context, String key, boolean value) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putBoolean(key, value);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static int getSharePrefrencesInteger(Context context, String key) {
|
||||
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
return sharedPreferences.getInt(key, 0);
|
||||
}
|
||||
|
||||
|
||||
public static long getSharePrefrencesLong(Context context, String key) {
|
||||
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
return sharedPreferences.getLong(key, 0);
|
||||
// return 0;
|
||||
}
|
||||
|
||||
public static boolean getSharePrefrencesBoolean(Context context, String key) {
|
||||
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(SHARE_NAME, 0);
|
||||
return sharedPreferences.getBoolean(key, false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
1034
nebula-sdk/src/main/java/com/android/util/StringUtil.java
Normal file
1034
nebula-sdk/src/main/java/com/android/util/StringUtil.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,549 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout.LayoutParams;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Class to manage status and navigation bar tint effects when using KitKat
|
||||
* translucent system UI modes.
|
||||
* 避免沉侵式状态栏和底部导航栏冲突的类
|
||||
*/
|
||||
public class SystemBarTintManager {
|
||||
|
||||
static {
|
||||
// Android allows a system property to override the presence of the navigation bar.
|
||||
// Used by the emulator.
|
||||
// See https://github.com/android/platform_frameworks_base/blob/master/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#L1076
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
try {
|
||||
Class c = Class.forName("android.os.SystemProperties");
|
||||
Method m = c.getDeclaredMethod("get", String.class);
|
||||
m.setAccessible(true);
|
||||
sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
|
||||
} catch (Throwable e) {
|
||||
sNavBarOverride = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The default system bar tint color value.
|
||||
*/
|
||||
public static final int DEFAULT_TINT_COLOR = 0x99000000;
|
||||
|
||||
private static String sNavBarOverride;
|
||||
|
||||
private final SystemBarConfig mConfig;
|
||||
private boolean mStatusBarAvailable;
|
||||
private boolean mNavBarAvailable;
|
||||
private boolean mStatusBarTintEnabled;
|
||||
private boolean mNavBarTintEnabled;
|
||||
private View mStatusBarTintView;
|
||||
private View mNavBarTintView;
|
||||
|
||||
/**
|
||||
* Constructor. Call this in the host activity onCreate method after its
|
||||
* content view has been set. You should always create new instances when
|
||||
* the host activity is recreated.
|
||||
*
|
||||
* @param activity The host activity.
|
||||
*/
|
||||
@TargetApi(19)
|
||||
@SuppressWarnings("ResourceType")
|
||||
public SystemBarTintManager(Activity activity) {
|
||||
|
||||
Window win = activity.getWindow();
|
||||
ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// check theme attrs
|
||||
int[] attrs = {android.R.attr.windowTranslucentStatus,
|
||||
android.R.attr.windowTranslucentNavigation};
|
||||
TypedArray a = activity.obtainStyledAttributes(attrs);
|
||||
try {
|
||||
mStatusBarAvailable = a.getBoolean(0, false);
|
||||
mNavBarAvailable = a.getBoolean(1, false);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
// check window flags
|
||||
WindowManager.LayoutParams winParams = win.getAttributes();
|
||||
int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||
if ((winParams.flags & bits) != 0) {
|
||||
mStatusBarAvailable = true;
|
||||
}
|
||||
bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
|
||||
if ((winParams.flags & bits) != 0) {
|
||||
mNavBarAvailable = true;
|
||||
}
|
||||
}
|
||||
|
||||
mConfig = new SystemBarConfig(activity, mStatusBarAvailable, mNavBarAvailable);
|
||||
// device might not have virtual navigation keys
|
||||
if (!mConfig.hasNavigtionBar()) {
|
||||
mNavBarAvailable = false;
|
||||
}
|
||||
|
||||
if (mStatusBarAvailable) {
|
||||
setupStatusBarView(activity, decorViewGroup);
|
||||
}
|
||||
if (mNavBarAvailable) {
|
||||
setupNavBarView(activity, decorViewGroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable tinting of the system status bar.
|
||||
* <p>
|
||||
* If the platform is running Jelly Bean or earlier, or translucent system
|
||||
* UI modes have not been enabled in either the theme or via window flags,
|
||||
* then this method does nothing.
|
||||
*
|
||||
* @param enabled True to enable tinting, false to disable it (default).
|
||||
*/
|
||||
public void setStatusBarTintEnabled(boolean enabled) {
|
||||
mStatusBarTintEnabled = enabled;
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable tinting of the system navigation bar.
|
||||
* <p>
|
||||
* If the platform does not have soft navigation keys, is running Jelly Bean
|
||||
* or earlier, or translucent system UI modes have not been enabled in either
|
||||
* the theme or via window flags, then this method does nothing.
|
||||
*
|
||||
* @param enabled True to enable tinting, false to disable it (default).
|
||||
*/
|
||||
public void setNavigationBarTintEnabled(boolean enabled) {
|
||||
mNavBarTintEnabled = enabled;
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified color tint to all system UI bars.
|
||||
*
|
||||
* @param color The color of the background tint.
|
||||
*/
|
||||
public void setTintColor(int color) {
|
||||
setStatusBarTintColor(color);
|
||||
setNavigationBarTintColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable or color resource to all system UI bars.
|
||||
*
|
||||
* @param res The identifier of the resource.
|
||||
*/
|
||||
public void setTintResource(int res) {
|
||||
setStatusBarTintResource(res);
|
||||
setNavigationBarTintResource(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable to all system UI bars.
|
||||
*
|
||||
* @param drawable The drawable to use as the background, or null to remove it.
|
||||
*/
|
||||
public void setTintDrawable(Drawable drawable) {
|
||||
setStatusBarTintDrawable(drawable);
|
||||
setNavigationBarTintDrawable(drawable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified alpha to all system UI bars.
|
||||
*
|
||||
* @param alpha The alpha to use
|
||||
*/
|
||||
public void setTintAlpha(float alpha) {
|
||||
setStatusBarAlpha(alpha);
|
||||
setNavigationBarAlpha(alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified color tint to the system status bar.
|
||||
*
|
||||
* @param color The color of the background tint.
|
||||
*/
|
||||
public void setStatusBarTintColor(int color) {
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable or color resource to the system status bar.
|
||||
*
|
||||
* @param res The identifier of the resource.
|
||||
*/
|
||||
public void setStatusBarTintResource(int res) {
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setBackgroundResource(res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable to the system status bar.
|
||||
*
|
||||
* @param drawable The drawable to use as the background, or null to remove it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setStatusBarTintDrawable(Drawable drawable) {
|
||||
if (mStatusBarAvailable) {
|
||||
mStatusBarTintView.setBackgroundDrawable(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified alpha to the system status bar.
|
||||
*
|
||||
* @param alpha The alpha to use
|
||||
*/
|
||||
@TargetApi(11)
|
||||
public void setStatusBarAlpha(float alpha) {
|
||||
if (mStatusBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mStatusBarTintView.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified color tint to the system navigation bar.
|
||||
*
|
||||
* @param color The color of the background tint.
|
||||
*/
|
||||
public void setNavigationBarTintColor(int color) {
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable or color resource to the system navigation bar.
|
||||
*
|
||||
* @param res The identifier of the resource.
|
||||
*/
|
||||
public void setNavigationBarTintResource(int res) {
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setBackgroundResource(res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified drawable to the system navigation bar.
|
||||
*
|
||||
* @param drawable The drawable to use as the background, or null to remove it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setNavigationBarTintDrawable(Drawable drawable) {
|
||||
if (mNavBarAvailable) {
|
||||
mNavBarTintView.setBackgroundDrawable(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified alpha to the system navigation bar.
|
||||
*
|
||||
* @param alpha The alpha to use
|
||||
*/
|
||||
@TargetApi(11)
|
||||
public void setNavigationBarAlpha(float alpha) {
|
||||
if (mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mNavBarTintView.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system bar configuration.
|
||||
*
|
||||
* @return The system bar configuration for the current device configuration.
|
||||
*/
|
||||
public SystemBarConfig getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is tinting enabled for the system status bar?
|
||||
*
|
||||
* @return True if enabled, False otherwise.
|
||||
*/
|
||||
public boolean isStatusBarTintEnabled() {
|
||||
return mStatusBarTintEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is tinting enabled for the system navigation bar?
|
||||
*
|
||||
* @return True if enabled, False otherwise.
|
||||
*/
|
||||
public boolean isNavBarTintEnabled() {
|
||||
return mNavBarTintEnabled;
|
||||
}
|
||||
|
||||
private void setupStatusBarView(Context context, ViewGroup decorViewGroup) {
|
||||
mStatusBarTintView = new View(context);
|
||||
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getStatusBarHeight());
|
||||
params.gravity = Gravity.TOP;
|
||||
if (mNavBarAvailable && !mConfig.isNavigationAtBottom()) {
|
||||
params.rightMargin = mConfig.getNavigationBarWidth();
|
||||
}
|
||||
mStatusBarTintView.setLayoutParams(params);
|
||||
mStatusBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
|
||||
mStatusBarTintView.setVisibility(View.GONE);
|
||||
decorViewGroup.addView(mStatusBarTintView);
|
||||
}
|
||||
|
||||
private void setupNavBarView(Context context, ViewGroup decorViewGroup) {
|
||||
mNavBarTintView = new View(context);
|
||||
LayoutParams params;
|
||||
if (mConfig.isNavigationAtBottom()) {
|
||||
params = new LayoutParams(LayoutParams.MATCH_PARENT, mConfig.getNavigationBarHeight());
|
||||
params.gravity = Gravity.BOTTOM;
|
||||
} else {
|
||||
params = new LayoutParams(mConfig.getNavigationBarWidth(), LayoutParams.MATCH_PARENT);
|
||||
params.gravity = Gravity.RIGHT;
|
||||
}
|
||||
mNavBarTintView.setLayoutParams(params);
|
||||
mNavBarTintView.setBackgroundColor(DEFAULT_TINT_COLOR);
|
||||
mNavBarTintView.setVisibility(View.GONE);
|
||||
decorViewGroup.addView(mNavBarTintView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class which describes system bar sizing and other characteristics for the current
|
||||
* device configuration.
|
||||
*/
|
||||
public static class SystemBarConfig {
|
||||
|
||||
private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";
|
||||
private static final String NAV_BAR_HEIGHT_RES_NAME = "navigation_bar_height";
|
||||
private static final String NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME = "navigation_bar_height_landscape";
|
||||
private static final String NAV_BAR_WIDTH_RES_NAME = "navigation_bar_width";
|
||||
private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";
|
||||
|
||||
private final boolean mTranslucentStatusBar;
|
||||
private final boolean mTranslucentNavBar;
|
||||
private final int mStatusBarHeight;
|
||||
private final int mActionBarHeight;
|
||||
private final boolean mHasNavigationBar;
|
||||
private final int mNavigationBarHeight;
|
||||
private final int mNavigationBarWidth;
|
||||
private final boolean mInPortrait;
|
||||
private final float mSmallestWidthDp;
|
||||
|
||||
private SystemBarConfig(Activity activity, boolean translucentStatusBar, boolean traslucentNavBar) {
|
||||
Resources res = activity.getResources();
|
||||
mInPortrait = (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
|
||||
mSmallestWidthDp = getSmallestWidthDp(activity);
|
||||
mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);
|
||||
mActionBarHeight = getActionBarHeight(activity);
|
||||
mNavigationBarHeight = getNavigationBarHeight(activity);
|
||||
mNavigationBarWidth = getNavigationBarWidth(activity);
|
||||
mHasNavigationBar = (mNavigationBarHeight > 0);
|
||||
mTranslucentStatusBar = translucentStatusBar;
|
||||
mTranslucentNavBar = traslucentNavBar;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private int getActionBarHeight(Context context) {
|
||||
int result = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
TypedValue tv = new TypedValue();
|
||||
context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);
|
||||
result = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private int getNavigationBarHeight(Context context) {
|
||||
Resources res = context.getResources();
|
||||
int result = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (hasNavBar(context)) {
|
||||
String key;
|
||||
if (mInPortrait) {
|
||||
key = NAV_BAR_HEIGHT_RES_NAME;
|
||||
} else {
|
||||
key = NAV_BAR_HEIGHT_LANDSCAPE_RES_NAME;
|
||||
}
|
||||
return getInternalDimensionSize(res, key);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private int getNavigationBarWidth(Context context) {
|
||||
Resources res = context.getResources();
|
||||
int result = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (hasNavBar(context)) {
|
||||
return getInternalDimensionSize(res, NAV_BAR_WIDTH_RES_NAME);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@TargetApi(14)
|
||||
private boolean hasNavBar(Context context) {
|
||||
Resources res = context.getResources();
|
||||
int resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android");
|
||||
if (resourceId != 0) {
|
||||
boolean hasNav = res.getBoolean(resourceId);
|
||||
// check override flag (see static block)
|
||||
if ("1".equals(sNavBarOverride)) {
|
||||
hasNav = false;
|
||||
} else if ("0".equals(sNavBarOverride)) {
|
||||
hasNav = true;
|
||||
}
|
||||
return hasNav;
|
||||
} else { // fallback
|
||||
return !ViewConfiguration.get(context).hasPermanentMenuKey();
|
||||
}
|
||||
}
|
||||
|
||||
private int getInternalDimensionSize(Resources res, String key) {
|
||||
int result = 0;
|
||||
int resourceId = res.getIdentifier(key, "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
result = res.getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private float getSmallestWidthDp(Activity activity) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
|
||||
} else {
|
||||
// TODO this is not correct, but we don't really care pre-kitkat
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
}
|
||||
float widthDp = metrics.widthPixels / metrics.density;
|
||||
float heightDp = metrics.heightPixels / metrics.density;
|
||||
return Math.min(widthDp, heightDp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should a navigation bar appear at the bottom of the screen in the current
|
||||
* device configuration? A navigation bar may appear on the right side of
|
||||
* the screen in certain configurations.
|
||||
*
|
||||
* @return True if navigation should appear at the bottom of the screen, False otherwise.
|
||||
*/
|
||||
public boolean isNavigationAtBottom() {
|
||||
return (mSmallestWidthDp >= 600 || mInPortrait);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the system status bar.
|
||||
*
|
||||
* @return The height of the status bar (in pixels).
|
||||
*/
|
||||
public int getStatusBarHeight() {
|
||||
return mStatusBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the action bar.
|
||||
*
|
||||
* @return The height of the action bar (in pixels).
|
||||
*/
|
||||
public int getActionBarHeight() {
|
||||
return mActionBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this device have a system navigation bar?
|
||||
*
|
||||
* @return True if this device uses soft key navigation, False otherwise.
|
||||
*/
|
||||
public boolean hasNavigtionBar() {
|
||||
return mHasNavigationBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of the system navigation bar.
|
||||
*
|
||||
* @return The height of the navigation bar (in pixels). If the device does not have
|
||||
* soft navigation keys, this will always return 0.
|
||||
*/
|
||||
public int getNavigationBarHeight() {
|
||||
return mNavigationBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the width of the system navigation bar when it is placed vertically on the screen.
|
||||
*
|
||||
* @return The width of the navigation bar (in pixels). If the device does not have
|
||||
* soft navigation keys, this will always return 0.
|
||||
*/
|
||||
public int getNavigationBarWidth() {
|
||||
return mNavigationBarWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout inset for any system UI that appears at the top of the screen.
|
||||
*
|
||||
* @param withActionBar True to include the height of the action bar, False otherwise.
|
||||
* @return The layout inset (in pixels).
|
||||
*/
|
||||
public int getPixelInsetTop(boolean withActionBar) {
|
||||
return (mTranslucentStatusBar ? mStatusBarHeight : 0) + (withActionBar ? mActionBarHeight : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout inset for any system UI that appears at the bottom of the screen.
|
||||
*
|
||||
* @return The layout inset (in pixels).
|
||||
*/
|
||||
public int getPixelInsetBottom() {
|
||||
if (mTranslucentNavBar && isNavigationAtBottom()) {
|
||||
return mNavigationBarHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout inset for any system UI that appears at the right of the screen.
|
||||
*
|
||||
* @return The layout inset (in pixels).
|
||||
*/
|
||||
public int getPixelInsetRight() {
|
||||
if (mTranslucentNavBar && !isNavigationAtBottom()) {
|
||||
return mNavigationBarWidth;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user