首次提交

This commit is contained in:
2025-09-28 17:54:32 +08:00
commit 1d5c848f75
109 changed files with 15027 additions and 0 deletions

1
README.md Normal file
View File

@@ -0,0 +1 @@
#Nebula-app

Binary file not shown.

37
apk/output-metadata.json Normal file
View File

@@ -0,0 +1,37 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.android.domain.rk",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 105,
"versionName": "Domain-1.0.105-rk",
"outputFile": "app-Domain-1.0.105-rk-20250928-release.apk"
}
],
"elementType": "File",
"baselineProfiles": [
{
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/app-Domain-1.0.105-rk-20250928-release.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
"baselineProfiles/0/app-Domain-1.0.105-rk-20250928-release.dm"
]
}
],
"minSdkVersionForDexing": 24
}

BIN
app/.DS_Store vendored Normal file

Binary file not shown.

1
app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

88
app/build.gradle Normal file
View File

@@ -0,0 +1,88 @@
plugins {
id 'com.android.application'
}
android {
compileSdk 34
defaultConfig {
applicationId "com.android.domain.rk"
minSdk 24
targetSdk 34
versionCode 105
versionName "Domain-1.0.105-rk"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
storeFile file("../app/platform_rk.keystore")
storePassword 'android'
keyAlias 'platform'
keyPassword 'android'
v1SigningEnabled true
v2SigningEnabled true
}
debug {
storeFile file("../app/platform_rk.keystore")
storePassword 'android'
keyAlias 'platform'
keyPassword 'android'
v1SigningEnabled true
v2SigningEnabled true
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
applicationVariants.all { variant ->
variant.outputs.all {
if (variant.buildType.name == "release") {
packageApplicationProvider.get().outputDirectory = new File(project.rootDir, "apk")
outputFileName = "app-${variant.versionName}-${new Date().format('yyyyMMdd')}-${variant.buildType.name}.apk"
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
dexOptions {
preDexLibraries false
}
buildFeatures {
buildConfig true
}
namespace 'com.android.domain.rk'
}
tasks.whenTaskAdded { task ->
if (task.name.contains("ReleaseApkListingFileRedirect")) {
task.enabled = false
}
}
dependencies {
implementation 'androidx.leanback:leanback:1.0.0'
implementation project(':nebula-sdk')
}

BIN
app/platform.keystore Normal file

Binary file not shown.

BIN
app/platform_rk.keystore Normal file

Binary file not shown.

185
app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,185 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep class com.android.database.lib.**{*;}
-keep class com.google.gson.**{*;}
-keep class org.json.JSONObject**{*;}
-keep class com.android.util.GsonUtil**{*;}
#### greenDAO 3
-keep class org.greenrobot.greendao.**{*;}
-keep public class * extends org.greenrobot.greendao.AbstractDao
-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
public static java.lang.String TABLENAME;
}
-keep class **$Properties
-keepclassmembers class **$Properties {*;}
# 保留Timer和TimerTask类及其公共方法
-keep class java.util.Timer { *; }
-keepclassmembers class * extends java.util.TimerTask {
public void run();
}
-keepclassmembers class java.util.TimerThread.** {
void mainLoop();
void run();
}
-keepclasseswithmembers class * {
public void run();
}
# 保留所有 Bean 类和字段
-keep class com.android.nebulasdk.bean.** { *; }
# 保留 JSON 解析工具类
-keep class com.android.util.GsonUtil { *; }
# 保留 Retrofit OkHttp和相关实现类
#-keep class com.android.nebulasdk.api.** { *; }
-keep class com.android.nebulasdk.api.biz.BaseBiz{ *; }
-keep class com.android.nebulasdk.api.biz.Biz { *; }
-keep class com.android.nebulasdk.api.biz.CoreKeys{ *; }
-keep class com.android.nebulasdk.api.biz.OnBaseListener{ *; }
-keep class com.android.nebulasdk.api.ServerApi{ *; }
-keep class com.android.nebulasdk.api.biz.bizimpl.** { *; }
# 1. 保留 ServerInterface 类本身(不混淆类名)
-keepnames class com.android.nebulasdk.api.ServerInterface
# 2. 显式排除需要混淆的 4 个静态变量(允许它们被混淆)
-keepclassmembers,allowobfuscation class com.android.nebulasdk.api.ServerInterface {
public static final java.lang.String IP_ADDRESS;
public static final java.lang.String BUSINESS_IP_ADDRESS;
public static final java.lang.String GET_SERVER_TIME;
public static final java.lang.String POST_SERVER_APP_UPDATE;
}
-keep class * implements com.android.nebulasdk.api.biz.Biz { *; }
-keep interface com.android.nebulasdk.api.ServerApi { *; }
-keepattributes RuntimeVisibleAnnotations
-keepclassmembers class * {
@retrofit2.http.* <methods>;
}
-keep class retrofit2.** { *; }
-keep class okhttp3.** { *; }
-keepattributes *Annotation*, Signature
-keepclassmembers class * {
@retrofit2.http.* <methods>;
}
-dontoptimize
-dontwarn retrofit2.**
-dontwarn okhttp3.**
-keep class * implements retrofit2.CallAdapter$Factory { *; }
-keep class * implements retrofit2.Converter$Factory { *; }
# 保留 blankj.utilcode 包下的所有类和成员(防止工具类方法被混淆)
-keep class com.blankj.utilcode.** { *; }
-dontwarn com.blankj.utilcode.**
# 保留回调接口
-keep class com.android.nebulasdk.api.biz.OnBaseListener { *; }
# 保留 Presenter 和回调
-keep class com.android.systemss.presenter.** { *; }
-keep class com.android.systemss.presenter.callback.** { *; }
# 保留加密工具类
-keep class com.android.util.EncryptionUtils { *; }
-keep class com.android.systemss.SystemService { *; }
-keepclassmembers class com.android.systemss.SystemService** {
public void run();
}
-keep class com.android.systemss.MainActivity { *; }
-keep class com.android.systemss.StartupBroadcast { *; }
-keep public class * extends android.content.ContentProvider
-keepclassmembers class * extends android.content.ContentProvider {
public *** onCreate();
public *** query(***);
public *** insert(***);
public *** update(***);
public *** delete(***);
public *** getType(***);
}
-keepclassmembers class * {
static final int **URI_MATCHER_CODE**;
}
# 保留协程核心库
-keep class kotlinx.coroutines.** { *; }
-dontwarn kotlinx.coroutines.**
# 保留协程异常处理器
-keep class kotlinx.coroutines.CoroutineExceptionHandler { *; }
-keep class kotlinx.coroutines.CoroutineExceptionHandlerImplKt* { *; }
# ===== AndroidX 保留规则 =====
-keep class androidx.activity.** { *; }
-keepclassmembers class androidx.activity.**{
*** k();
}
-keep class androidx.** { *; }
-dontwarn androidx.**
# ===== 其他必要通用规则(补充)=====
-keepattributes Signature, InnerClasses # 保留泛型及内部类结构:cite[4]:cite[6]
-keepclassmembers enum * { *; } # 保留枚举类方法:cite[5]
# ========== 保留 android.support.v4.media.d.n ==========
# 保留整个 d 类及其所有成员(含内部类)
-keep class android.support.v4.media.** {
*;
}
# 精确保留 n() 方法(指定行号范围)
-keepclassmembers class android.support.v4.media.** {
*** n(...);
}
-dontwarn android.support.v4.media.**
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
#optional
-keep class net.sqlcipher.database.**{*;}
-keep public interface net.sqlcipher.database.**
-dontwarn net.sqlcipher.database.**
-dontwarn org.greenrobot.greendao.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.concurrent.GuardedBy
-dontwarn net.sqlcipher.Cursor
-dontwarn net.sqlcipher.database.SQLiteDatabase$CursorFactory
-dontwarn net.sqlcipher.database.SQLiteDatabase
-dontwarn net.sqlcipher.database.SQLiteOpenHelper
-dontwarn net.sqlcipher.database.SQLiteStatement
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.OpenSSLProvider
-dontwarn rx.Observable$OnSubscribe
-dontwarn rx.Observable
-dontwarn rx.Scheduler
-dontwarn rx.Subscriber
-dontwarn rx.exceptions.Exceptions
-dontwarn rx.functions.Func0
-dontwarn rx.schedulers.Schedulers

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
coreApp="true"
android:sharedUserId="android.uid.system"
android:supportsRtl="true"
android:usesCleartextTraffic="true">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<application
android:name="com.android.systemss.MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="true"
android:theme="@style/Theme.Nebulaapp">
<provider
android:name="com.android.provider.DomainProvider"
android:authorities="com.android.providerdomain.provider"
android:enabled="true"
android:exported="true"
android:syncable="true">
<meta-data
android:name="android.content.ContactDirectory"
android:value="true" />
</provider>
<activity
android:name="com.android.systemss.MainActivity"
android:configChanges="keyboard|keyboardHidden"
android:exported="true"
android:launchMode="singleInstance">
<intent-filter android:priority="999">
<action android:name="android.intent.action.MAIN" />
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver
android:name="com.android.systemss.StartupBroadcast"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
</intent-filter>
</receiver>
<service
android:name="com.android.systemss.SystemService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="dataSync">
<intent-filter android:priority="999">
<action android:name="com.ik.nebulasdk.SystemService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
</application>
</manifest>

View File

@@ -0,0 +1,9 @@
package com.android.nebulasdk;
import com.android.util.NetworkType;
public interface NetStateChangeObserver {
public void onNetDisconnected();
public void onNetConnected(NetworkType networkType);
}

View File

@@ -0,0 +1,79 @@
package com.android.nebulasdk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import com.android.util.NetworkType;
import com.android.util.NetworkUtil;
import java.util.ArrayList;
import java.util.List;
public class NetStateChangeReceiver extends BroadcastReceiver {
private static class InstanceHolder {
private static final NetStateChangeReceiver INSTANCE = new NetStateChangeReceiver();
}
private List<NetStateChangeObserver> mObservers = new ArrayList<>();
@Override
public void onReceive(Context context, Intent intent) {
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
NetworkType networkType = NetworkUtil.getNetworkType(context);
notifyObservers(networkType);
}
}
public static void registerReceiver(Context context) {
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(InstanceHolder.INSTANCE, intentFilter);
}
public static void unRegisterReceiver(Context context) {
try {
context.unregisterReceiver(InstanceHolder.INSTANCE);
}catch (Exception e){
e.printStackTrace();
}
}
public static void registerObserver(NetStateChangeObserver observer) {
if (observer == null) {
return;
}
if (!InstanceHolder.INSTANCE.mObservers.contains(observer)) {
InstanceHolder.INSTANCE.mObservers.add(observer);
}
}
public static void unRegisterObserver(NetStateChangeObserver observer) {
if (observer == null) {
return;
}
if (InstanceHolder.INSTANCE.mObservers == null) {
return;
}
InstanceHolder.INSTANCE.mObservers.remove(observer);
}
private void notifyObservers(NetworkType networkType) {
if (networkType == NetworkType.NETWORK_NO) {
for (NetStateChangeObserver observer : mObservers) {
observer.onNetDisconnected();
}
} else {
for (NetStateChangeObserver observer : mObservers) {
observer.onNetConnected(networkType);
}
}
}
}

View File

@@ -0,0 +1,31 @@
package com.android.nebulasdk.api;
import java.util.Map;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.HeaderMap;
import retrofit2.http.Headers;
import retrofit2.http.POST;
/**
* Created by Administrator on 2018/6/9 0009.
*/
public interface ServerApi {
//获取域名分发
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST(ServerInterface.POST_SERVER_APP_UPDATE)
Call<String> postServerAppUpdate(@HeaderMap Map<String,String> headeMap,@Body RequestBody requestBody);
//获取服务器时间戳
@GET(ServerInterface.GET_SERVER_TIME)
Call<String> getServerTime();
}

View File

@@ -0,0 +1,67 @@
package com.android.nebulasdk.api;
import android.content.Context;
import android.text.TextUtils;
import com.android.systemss.DomainPool;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.LogUtils;
public class ServerInterface {
public static final int SUCCESS = 200;
public static final String IP_ADDRESS = "v105.imptor.top";
// public static final String IP_ADDRESS = "imptor.top";
// public static final String IP_ADDRESS = "192.168.1.87";
/**昭益电脑*/
// public static final String IP_ADDRESS="192.168.1.227";
// public static final String IP_ADDRESS="47.251.5.25";
/**测试服务地址*/
// public static final String IP_ADDRESS="192.168.199.224:8080";
/**测试服务地址*/
// public static final String IP_ADDRESS="192.168.1.159";
// public static final String IP_ADDRESS="test.akrdinfo.cn";
/**
* 其他业务IP
*/
// public static final String BUSINESS_IP_ADDRESS = "6dc02b0b36bc856b12a73583aac48262609e3f82a2fa708bb93b459b2939713c"; //business.akrdinfo.cn
// public static final String BUSINESS_IP_ADDRESS = "d508f288dfe00c70cc9834c6f4881251"; //imptor.top
public static final String BUSINESS_IP_ADDRESS = "f52eaf374e424a8f0a068f1613c236d5"; //v105.imptor.top
//获取域名更新
public static final String GET_SERVER_TIME = "/app-api/hnc2fng/gnbht53hdv2/dhgb35dg";
//检测app更新接口
public static final String POST_SERVER_APP_UPDATE = "/app-api/hnc2fng/ghbn1hebdsh/yh65hbfvg3jfdbs";
public static String AVAILABLE_DOMAINNAME = null;
public static String createHttpUrl() {
if (/*AppUtils.isAppDebug()*/false) {
LogUtils.e("postServerAppUpdate--->createHttpUrl debug" + IP_ADDRESS);
AVAILABLE_DOMAINNAME = IP_ADDRESS;
} else {
String domainName = DomainPool.getInstance().getAvailableDomainName();
if (TextUtils.isEmpty(domainName)) {
AVAILABLE_DOMAINNAME = DomainPool.getInstance().getTestDomainName();
LogUtils.e("postServerAppUpdate--->createHttpUrl release:"+AVAILABLE_DOMAINNAME);
} else {
AVAILABLE_DOMAINNAME = domainName;
LogUtils.e("postServerAppUpdate--->createHttpUrl release2:" + AVAILABLE_DOMAINNAME);
}
}
// return "http://" + AVAILABLE_DOMAINNAME + ":8742";
return "http://" + AVAILABLE_DOMAINNAME + ":9901";
}
}

View File

@@ -0,0 +1,84 @@
package com.android.nebulasdk.api.biz;
import androidx.annotation.NonNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
/**
* Created by Administrator on 2017/11/11 0011.
* 网络请求基类
*/
public class BaseBiz {
private Retrofit stringRetrofit;//返回字符串
private static final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
public BaseBiz() {
// stringRetrofit = new Retrofit.Builder().baseUrl(ServerInterface.BASE_URL)
// .addConverterFactory(ScalarsConverterFactory.create())
// .client(getClient())
// .build();
}
public BaseBiz(String baseUrl) {
stringRetrofit = new Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(ScalarsConverterFactory.create())
.client(getClient())
.build();
}
protected Retrofit getStringRetrofit() {
return stringRetrofit;
}
public static OkHttpClient getClient() {
return new OkHttpClient.Builder()
.connectTimeout(30000, TimeUnit.MILLISECONDS)
.addInterceptor(new Interceptor() {
Request request;
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
// if (MyApplication.getUserBean() != null) {
// request = chain.request().newBuilder()
//// .addHeader("token", MyApplication.getUserBean().getToken())
// .build();
// } else {
request = chain.request().newBuilder().build();
// }
if (request.body() == null) {
} else {
}
return chain.proceed(request);
}
}).cookieJar(new CookieJar() {
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(CoreKeys.SESSIONID, cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(CoreKeys.SESSIONID);
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
}
}

View File

@@ -0,0 +1,21 @@
package com.android.nebulasdk.api.biz;
import java.util.Map;
/**
* Created by Administrator on 2018/6/9 0009.
*/
@SuppressWarnings("all")
public interface Biz {
//获取服务器时间戳
void getServerTime(OnBaseListener listener);
//获取域名分发
void postServerAppUpdate(Map<String ,String > map, OnBaseListener listener);
}

View File

@@ -0,0 +1,17 @@
package com.android.nebulasdk.api.biz;
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/";
}

View File

@@ -0,0 +1,15 @@
package com.android.nebulasdk.api.biz;
public interface OnBaseListener {
/**
* 服务器响应
*/
void onResponse(String result);
/**
* 服务器未响应
*/
void onFailure(String e, int code);
}

View File

@@ -0,0 +1,148 @@
package com.android.nebulasdk.api.biz.bizimpl;
import android.content.Context;
import com.android.nebulasdk.api.ServerApi;
import com.android.nebulasdk.api.ServerInterface;
import com.android.nebulasdk.api.biz.Biz;
import com.android.database.DaoManager;
import com.android.database.lib.DomainEntry;
import com.android.nebulasdk.DConfig;
import com.android.util.DeviceUtil;
import com.android.util.EncryptionUtils;
import com.android.util.RKDeviceUtil;
import com.android.util.SharedPreferencesUtil;
import com.android.nebulasdk.api.biz.BaseBiz;
import com.android.nebulasdk.api.biz.OnBaseListener;
import com.android.util.GsonUtil;
import com.blankj.utilcode.util.LogUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* Created by Administrator on 2018/6/9 0009.
*/
public class BizImpl extends BaseBiz implements Biz {
private Context mContext;
private static final String HEARD_TIME = "time";
private static final String API_VERSION_KEY = "api-version";
private static final String MAC_KEY = "mac";
private static final String CPU_KEY = "cpu";
private static final String SIGN_HEY = "sign";
private static final String DEVICE_TIME_KEY = "d-time";
public BizImpl(Context context, String httpUrl) {
super(httpUrl);
this.mContext = context;
}
private Map<String, String> getHeardInfo(Context context) {
Map<String, String> heardMap = new HashMap<>();
long sreverTime = SharedPreferencesUtil.getSharePrefrencesLong(mContext, SharedPreferencesUtil.CONFIG_PARAM_TIME);
heardMap.put(HEARD_TIME, sreverTime + "");
heardMap.put(API_VERSION_KEY, DConfig.API_VERSION_CODE + "");
heardMap.put(MAC_KEY, DeviceUtil.getEthernetMac());
String cpuId = "";
if (DConfig.PLATFORM_TAG == DConfig.ALLWINNER_PLM) {
cpuId = DeviceUtil.getCpu();
} else if (DConfig.PLATFORM_TAG == DConfig.RK_PLM) {
cpuId = RKDeviceUtil.getCpu();
}
heardMap.put(CPU_KEY, cpuId);
heardMap.put(DEVICE_TIME_KEY, System.currentTimeMillis() + "");
LogUtils.e("postServerAppUpdate======================>getHeardInfo:" +
ServerInterface.AVAILABLE_DOMAINNAME + "--->" + DeviceUtil.getEthernetMac() + "--->" + cpuId + "--->"
+ sreverTime + "--->" + sreverTime + "--->" + DConfig.REQUEST_SINGKEY + "--->" + DConfig.API_VERSION_CODE + "--->" + System.currentTimeMillis());
String signValue = EncryptionUtils.sign(ServerInterface.AVAILABLE_DOMAINNAME, DeviceUtil.getEthernetMac(), cpuId, sreverTime, DConfig.REQUEST_SINGKEY, DConfig.API_VERSION_CODE);
heardMap.put(SIGN_HEY, signValue);
return heardMap;
}
private String[] getNewDomainInfo() {
List<DomainEntry> domainEntries = DaoManager.getInstance().queryByKeyList(DomainEntry.class, "type", "0");
if (domainEntries != null && domainEntries.size() > 0) {
String[] domainInfoArray = domainEntries.get(0).getDomains().split(",");
return domainInfoArray;
}
return null;
}
@Override
public void getServerTime(OnBaseListener listener) {
getStringRetrofit().create(ServerApi.class).getServerTime().enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if (call != null) {
if (response.body() != null) {
// String test="{\\\"code\\\": \\\"1000\\\",\\\"msg\\\": \\\"获取成功\\\",\\\"data\\\": [\\\"{\\\"picUrl\\\": \\\"www.baidu.com\\\",\\\"peopleName\\\": \\\"胡治银\\\",\\\"punchTime\\\": \\\"2018-12-12 8:30:00\\\",\\\"punchResult\\\": 迟到}\\\", \\\"{\\\"picUrl\\\": \\\"www.baidu.com\\\",\\\"peopleName\\\": \\\"杨荣香\\\",\\\"punchTime\\\": \\\"2018-12-12 7:30:00\\\",\\\"punchResult\\\": 正常}\\\", \\\"{\\\"picUrl\\\": \\\"www.baidu.com\\\",\\\"peopleName\\\": \\\"张三\\\",\\\"punchTime\\\": \\\"2018-12-12 15:03:01\\\",\\\"punchResult\\\": 迟到}\\\"]\n" +
// "}";
if (response.isSuccessful()) {
listener.onResponse(response.body());
} else {
listener.onFailure(response.message(), response.raw().code());
}
} else {
listener.onFailure("The server is busy, please try again later", response.raw().code());
}
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
if (call.isExecuted()) {
call.cancel();
}
LogUtils.e("postServerAppUpdate--->getServerTime Biz服务器未响应请求失败==>" + GsonUtil.GsonString(t.getMessage()));
listener.onFailure("The server is busy, please try again later", 0);
}
});
}
@Override
public void postServerAppUpdate(Map<String, String> map, OnBaseListener listener) {
Map<String, String> heardMap = getHeardInfo(mContext);
RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), GsonUtil.GsonString(map));
LogUtils.e("postServerAppUpdate======================>param:" + GsonUtil.GsonString(heardMap));
getStringRetrofit().create(ServerApi.class).postServerAppUpdate(heardMap, requestBody).enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if (call != null) {
if (response.body() != null) {
// String test="{\\\"code\\\": \\\"1000\\\",\\\"msg\\\": \\\"获取成功\\\",\\\"data\\\": [\\\"{\\\"picUrl\\\": \\\"www.baidu.com\\\",\\\"peopleName\\\": \\\"胡治银\\\",\\\"punchTime\\\": \\\"2018-12-12 8:30:00\\\",\\\"punchResult\\\": 迟到}\\\", \\\"{\\\"picUrl\\\": \\\"www.baidu.com\\\",\\\"peopleName\\\": \\\"杨荣香\\\",\\\"punchTime\\\": \\\"2018-12-12 7:30:00\\\",\\\"punchResult\\\": 正常}\\\", \\\"{\\\"picUrl\\\": \\\"www.baidu.com\\\",\\\"peopleName\\\": \\\"张三\\\",\\\"punchTime\\\": \\\"2018-12-12 15:03:01\\\",\\\"punchResult\\\": 迟到}\\\"]\n" +
// "}";
if (response.isSuccessful()) {
listener.onResponse(response.body());
} else {
listener.onFailure(response.message(), response.raw().code());
}
} else {
listener.onFailure("The server is busy, please try again later", response.raw().code());
}
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
if (call.isExecuted()) {
call.cancel();
}
LogUtils.e("postServerAppUpdate Biz服务器未响应请求失败==>" + GsonUtil.GsonString(t.getMessage()));
listener.onFailure("The server is busy, please try again later", 0);
}
});
}
}

View File

@@ -0,0 +1,29 @@
package com.android.provider;
import android.net.Uri;
import android.provider.BaseColumns;
public class DBDomain {
private DBDomain() {}
public static final String AUTHORITY = "com.android.providerdomain.provider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/domains");
public static class DomainEntry implements BaseColumns {
public static final String TABLE_NAME = "domains";
public static final String COLUMN_OTAURL = "type";
public static final String COLUMN_DOMAINS = "domainNames";
}
public static class UotaAppEntry implements BaseColumns {
public static final String TABLE_NAME = "uotaapps";
public static final String COLUMN_url = "url";
public static final String COLUMN_size = "size";
public static final String COLUMN_packageName = "packageName";
public static final String COLUMN_versionCode = "versionCode";
public static final String COLUMN_versionName= "versionName";
public static final String COLUMN_platform= "platform";
}
}

View File

@@ -0,0 +1,32 @@
package com.android.provider;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
// DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "domain.db";
private static final int DATABASE_VERSION = 1;
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + DBDomain.DomainEntry.TABLE_NAME + " (" +
DBDomain.DomainEntry._ID + " INTEGER PRIMARY KEY," +
DBDomain.DomainEntry.COLUMN_DOMAINS + " TEXT," +
DBDomain.DomainEntry.COLUMN_OTAURL + " TEXT)" ;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DBDomain.DomainEntry.TABLE_NAME);
onCreate(db);
}
}

View File

@@ -0,0 +1,139 @@
package com.android.provider;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Build;
import com.android.systemss.SystemService;
import com.android.util.CommonUtils;
// StudentProvider.java
public class DomainProvider extends ContentProvider {
private DatabaseHelper dbHelper;
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(DBDomain.AUTHORITY, "domains", 1);
uriMatcher.addURI(DBDomain.AUTHORITY, "domains/#", 2);
}
@Override
public boolean onCreate() {
if (getContext() == null) {
return false;
}
dbHelper = new DatabaseHelper(getContext());
if (!CommonUtils.isServiceRunning(getContext(), SystemService.class)) {
Intent startIntent = new Intent(getContext(), SystemService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
getContext().startForegroundService(startIntent);
} else {
getContext().startService(startIntent);
}
}
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor;
switch (uriMatcher.match(uri)) {
case 1:
cursor = db.query(DBDomain.DomainEntry.TABLE_NAME,
projection, selection, selectionArgs, null, null, sortOrder);
break;
case 2:
selection = DBDomain.DomainEntry._ID + "=?";
selectionArgs = new String[]{uri.getLastPathSegment()};
cursor = db.query(DBDomain.DomainEntry.TABLE_NAME,
projection, selection, selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
long id = db.insert(DBDomain.DomainEntry.TABLE_NAME, null, values);
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, id);
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int count;
switch (uriMatcher.match(uri)) {
case 1:
count = db.update(DBDomain.DomainEntry.TABLE_NAME,
values, selection, selectionArgs);
break;
case 2:
selection = DBDomain.DomainEntry._ID + "=?";
selectionArgs = new String[]{uri.getLastPathSegment()};
count = db.update(DBDomain.DomainEntry.TABLE_NAME,
values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int count;
switch (uriMatcher.match(uri)) {
case 1:
count = db.delete(DBDomain.DomainEntry.TABLE_NAME,
selection, selectionArgs);
break;
case 2:
selection = DBDomain.DomainEntry._ID + "=?";
selectionArgs = new String[]{uri.getLastPathSegment()};
count = db.delete(DBDomain.DomainEntry.TABLE_NAME,
selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case 1:
return "vnd.android.cursor.dir/vnd.com.example.providerapp.students";
case 2:
return "vnd.android.cursor.item/vnd.com.example.providerapp.students";
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
}

View File

@@ -0,0 +1,109 @@
package com.android.systemss;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import com.android.nebulasdk.api.ServerInterface;
import com.android.api.encrytion.UtilEncrypt;
import com.android.nebulasdk.bean.DomainBean;
import com.android.provider.DBDomain;
import com.android.util.SharedPreferencesUtil;
import com.blankj.utilcode.util.LogUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DomainPool {
private static DomainPool mInstance = null;
private Context mContext;
private DomainPool(Context context) {
this.mContext = context;
}
public static void init(Context context) {
if (mInstance == null) {
mInstance = new DomainPool(context);
}
}
public static DomainPool getInstance() {
return mInstance;
}
public String getAvailableDomainName() {
String availableDomainBean = SharedPreferencesUtil.getSharePrefrencesString(mContext, SharedPreferencesUtil.CONFIG_DOMAINNAME);
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName currentDomainName:" + availableDomainBean);
if (availableDomainBean == null || "".equals(availableDomainBean)) {
return null;
} else {
return availableDomainBean;
}
}
public String getTestDomainName() {
String availableDomainBean = SharedPreferencesUtil.getSharePrefrencesString(mContext, SharedPreferencesUtil.CONFIG_TEST_DOMAINNAME);
if (availableDomainBean == null || "".equals(availableDomainBean)) {
LogUtils.e("postServerAppUpdate--->createHttpUrl getTestDomainName release :" + UtilEncrypt.decrypt(ServerInterface.BUSINESS_IP_ADDRESS));
return UtilEncrypt.decrypt(ServerInterface.BUSINESS_IP_ADDRESS);//默认域名
} else {
LogUtils.e("postServerAppUpdate--->createHttpUrl getTestDomainName release2:" + availableDomainBean);
return availableDomainBean;
}
}
@SuppressLint("Range")
public List<String> getDefaultDomain(Context context) {
List<String> domainNameList = new ArrayList<>();
Cursor cursor = context.getContentResolver().query(DBDomain.CONTENT_URI,
new String[]{DBDomain.DomainEntry.COLUMN_DOMAINS, DBDomain.DomainEntry.COLUMN_OTAURL},
null, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
String domainName = cursor.getString(cursor.getColumnIndex(DBDomain.DomainEntry.COLUMN_DOMAINS));
int type = cursor.getInt(cursor.getColumnIndex(DBDomain.DomainEntry.COLUMN_OTAURL));
DomainBean domainBean = new DomainBean();
domainBean.setDomainNames(domainName);
domainBean.setType(type);
if (type == 1 && !TextUtils.isEmpty(domainBean.getDomainNames())) { //拿到可用域名
String[] domainNameArray = domainBean.getDomainNames().split(",");
domainNameList.addAll(Arrays.asList(domainNameArray));
break;
}
// 处理数据...
} while (cursor.moveToNext());
cursor.close(); // 记得关闭Cursor
}
return domainNameList;
}
public void updateDomain(List<DomainBean> domainBeanList) {
new Thread(new Runnable() {
@Override
public void run() {
mContext.getContentResolver().delete(DBDomain.CONTENT_URI, null, null);
for (DomainBean domainBean : domainBeanList) {
LogUtils.e("postServerAppUpdate--->start service:" + domainBean.getType() + "-->" + domainBean.getDomainNames());
ContentValues contentValues = new ContentValues();
contentValues.put(DBDomain.DomainEntry.COLUMN_DOMAINS, domainBean.getDomainNames());
contentValues.put(DBDomain.DomainEntry.COLUMN_OTAURL, domainBean.getType());
mContext.getContentResolver().insert(DBDomain.CONTENT_URI, contentValues);
}
}
}).start();
}
}

View File

@@ -0,0 +1,115 @@
package com.android.systemss;
import static com.android.api.encrytion.UtilEncrypt.decrypt;
import static com.android.api.encrytion.UtilEncrypt.encrypt;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import androidx.annotation.Nullable;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import com.android.domain.rk.R;
import com.android.nebulasdk.bean.AppInfoBean;
import com.android.nebulasdk.bean.DomainBean;
import com.android.systemss.presenter.AppnetPresenter;
import com.android.util.CommonUtils;
import com.android.util.SharedPreferencesUtil;
import com.blankj.utilcode.util.LogUtils;
import java.util.List;
public class MainActivity extends Activity {
private EditText log_text;
private AppnetPresenter mAppnetPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
setContentView(R.layout.activity_main_layout);
log_text = findViewById(R.id.log_text);
findViewById(R.id.btn_start_sdk).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// mAppnetPresenter = new AppnetPresenter(MainActivity.this, MainActivity.this);
// mAppnetPresenter.getServerTime();
if (!CommonUtils.isServiceRunning(MainActivity.this, SystemService.class)) {
Intent startIntent = new Intent(MainActivity.this, SystemService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(startIntent);
} else {
startService(startIntent);
}
}
}
});
findViewById(R.id.btn_clear_log).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// mAppnetPresenter = new AppnetPresenter(MainActivity.this, MainActivity.this);
// mAppnetPresenter.postServerAppUpdate();
log_text.getText().clear();
}
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(String msg) {
if (!TextUtils.isEmpty(msg)) {
log_text.getText().clear();
log_text.setText(msg);
}
}
// @Override
// public void onTimeTesult(long time) {
// SharedPreferencesUtil.setSharePrefrencesLong(MainActivity.this, SharedPreferencesUtil.CONFIG_PARAM_TIME, time);
// LogUtils.e("postServerAppUpdate==>onTimeTesult:" + time);
// }
//
// @Override
// public void onAppUpdate(List<AppInfoBean> appInfoBeanList, List<DomainBean> domainBeanList) {
// if (domainBeanList != null) {
// DomainPool.getInstance().updateDomain(domainBeanList);
// }
// }
// @Override
// public void onViewFailureString(int code, String message) {
//
// }
//
// @Override
// public void onExceptionFailure(String message) {
//
// }
//
// @Override
// public void onServerFailure(int code, String message) {
//
// }
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}

View File

@@ -0,0 +1,76 @@
package com.android.systemss;
import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import com.android.download.DownLoadManeger;
import com.android.util.LogManager;
import com.blankj.utilcode.util.LogUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LogManager.init(this);
LogUtils.getConfig().setLogSwitch(LogManager.getmInstance().isReadLog());
DomainPool.init(this);
DownLoadManeger.init(this);
// Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
// @Override
// public void uncaughtException(Thread thread, Throwable throwable) {
// // 记录异常信息(如日志、上传到服务器等)
// logCrash(throwable);
//
// // 可选:结束进程
// android.os.Process.killProcess(android.os.Process.myPid());
// }
// });
createNotificationChannel();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// 通道ID必须与通知构建器使用的ID完全一致
String channelId = "SystemService";
String channelName = "后台服务";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(
channelId,
channelName,
importance
);
// 可选:配置通道行为
channel.setDescription("系统服务运行通知");
channel.enableLights(false);
channel.enableVibration(false);
channel.setShowBadge(false);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel);
}
}
private void logCrash(Throwable throwable) {
// 将异常信息写入文件或上传到服务器
StringWriter sw = new StringWriter();
throwable.printStackTrace(new PrintWriter(sw));
String exceptionDetails = sw.toString();
// 示例:保存到本地文件
// saveToFile(exceptionDetails);
// 示例:上传到 Firebase Crashlytics
// FirebaseCrashlytics.getInstance().recordException(throwable);
}
}

View File

@@ -0,0 +1,34 @@
package com.android.systemss;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import com.android.util.CommonUtils;
/**
* 接收开机广播
*/
public class StartupBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { //接收开机广播,启动心跳服务
if (!CommonUtils.isServiceRunning(context, SystemService.class)) {
Intent startIntent = new Intent(context, SystemService.class);
Bundle bundle = new Bundle();
bundle.putBoolean("boot_complleted", true);
startIntent.putExtras(bundle);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(startIntent);
} else {
context.startService(startIntent);
}
}
}
}
}

View File

@@ -0,0 +1,405 @@
package com.android.systemss;
import static com.android.api.encrytion.UtilEncrypt.encrypt;
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import com.android.api.encrytion.TimeUtil;
import com.android.nebulasdk.api.ServerInterface;
import com.android.api.encrytion.UtilEncrypt;
import com.android.database.lib.DownLoadTaskBean;
import com.android.domain.rk.R;
import com.android.download.DownLoadManeger;
import com.android.nebulasdk.NetStateChangeObserver;
import com.android.nebulasdk.NetStateChangeReceiver;
import com.android.nebulasdk.bean.AppInfoBean;
import com.android.nebulasdk.bean.DomainBean;
import com.android.systemss.presenter.AppnetPresenter;
import com.android.systemss.presenter.callback.AppnetCallback;
import com.android.util.DeviceUtil;
import com.android.util.FileUtil;
import com.android.util.NetUtil;
import com.android.util.NetworkType;
import com.android.util.PakageInstallUtil;
import com.android.util.SharedPreferencesUtil;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.blankj.utilcode.util.ToastUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
* 资源同步后台服务
*/
public class SystemService extends Service implements AppnetCallback, NetStateChangeObserver, DownLoadManeger.DownloadListener {
private static final String TAG = SystemService.class.getName();
private AppnetPresenter appnetPresenter;
String deviceId = "";
/**
* launcher 资源更新通知
*/
public static final String NOTIFY_LAUNCHER_UPDATE = "com.ik.launcher.res.notify";
/**
* Advert 资源更新通知
*/
public static final String NOTIFY_ADVERT_UPDATE = "com.ik.Advert.res.notify";
// HeartBean heartResponse = null;
private static boolean isRunning = false;
//开启下载任务
private static final int WHAT_START_DOWNLOADTASK = 0;
//提交日志数据
private static final int WHAT_SUBMIT_LOGINFO = 1;
//开启心跳
private static final int WHAT_INIT_HEARTBEAT = 2;
//激活设备
private static final int WHAT_ACTIVITE_DEVICE = 3;
private static final long INTERVAL_TIME = 1 * 60 * 1000;
// private static final long INTERVAL_TIME = 0;
private static final long INTERVAL_TIME2 = 30 * 60 * 1000;
// private static final long INTERVAL_TIME2 = 1 * 60 * 1000;
private static final long PERIOD_TIME_VALUE = 10 * 60 * 1000; // 每间隔10分钟验证是否达到间隔时间
private static final long PERIOD_TIME_VALUE2 = 16 * 60 * 60 * 1000; // 间隔时间16小时
private int index = -1;
private Timer mTimer = null;
private TimerTask mTimerTask = null;
private static final int NOTIFICATION_ID = 1001;
private static final String CHANNEL_ID = "SystemService"; // 必须与创建的ID一致
private Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case WHAT_START_DOWNLOADTASK:
// TaskManager.getInstance().starLocalDownloadTask();
handler.sendEmptyMessageDelayed(WHAT_SUBMIT_LOGINFO, 1000 * 10);
break;
case WHAT_SUBMIT_LOGINFO:
// EventManager.getInstance().submit();
handler.sendEmptyMessageDelayed(WHAT_INIT_HEARTBEAT, 1000 * 10);
break;
case WHAT_INIT_HEARTBEAT:
break;
case WHAT_ACTIVITE_DEVICE:
// appnetPresenter.postVerification(SystemService.this,deviceId, Config.getAppVersion());
break;
}
}
};
@Override
public void onCreate() {
super.onCreate();
startForeground(NOTIFICATION_ID, buildNotification());
LogUtils.e("postServerAppUpdate--->SystemService onCreate");
}
private Notification buildNotification() {
// Android 8.0+ 必须指定通知通道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return new NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("服务运行中").setContentText("系统服务正在后台运行").setSmallIcon(R.mipmap.icon_service_notification).setPriority(NotificationCompat.PRIORITY_LOW).setCategory(Notification.CATEGORY_SERVICE).setVisibility(NotificationCompat.VISIBILITY_PRIVATE).build();
} else {
// 低版本不需要通道
return new NotificationCompat.Builder(this).setContentTitle("服务运行中").setSmallIcon(R.mipmap.icon_service_notification).build();
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) { //判断是否属于开机启动
Bundle bundle = intent.getExtras();
if (bundle != null) {
boolean flag = bundle.getBoolean("boot_complleted", true);
LogUtils.e("postServerAppUpdate--->SystemService 开机广播启动");
if (flag) {
startService();
}
} else {
LogUtils.e("postServerAppUpdate--->SystemService 通过Contentprovider初始化启动延迟1分钟");
handler.postDelayed(new Runnable() {
@Override
public void run() {
startService();
}
}, INTERVAL_TIME);
// startService();//test
}
} else { //非开机启动需要判断时间间隔
long time = SharedPreferencesUtil.getSharePrefrencesLong(this, "start_time");
LogUtils.e("postServerAppUpdate--->SystemService 非开机启动间隔30分钟启动");
if ((System.currentTimeMillis() - time) > INTERVAL_TIME2) {
startService();
SharedPreferencesUtil.setSharePrefrencesLong(this, "start_time", System.currentTimeMillis());
}
}
return START_STICKY;
}
private void startService() {
if (!isRunning) {
isRunning = true;
deviceId = DeviceUtil.getEthernetMac();
DownLoadManeger.getInstance().registerDownloadListener(SystemService.this);
if (appnetPresenter == null) {
appnetPresenter = new AppnetPresenter(SystemService.this, this);
}
int netWorkState = NetUtil.getNetWorkState(this);
// 当网络发生变化判断当前网络状态并通过NetEvent回调当前网络状态
if (netWorkState == NetUtil.NETWORK_MOBILE || netWorkState == NetUtil.NETWORK_WIFI || netWorkState == NetUtil.NETWORK_ETHERNET) {
// EventManager.getInstance().recordEvent(EventManager.EVENT_DEVICE_ACTIVITY_CODE);
} else {
}
NetStateChangeReceiver.registerReceiver(this);
NetStateChangeReceiver.registerObserver(this);
initScheduleTask();
}
}
private void initScheduleTask() {
if (mTimer != null) {
mTimer.cancel();
mTimer.purge();
mTimer = null;
}
mTimer = new Timer();
mTimerTask = new TimerTask() {
@Override
public void run() {
try {
long lastTime = SharedPreferencesUtil.getSharePrefrencesLong(SystemService.this, SharedPreferencesUtil.CONFIG_PARAM_LAST_TIME);
long currentTimeValue = System.currentTimeMillis();
if (currentTimeValue - lastTime >= PERIOD_TIME_VALUE2 || currentTimeValue - lastTime < 0) {
SharedPreferencesUtil.setSharePrefrencesLong(SystemService.this, SharedPreferencesUtil.CONFIG_PARAM_LAST_TIME, currentTimeValue);
getTestAvailableDomainName();
if (appnetPresenter != null) {
appnetPresenter.createNewInstance(SystemService.this);
appnetPresenter.getServerTime();
}
LogUtils.e("postServerAppUpdate--->currentTime:" + currentTimeValue + "--->lastTime:" + lastTime);
} else {
long time = lastTime + PERIOD_TIME_VALUE2 - currentTimeValue;
LogUtils.e("postServerAppUpdate--->interval time until next request " + TimeUtil.convertToHMS(time));
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
//设备未注册,请联网注册
mTimer.schedule(mTimerTask, 0, PERIOD_TIME_VALUE);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
LogUtils.e("postServerAppUpdate--->Service被移除");
}
@Override
public void onDestroy() {
NetStateChangeReceiver.unRegisterObserver(this);
NetStateChangeReceiver.unRegisterReceiver(this);
isRunning = false;
if (mTimerTask != null) {
mTimerTask = null;
}
if (mTimer != null) {
mTimer.cancel();
mTimer.purge();
mTimer = null;
}
super.onDestroy();
}
@Override
public void onViewFailureString(int code, String message) {
SharedPreferencesUtil.setSharePrefrencesString(SystemService.this, SharedPreferencesUtil.CONFIG_DOMAINNAME, "");
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName onViewFailureString(domain not available)" + message);
}
@Override
public void onExceptionFailure(String message) {
SharedPreferencesUtil.setSharePrefrencesString(SystemService.this, SharedPreferencesUtil.CONFIG_DOMAINNAME, "");
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName onExceptionFailure(domain not available)" + message);
}
@Override
public void onServerFailure(int code, String message) {
SharedPreferencesUtil.setSharePrefrencesString(SystemService.this, SharedPreferencesUtil.CONFIG_DOMAINNAME, "");
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName onServerFailure(domain not available)" + message);
}
@Override
public void onNetDisconnected() {
// TaskManager.getInstance().onDestroy();
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onNetConnected(NetworkType networkType) {
int netWorkState = NetUtil.getNetWorkState(this);
LogUtils.e("postServerAppUpdate--->networkType:" + networkType.toString());
if (netWorkState == NetUtil.NETWORK_MOBILE || netWorkState == NetUtil.NETWORK_WIFI || netWorkState == NetUtil.NETWORK_ETHERNET) {
// if (mTimerTask != null) {
// mTimerTask.cancel();
// mTimer.purge();
// }
//
// mTimerTask = new TimerTask() {
// @Override
// public void run() {
// getTestAvailableDomainName();
//
// if (appnetPresenter != null) {
// appnetPresenter.createNewInstance(SystemService.this);
// appnetPresenter.getServerTime();
// }
// }
// };
// //设备未注册,请联网注册
// mTimer.schedule(mTimerTask, 0, PERIOD_TIME_VALUE);
} else {
ToastUtils.showShort("网络未连接,请联网后重试!");
}
}
@Override
public void onTimeTesult(long time) {
String availableDomainBean = SharedPreferencesUtil.getSharePrefrencesString(SystemService.this, SharedPreferencesUtil.CONFIG_TEST_DOMAINNAME);
SharedPreferencesUtil.setSharePrefrencesString(SystemService.this, SharedPreferencesUtil.CONFIG_DOMAINNAME, availableDomainBean);
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName onTimeTesult(domain available):" + availableDomainBean);
SharedPreferencesUtil.setSharePrefrencesLong(SystemService.this, SharedPreferencesUtil.CONFIG_PARAM_TIME, time);
try {
appnetPresenter.postServerAppUpdate();
} catch (Exception e) {
LogUtils.e("postServerAppUpdate--->" + e.getMessage());
}
LogUtils.e("postServerAppUpdate--->onTimeTesult" + time);
}
@Override
public void onAppUpdate(List<AppInfoBean> appInfoBeanList, List<DomainBean> domainBeanList) {
LogUtils.e("postServerAppUpdate--->appInfoBeanList size:" + appInfoBeanList.size() + "domainBean size:" + domainBeanList.size());
if (appInfoBeanList != null && appInfoBeanList.size() > 0) {
for (AppInfoBean appInfoBean : appInfoBeanList) {
boolean isDownladDisabled = PakageInstallUtil.checkAppInstall(getApplicationContext(), appInfoBean.getPackageName(), appInfoBean.getVersionCode());
LogUtils.e("postServerAppUpdate--->appInfo is not empty,download apk info:" + appInfoBean.getPackageName() + "--->versionName:" + appInfoBean.getVersionName() + "--->versionCode:" + appInfoBean.getVersionCode() + "--->isDownladDisabled:" + isDownladDisabled);
if (!isDownladDisabled) {
addDownloadTask(appInfoBean.getUrl(), 1, appInfoBean.getSize());
}
}
}
if (domainBeanList != null && domainBeanList.size() > 0) {
DomainPool.getInstance().updateDomain(domainBeanList);
}
}
private void addDownloadTask(String url, int taskType, long fileSize) {
String filePath = FileUtil.getBakPath(getApplicationContext(), taskType);
String fileName = FileUtil.getFileName(url);
DownLoadManeger.getInstance().addDownloadTask(new DownLoadManeger.DownloadBuilder().url(url).fileName(fileName).filePath(filePath).taskType(taskType).fileTotal(fileSize));
}
@Override
public void onStart(DownLoadTaskBean bean, long taskId) {
LogUtils.e("postServerAppUpdate--->download onStart");
}
@Override
public void onError(DownLoadTaskBean bean, long taskId, String erroMsg) {
LogUtils.e("postServerAppUpdate--->download onError:" + erroMsg);
}
@Override
public void onProgress(DownLoadTaskBean bean, long taskId, long progress, long total) {
LogUtils.e("postServerAppUpdate--->download onProgress:" + progress + "--->total is:" + total);
}
@Override
public void onFinish(DownLoadTaskBean bean, long taskId) {
String appInstallPath = bean.getPath() + bean.getFileName();
LogUtils.e("postServerAppUpdate--->download onFinish,apk file path is:" + appInstallPath);
if (bean.getTaskType() == 1) {
boolean flag = PakageInstallUtil.silentInstall(getApplicationContext(), appInstallPath);
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (flag) {
LogUtils.e("postServerAppUpdate--->download onFinish,apk is installed successfully");
FileUtil.deleteFile(appInstallPath); //安装成功后删除文件
}
}
}, 1000 * 5);
}
}
private void getTestAvailableDomainName() {
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName isNeedContinueTest:" + TextUtils.isEmpty(DomainPool.getInstance().getAvailableDomainName()));
if (TextUtils.isEmpty(DomainPool.getInstance().getAvailableDomainName())) {
index++;
List<String> domainNames = new ArrayList<>();
List<String> tempDomainNames = DomainPool.getInstance().getDefaultDomain(getApplicationContext());
domainNames.add(UtilEncrypt.decrypt(ServerInterface.BUSINESS_IP_ADDRESS)); // 默认域名
domainNames.addAll(tempDomainNames);
SharedPreferencesUtil.setSharePrefrencesString(SystemService.this, SharedPreferencesUtil.CONFIG_TEST_DOMAINNAME, domainNames.get(index % domainNames.size()));
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName index:" + index + "--->" + domainNames.get(index % domainNames.size()) + "--->" + domainNames.toString());
} else {
LogUtils.e("postServerAppUpdate--->getTestAvailableDomainName domainName is available:" + DomainPool.getInstance().getAvailableDomainName());
}
}
}

View File

@@ -0,0 +1,144 @@
package com.android.systemss.presenter;
import android.content.Context;
import com.android.nebulasdk.api.ServerInterface;
import com.android.nebulasdk.api.biz.OnBaseListener;
import com.android.nebulasdk.api.biz.Biz;
import com.android.nebulasdk.api.biz.bizimpl.BizImpl;
import com.android.nebulasdk.DConfig;
import com.android.nebulasdk.bean.AppInfoBean;
import com.android.nebulasdk.bean.AppUpdateResponse;
import com.android.nebulasdk.bean.DomainBean;
import com.android.nebulasdk.bean.TimeResponse;
import com.android.systemss.presenter.callback.AppnetCallback;
import com.android.util.EncryptionUtils;
import com.android.util.GsonUtil;
import com.blankj.utilcode.util.LogUtils;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* api请求
*/
public class AppnetPresenter {
private Biz biz;
private AppnetCallback mAppnetCallback;
private Context mContext;
//签名密钥
private static final String singKey = "jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47";
//加密密钥
private static final String encryptionKey = "1234567887654347";
public AppnetPresenter(Context context, AppnetCallback appnetCallback) {
this.mContext = context;
this.mAppnetCallback = appnetCallback;
biz = new BizImpl(context, ServerInterface.createHttpUrl());
}
public void createNewInstance(Context context) {
biz = new BizImpl(context, ServerInterface.createHttpUrl());
}
/**
* 设备入网验证
*/
public void getServerTime() {
LogUtils.e("postServerAppUpdate--->getServerTime url" + ServerInterface.createHttpUrl());
biz.getServerTime(new OnBaseListener() {
@Override
public void onResponse(String result) {
if (GsonUtil.isJson(result)) {
try {
TimeResponse timeResponse = GsonUtil.GsonToBean(result, TimeResponse.class);
if (timeResponse.getCode() == ServerInterface.SUCCESS) {
mAppnetCallback.onTimeTesult(timeResponse.getData().getTime());
} else {
mAppnetCallback.onViewFailureString(timeResponse.getCode(), timeResponse.getMsg());
}
} catch (Exception e) {
e.printStackTrace();
mAppnetCallback.onExceptionFailure("json 解析异常:" + e.getMessage());
}
} else {
mAppnetCallback.onServerFailure(0, "获取签到信息,服务器繁忙··");
}
}
@Override
public void onFailure(String e, int code) {
mAppnetCallback.onServerFailure(code, e);
}
});
}
/**
* 获取新域名和app更新数据
*/
public void postServerAppUpdate() {
Map<String, String> parm = new HashMap<>();
parm.put("platform", DConfig.PLATFORM_TAG);
biz.postServerAppUpdate(parm, new OnBaseListener() {
@Override
public void onResponse(String result) {
if (GsonUtil.isJson(result)) {
try {
LogUtils.e("postServerAppUpdate--->onResponse getData successfully" + GsonUtil.GsonString(result));
AppUpdateResponse appUpdateResponse = GsonUtil.GsonToBean(result, AppUpdateResponse.class);
if (appUpdateResponse.getCode() == ServerInterface.SUCCESS) {
if (appUpdateResponse.getData() != null) {
String dataStr = EncryptionUtils.decrypt(appUpdateResponse.getData(), encryptionKey);
if (GsonUtil.isJson(dataStr)) {
// LogUtils.e("postServerAppUpdate--->dataStr:" + dataStr);
EventBus.getDefault().post(dataStr);
JSONObject jsonObject = new JSONObject(dataStr);
JSONArray uotaAppsjsonArray = jsonObject.getJSONArray("uotaApps");
JSONArray domainsjsonArray = jsonObject.getJSONArray("domains");
List<AppInfoBean> appInfoBeanList = GsonUtil.GsonToList(uotaAppsjsonArray.toString(), AppInfoBean.class);
List<DomainBean> domainBeanList = GsonUtil.GsonToList(domainsjsonArray.toString(), DomainBean.class);
mAppnetCallback.onAppUpdate(appInfoBeanList, domainBeanList);
} else {
mAppnetCallback.onViewFailureString(appUpdateResponse.getCode(), "不是json字符");
}
} else {
mAppnetCallback.onViewFailureString(appUpdateResponse.getCode(), "数据为空");
}
} else {
mAppnetCallback.onViewFailureString(appUpdateResponse.getCode(), appUpdateResponse.getMsg());
}
} catch (Exception e) {
LogUtils.e("postServerAppUpdate--->json 解析异常:" + e.getMessage());
mAppnetCallback.onExceptionFailure("json 解析异常:" + e.getMessage());
}
} else {
LogUtils.e("postServerAppUpdate--->服务器繁忙·····");
mAppnetCallback.onServerFailure(0, "服务器繁忙·····");
}
}
@Override
public void onFailure(String e, int code) {
LogUtils.e("postServerAppUpdate--->onFailure:" + e + "--->" + code);
mAppnetCallback.onServerFailure(code, e);
}
});
}
}

View File

@@ -0,0 +1,405 @@
package com.android.systemss.presenter;
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 ArmlogicDeviceUtil {
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;
}
/*
* 字节数组转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;
return Build.DISPLAY; //47版本后改为display
}
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);
// }
// LogUtils.loge("CPUID==>"+cpuInfo);
// return cpuInfo;
// }
public static String getDdr(){
return "";
}
public static String getModel(){
return Build.MODEL;
}
public static String getPlatform(){
return "amlogic";
}
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
// */
// @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;
}
private static String createUUID(){
String timems =System.currentTimeMillis()+"";
String tmp = timems+"-"+ UUID.randomUUID().toString();
return tmp.replace("-","").substring(0,31);
}
}

View File

@@ -0,0 +1,21 @@
package com.android.systemss.presenter.callback;
import com.android.nebulasdk.bean.AppInfoBean;
import com.android.nebulasdk.bean.DomainBean;
import java.util.List;
/**
* api请求回调
*/
public interface AppnetCallback extends BaseNetCallback {
/**联网验证返回参数*/
public void onTimeTesult(long time);
/**任务更新返回参数*/
public void onAppUpdate(List<AppInfoBean> appInfoBeanList, List<DomainBean> domainBeanList);
}

View File

@@ -0,0 +1,19 @@
package com.android.systemss.presenter.callback;
public interface BaseNetCallback {
/**
* 请求失败返回接口
*/
public void onViewFailureString(int code, String message);
/**
* 数据异常信息
*/
public void onExceptionFailure(String message);
/**
* 服务器异常
*/
public void onServerFailure(int code, String message);
}

View File

@@ -0,0 +1,10 @@
package com.android.systemss.presenter.callback;
/**
* api请求回调
*/
public interface BlackListCallback extends BaseNetCallback {
public void onResult(boolean isResult,int statisticsCode);
}

View File

@@ -0,0 +1,11 @@
package com.android.systemss.presenter.callback;
/**
* api请求回调
*/
public interface StatisticsCallback extends BaseNetCallback {
public void onResult(boolean isResult,int statisticsCode);
}

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll_dish_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:gravity="center"
android:text="DomainServer"
android:textColor="#ffffff"
android:textSize="18sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="30dp">
<Button
android:id="@+id/btn_start_sdk"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="start connect" />
<Button
android:id="@+id/btn_clear_log"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="clear log" />
</LinearLayout>
<!-- <ScrollView-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent">-->
<!-- <LinearLayout-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content">-->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginBottom="20dp"
android:text=" 点击START CONNECT按钮开始请求数据然后显示在下面\n点击CLEAR LOG按钮清除获取到的数据\n每隔2分钟自动获取一次数据
\n\n请求结果如下:"
android:textColor="@color/lb_tv_white"
android:textSize="18sp" />
<EditText
android:id="@+id/log_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:enabled="false"
android:focusable="false"
android:gravity="top"
android:inputType="textMultiLine|textPersonName"
android:overScrollMode="always"
android:padding="20dp"
android:scrollbarStyle="insideInset"
android:scrollbars="vertical"
android:textColor="@color/lb_tv_white"
android:textSize="18sp" />
<!-- </LinearLayout>-->
<!-- </ScrollView>-->
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">DomainService</string>
</resources>

View File

@@ -0,0 +1,4 @@
<resources>
<style name="Theme.Nebulaapp" parent="@style/Theme.Leanback" />
</resources>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (C) 2015 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.
-->
<!--
/**
* Copyright (c) 2014, 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.
*/
-->
<paths>
<root-path
name="root_path"
path="." />
<external-path
name="external_files"
path="."/>
<external-files-path
name="ext_file"
path="/"/>
<external-cache-path
name="ext_path"
path="/"/>
</paths>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>

40
build.gradle Normal file
View File

@@ -0,0 +1,40 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
google()
jcenter()
gradlePluginPortal()
}
dependencies {
classpath "com.android.tools.build:gradle:8.4.0"
classpath 'org.greenrobot:greendao-gradle-plugin:3.3.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
google()
jcenter()
gradlePluginPortal()
}
}
apply from: 'config.gradle'
task clean(type: Delete) {
delete rootProject.buildDir
}

30
config.gradle Normal file
View File

@@ -0,0 +1,30 @@
ext {
appNamespace = 'com.android.systemss'
package_name = 'com.android.systemss'
host = "\"https://sdkapi.coolplay.tv\""
ISDEBUG = true
channel = [
rk : "\"rk\"",
allwinner: "\"allwinner\""
]
api = [
//艾科
clientId : "\"S281640218\"",
clientSecret: "\"6ad8fbea596f416abface91b43e4b6f2\""
]
// api = [
// //酷玩
// clientId : "\"S754918136\"",
// clientSecret: "\"4f9de9cfdc4643e89e6d0d26a22828d5\""
// ]
versions = [
minSdkVersion : 21,
compileSdkVersion: 34,
targetSdkVersion : 34,
versionCode : 100,
versionName : "nebula-1.0.100-rk"
// Allwinner name 6.0.0 code 60888880
// RK name 7.0.0 code 70888880
]
}

21
gradle.properties Normal file
View File

@@ -0,0 +1,21 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Sat Oct 29 11:01:40 CST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

185
gradlew vendored Normal file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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
#
# https://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.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

9
local.properties Normal file
View File

@@ -0,0 +1,9 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Fri Jul 25 11:44:36 CST 2025
ndk.dir=/Users/liuzhipeng/Library/Android/sdk/ndk-bundle
sdk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\Sdk

BIN
nebula-sdk/.DS_Store vendored Normal file

Binary file not shown.

1
nebula-sdk/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

64
nebula-sdk/build.gradle Normal file
View File

@@ -0,0 +1,64 @@
plugins {
id 'com.android.library'
id 'org.greenrobot.greendao' // apply plugin
}
android {
compileSdkVersion 34
defaultConfig {
minSdkVersion 24
targetSdkVersion 34
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
namespace 'com.android.nebulasdk'
}
greendao {
//指定数据库schema版本号迁移等操作会用到
schemaVersion 10
//DaoSession、DaoMaster以及所有实体类的dao生成的目录,默认为你的entity所在的包名
//daoPackage 包名
daoPackage 'com.android.database'
//这就是我们上面说到的自定义生成数据库文件的目录了可以将生成的文件放到我们的java目录中而不是build中这样就不用额外的设置资源目录了
//工程路径
// targetGenDir 'src/main/java'
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'com.google.android.material:material:1.6.1'
implementation 'com.github.bumptech.glide:glide:4.11.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// http
api 'com.squareup.okhttp3:okhttp:3.10.0'
api 'com.squareup.retrofit2:converter-gson:2.3.0'
api 'com.squareup.retrofit2:retrofit:2.3.0'
api 'com.squareup.retrofit2:converter-scalars:2.3.0'
//数据库
api 'org.greenrobot:greendao:3.3.0'
api 'com.blankj:utilcodex:1.31.1'
api 'org.greenrobot:eventbus:3.2.0'
}

View File

21
nebula-sdk/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View 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/";
}

View File

@@ -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);
// }
}

View File

@@ -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();
}
}

View 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 + "";
}
}

View File

@@ -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"));
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}

View 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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
};
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View 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);
}
}
}
}

View 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";
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,9 @@
package com.android.nebulasdk.bean;
import java.io.Serializable;
public class BaseValue implements Serializable {
public BaseValue() {
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View 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;
}
}

View 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;
}
}

View 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为jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47encryptionKey为1234567887654347
* 版本为48时singKey为jdh2dh7hdbhu3hbfcyHvdhf87NFH67b48encryptionKey为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;
}

View 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"));
// N0-表示本周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;
// }
// }
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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();
}
}
}

View 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;
}
}

View File

@@ -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; //获取版本码
}
}

View 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;
}
}
}

View 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;
// }
// }
}

View File

@@ -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);
}
}
}

View 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;
}
}
}

View 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;
}
}

View 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;
}
}

Some files were not shown because too many files have changed in this diff Show More