首次提交
This commit is contained in:
BIN
apk/app-Domain-1.0.105-rk-20250928-release.apk
Normal file
BIN
apk/app-Domain-1.0.105-rk-20250928-release.apk
Normal file
Binary file not shown.
BIN
apk/baselineProfiles/0/app-Domain-1.0.105-rk-20250928-release.dm
Normal file
BIN
apk/baselineProfiles/0/app-Domain-1.0.105-rk-20250928-release.dm
Normal file
Binary file not shown.
BIN
apk/baselineProfiles/1/app-Domain-1.0.105-rk-20250928-release.dm
Normal file
BIN
apk/baselineProfiles/1/app-Domain-1.0.105-rk-20250928-release.dm
Normal file
Binary file not shown.
37
apk/output-metadata.json
Normal file
37
apk/output-metadata.json
Normal 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
BIN
app/.DS_Store
vendored
Normal file
Binary file not shown.
1
app/.gitignore
vendored
Normal file
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
88
app/build.gradle
Normal file
88
app/build.gradle
Normal 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
BIN
app/platform.keystore
Normal file
Binary file not shown.
BIN
app/platform_rk.keystore
Normal file
BIN
app/platform_rk.keystore
Normal file
Binary file not shown.
185
app/proguard-rules.pro
vendored
Normal file
185
app/proguard-rules.pro
vendored
Normal 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
|
||||
93
app/src/main/AndroidManifest.xml
Normal file
93
app/src/main/AndroidManifest.xml
Normal 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>
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.android.nebulasdk;
|
||||
|
||||
import com.android.util.NetworkType;
|
||||
|
||||
public interface NetStateChangeObserver {
|
||||
|
||||
public void onNetDisconnected();
|
||||
public void onNetConnected(NetworkType networkType);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
31
app/src/main/java/com/android/nebulasdk/api/ServerApi.java
Normal file
31
app/src/main/java/com/android/nebulasdk/api/ServerApi.java
Normal 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();
|
||||
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
84
app/src/main/java/com/android/nebulasdk/api/biz/BaseBiz.java
Normal file
84
app/src/main/java/com/android/nebulasdk/api/biz/BaseBiz.java
Normal 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();
|
||||
}
|
||||
}
|
||||
21
app/src/main/java/com/android/nebulasdk/api/biz/Biz.java
Normal file
21
app/src/main/java/com/android/nebulasdk/api/biz/Biz.java
Normal 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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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/";
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.android.nebulasdk.api.biz;
|
||||
|
||||
|
||||
public interface OnBaseListener {
|
||||
|
||||
/**
|
||||
* 服务器响应
|
||||
*/
|
||||
void onResponse(String result);
|
||||
|
||||
/**
|
||||
* 服务器未响应
|
||||
*/
|
||||
void onFailure(String e, int code);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
29
app/src/main/java/com/android/provider/DBDomain.java
Normal file
29
app/src/main/java/com/android/provider/DBDomain.java
Normal 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";
|
||||
}
|
||||
}
|
||||
32
app/src/main/java/com/android/provider/DatabaseHelper.java
Normal file
32
app/src/main/java/com/android/provider/DatabaseHelper.java
Normal 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);
|
||||
}
|
||||
}
|
||||
139
app/src/main/java/com/android/provider/DomainProvider.java
Normal file
139
app/src/main/java/com/android/provider/DomainProvider.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
109
app/src/main/java/com/android/systemss/DomainPool.java
Normal file
109
app/src/main/java/com/android/systemss/DomainPool.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
115
app/src/main/java/com/android/systemss/MainActivity.java
Normal file
115
app/src/main/java/com/android/systemss/MainActivity.java
Normal 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);
|
||||
}
|
||||
}
|
||||
76
app/src/main/java/com/android/systemss/MyApplication.java
Normal file
76
app/src/main/java/com/android/systemss/MyApplication.java
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
34
app/src/main/java/com/android/systemss/StartupBroadcast.java
Normal file
34
app/src/main/java/com/android/systemss/StartupBroadcast.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
405
app/src/main/java/com/android/systemss/SystemService.java
Normal file
405
app/src/main/java/com/android/systemss/SystemService.java
Normal 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.android.systemss.presenter.callback;
|
||||
|
||||
|
||||
/**
|
||||
* api请求回调
|
||||
*/
|
||||
public interface BlackListCallback extends BaseNetCallback {
|
||||
|
||||
public void onResult(boolean isResult,int statisticsCode);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.android.systemss.presenter.callback;
|
||||
|
||||
|
||||
/**
|
||||
* api请求回调
|
||||
*/
|
||||
public interface StatisticsCallback extends BaseNetCallback {
|
||||
|
||||
|
||||
public void onResult(boolean isResult,int statisticsCode);
|
||||
}
|
||||
83
app/src/main/res/layout/activity_main_layout.xml
Normal file
83
app/src/main/res/layout/activity_main_layout.xml
Normal 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>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/icon_service_notification.png
Normal file
BIN
app/src/main/res/mipmap-xxhdpi/icon_service_notification.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
3
app/src/main/res/values/strings.xml
Normal file
3
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">DomainService</string>
|
||||
</resources>
|
||||
4
app/src/main/res/values/themes.xml
Normal file
4
app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Nebulaapp" parent="@style/Theme.Leanback" />
|
||||
</resources>
|
||||
51
app/src/main/res/xml/file_paths.xml
Normal file
51
app/src/main/res/xml/file_paths.xml
Normal 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>
|
||||
|
||||
5
app/src/main/res/xml/network_security_config.xml
Normal file
5
app/src/main/res/xml/network_security_config.xml
Normal 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
40
build.gradle
Normal 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
30
config.gradle
Normal 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
21
gradle.properties
Normal 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
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal 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
185
gradlew
vendored
Normal 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
89
gradlew.bat
vendored
Normal 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
9
local.properties
Normal 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
BIN
nebula-sdk/.DS_Store
vendored
Normal file
Binary file not shown.
1
nebula-sdk/.gitignore
vendored
Normal file
1
nebula-sdk/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
64
nebula-sdk/build.gradle
Normal file
64
nebula-sdk/build.gradle
Normal 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'
|
||||
}
|
||||
0
nebula-sdk/consumer-rules.pro
Normal file
0
nebula-sdk/consumer-rules.pro
Normal file
21
nebula-sdk/proguard-rules.pro
vendored
Normal file
21
nebula-sdk/proguard-rules.pro
vendored
Normal 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
|
||||
3
nebula-sdk/src/main/AndroidManifest.xml
Normal file
3
nebula-sdk/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
</manifest>
|
||||
17
nebula-sdk/src/main/java/com/android/api/CoreKeys.java
Normal file
17
nebula-sdk/src/main/java/com/android/api/CoreKeys.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.android.api;
|
||||
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class CoreKeys {
|
||||
|
||||
public static final String SESSIONID = "sessionid";
|
||||
public static final String CONFIGDATABEAN="ConfigDataBean";
|
||||
|
||||
public static String local_file = Environment.getExternalStorageDirectory()
|
||||
+ File.separator + Environment.DIRECTORY_DCIM
|
||||
+ File.separator + "Camera" + File.separator;
|
||||
public static String down_file = Environment.getExternalStorageDirectory().getAbsolutePath() + "/atv-ota/";
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
|
||||
|
||||
public class AESUtil {
|
||||
|
||||
|
||||
private static final String password="wwwwaaabbb";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param dataStr
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String encryptVerification(String dataStr){
|
||||
|
||||
if(dataStr==null||"".equals(dataStr)){
|
||||
return "";
|
||||
}
|
||||
String headMsg="";
|
||||
String endMag="";
|
||||
String addendMag="";
|
||||
if(dataStr.length()>3) {
|
||||
headMsg = dataStr.substring(0,3);
|
||||
}
|
||||
if(dataStr.length()>4){
|
||||
endMag=dataStr.substring(dataStr.length()-4,dataStr.length());
|
||||
}
|
||||
if(dataStr.length()>7){
|
||||
addendMag=dataStr.substring(0,7);
|
||||
}
|
||||
String time=TimeUtil.getDateEND(System.currentTimeMillis());
|
||||
String tmp=headMsg+time+addendMag+endMag;
|
||||
String verification = MD5Utils.md5(tmp).substring(0,15);
|
||||
return UtilEncrypt.encrypt(password,verification);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * 测试
|
||||
// *
|
||||
// * @param args
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public static void main(String[] args) throws Exception {
|
||||
//// String test= encryptVerification("8618665362153","123456");
|
||||
//
|
||||
// String test=UtilEncrypt.encrypt("test","123456");
|
||||
// System.out.print(test);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
|
||||
/**
|
||||
* Created by jzm on 2016/7/18.
|
||||
*/
|
||||
public class MD5Utils {
|
||||
|
||||
/**
|
||||
* 使用md5的算法进行加密
|
||||
*/
|
||||
public static String md5(String encryptStr) {
|
||||
MessageDigest md5;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
byte[] md5Bytes = md5.digest(encryptStr.getBytes());
|
||||
StringBuffer hexValue = new StringBuffer();
|
||||
for (int i = 0; i < md5Bytes.length; i++) {
|
||||
int val = ((int) md5Bytes[i]) & 0xff;
|
||||
if (val < 16)
|
||||
hexValue.append("0");
|
||||
hexValue.append(Integer.toHexString(val));
|
||||
}
|
||||
encryptStr = hexValue.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return encryptStr.toLowerCase();
|
||||
}
|
||||
}
|
||||
551
nebula-sdk/src/main/java/com/android/api/encrytion/TimeUtil.java
Normal file
551
nebula-sdk/src/main/java/com/android/api/encrytion/TimeUtil.java
Normal file
@@ -0,0 +1,551 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* 时间转换工具
|
||||
*/
|
||||
public class TimeUtil {
|
||||
public static final long DAY_MILLSECONDS = 24 * 3600 * 1000;
|
||||
|
||||
private TimeUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间戳(毫秒)转换为时分秒格式(HH:mm:ss)
|
||||
*
|
||||
* @param milliseconds 时间戳(毫秒)
|
||||
* @return 格式化后的时间字符串(HH:mm:ss)
|
||||
*/
|
||||
public static String convertToHMS(long milliseconds) {
|
||||
// 确保时间戳为非负数
|
||||
if (milliseconds < 0) {
|
||||
throw new IllegalArgumentException("时间戳不能为负数");
|
||||
}
|
||||
|
||||
long hours = TimeUnit.MILLISECONDS.toHours(milliseconds);
|
||||
long minutes = TimeUnit.MILLISECONDS.toMinutes(milliseconds)
|
||||
- TimeUnit.HOURS.toMinutes(hours);
|
||||
long seconds = TimeUnit.MILLISECONDS.toSeconds(milliseconds)
|
||||
- TimeUnit.HOURS.toSeconds(hours)
|
||||
- TimeUnit.MINUTES.toSeconds(minutes);
|
||||
|
||||
// 格式化输出,确保两位数字
|
||||
return String.format("%02dh%02dm%02ds", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
public static String showMessageTime(long MessageTime) {
|
||||
SimpleDateFormat format;
|
||||
String showtimeString;
|
||||
long startTime = MessageTime * 1000;
|
||||
//获取当前年份
|
||||
int current_year = Integer.parseInt(getYear(System.currentTimeMillis()));
|
||||
//获取发消息的年份
|
||||
int year = Integer.parseInt(getYear(startTime));
|
||||
if (current_year > year) {
|
||||
//不在同一年 显示完整的年月日
|
||||
showtimeString = getDateEN(startTime);
|
||||
} else {
|
||||
if (newchajitian(startTime) == 0) {
|
||||
//同一天 显示时分
|
||||
format = new SimpleDateFormat("HH:mm");
|
||||
showtimeString = format.format(new Date(startTime));
|
||||
} else if (newchajitian(startTime) == 1) {
|
||||
//相差一天 显示昨天
|
||||
showtimeString = "昨天";
|
||||
} else if (newchajitian(startTime) > 1 && newchajitian(startTime) < 7) {
|
||||
//相差一天以上 七天之内 显示星期几
|
||||
showtimeString = getWeek(startTime);
|
||||
} else {
|
||||
format = new SimpleDateFormat("MM-dd");
|
||||
showtimeString = format.format(new Date(startTime));
|
||||
}
|
||||
|
||||
}
|
||||
return showtimeString;
|
||||
}
|
||||
|
||||
public static String getLastM(int total, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM");
|
||||
Date date = new Date();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - (total - value));
|
||||
date = calendar.getTime();
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户生日计算年龄
|
||||
*/
|
||||
public static String getAgeByBirthday(Date birthday) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
|
||||
if (cal.before(birthday)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The birthDay is before Now.It's unbelievable!");
|
||||
}
|
||||
|
||||
int yearNow = cal.get(Calendar.YEAR);
|
||||
int monthNow = cal.get(Calendar.MONTH) + 1;
|
||||
int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
cal.setTime(birthday);
|
||||
int yearBirth = cal.get(Calendar.YEAR);
|
||||
int monthBirth = cal.get(Calendar.MONTH) + 1;
|
||||
int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
int age = yearNow - yearBirth;
|
||||
|
||||
if (monthNow <= monthBirth) {
|
||||
if (monthNow == monthBirth) {
|
||||
// monthNow==monthBirth
|
||||
if (dayOfMonthNow < dayOfMonthBirth) {
|
||||
age--;
|
||||
}
|
||||
} else {
|
||||
// monthNow>monthBirth
|
||||
age--;
|
||||
}
|
||||
}
|
||||
return age + "岁";
|
||||
}
|
||||
//获取当前年月日生成的唯一标识码
|
||||
public static String getTimeNumber(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||
return format.format(new Date(time));// 2012-10-03-23-41-31
|
||||
}
|
||||
//显示完整的年月日 时分秒
|
||||
public static String getTime(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
//显示完整的年月日 时分秒
|
||||
public static String getMinute(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("mm:ss");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
//显示完整的月日 时分
|
||||
public static String getComTime(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
//显示完整的年月日
|
||||
public static String getDateEN(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
//显示完整的年月日
|
||||
public static String getDateEND(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
//显示完整的年月日
|
||||
public static String getDateMon(long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("MM月dd日");
|
||||
return format.format(new Date(time));// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
// 获取当前年份
|
||||
public static String getYear(Long time) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy");
|
||||
return format.format(new Date(time));
|
||||
}
|
||||
|
||||
public static long getDate(String timeStr) {
|
||||
long time = 0;
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
try {
|
||||
Date date = format.parse(timeStr);
|
||||
time = date.getTime();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return time / 1000;
|
||||
}
|
||||
|
||||
public static long getDateByString(String timeStr) {
|
||||
long time = 0;
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
Date date = format.parse(timeStr);
|
||||
time = date.getTime();
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
public static String getTimeByString(String timeStr) {
|
||||
|
||||
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddhhmmss");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf1.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
return sdf2.format(date);
|
||||
}
|
||||
|
||||
public static String getTimeByStr(String timeStr) {
|
||||
|
||||
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddhhmmss");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf1.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
|
||||
return sdf2.format(date);
|
||||
}
|
||||
|
||||
|
||||
public static String setTimeByString(String timeStr) {
|
||||
|
||||
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
Date date = null;
|
||||
try {
|
||||
date = sdf1.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddhhmmss");
|
||||
return sdf2.format(date);
|
||||
}
|
||||
|
||||
// 获取上午、下午时间
|
||||
public static String getHour(Long time) {
|
||||
String str;
|
||||
final Calendar mCalendar = Calendar.getInstance();
|
||||
mCalendar.setTimeInMillis(time);
|
||||
int apm = mCalendar.get(Calendar.AM_PM);
|
||||
SimpleDateFormat format = new SimpleDateFormat("hh:mm");
|
||||
String hour = format.format(time);
|
||||
|
||||
if (apm == 0) {
|
||||
str = "上午 " + hour;
|
||||
} else {
|
||||
str = "下午 " + hour;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public static long newchajitian(Long lstartTime) {
|
||||
Calendar c1 = Calendar.getInstance();
|
||||
int year = c1.get(Calendar.YEAR);
|
||||
int yue = c1.get(Calendar.MONTH);
|
||||
int ri = c1.get(Calendar.DATE);
|
||||
c1.set(year, yue + 1, ri, 0, 0);
|
||||
Calendar c2 = Calendar.getInstance();
|
||||
int year_ = Integer.parseInt((getYear(lstartTime)));
|
||||
int yue_ = getYue(lstartTime);
|
||||
int ri_ = getDay(lstartTime);
|
||||
c2.set(year_, yue_, ri_, 0, 0);
|
||||
return getAbsDayDiff(c2, c1);
|
||||
}
|
||||
|
||||
public static int getDay(long time) {
|
||||
SimpleDateFormat format1 = new SimpleDateFormat("dd");
|
||||
String date1 = format1.format(new Date(time));
|
||||
return Integer.parseInt(date1);// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
public static int getYue(long time) {
|
||||
SimpleDateFormat format1 = new SimpleDateFormat("MM");
|
||||
String date1 = format1.format(new Date(time));
|
||||
return Integer.parseInt(date1);// 2012-10-03 23:41:31
|
||||
}
|
||||
|
||||
public static int getAbsDayDiff(Calendar calStart, Calendar calEnd) {
|
||||
Calendar start = (Calendar) calStart.clone();
|
||||
Calendar end = (Calendar) calEnd.clone();
|
||||
|
||||
start.set(start.get(Calendar.YEAR), start.get(Calendar.MONTH),
|
||||
start.get(Calendar.DATE), 0, 0, 0);
|
||||
start.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
end.set(end.get(Calendar.YEAR), end.get(Calendar.MONTH),
|
||||
end.get(Calendar.DATE), 0, 0, 0);
|
||||
end.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
return (int) ((end.getTimeInMillis() - start.getTimeInMillis()) / DAY_MILLSECONDS);
|
||||
}
|
||||
|
||||
//获取星期几
|
||||
public static String getWeek(long timeStamp) {
|
||||
int myDate;
|
||||
String week = null;
|
||||
Calendar cd = Calendar.getInstance();
|
||||
cd.setTime(new Date(timeStamp));
|
||||
myDate = cd.get(Calendar.DAY_OF_WEEK);
|
||||
// 获取指定日期转换成星期几
|
||||
if (myDate == 1) {
|
||||
week = "星期日";
|
||||
} else if (myDate == 2) {
|
||||
week = "星期一";
|
||||
} else if (myDate == 3) {
|
||||
week = "星期二";
|
||||
} else if (myDate == 4) {
|
||||
week = "星期三";
|
||||
} else if (myDate == 5) {
|
||||
week = "星期四";
|
||||
} else if (myDate == 6) {
|
||||
week = "星期五";
|
||||
} else if (myDate == 7) {
|
||||
week = "星期六";
|
||||
}
|
||||
return week;
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间转化为显示字符串
|
||||
*
|
||||
* @param timeStamp 单位为秒
|
||||
*/
|
||||
public static String getTimeStr(long timeStamp) {
|
||||
if (timeStamp == 0) return "";
|
||||
Calendar inputTime = Calendar.getInstance();
|
||||
inputTime.setTimeInMillis(timeStamp * 1000);
|
||||
Date currenTimeZone = inputTime.getTime();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (calendar.before(inputTime)) {
|
||||
//当前时间在输入时间之前
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
if (calendar.before(inputTime)) {
|
||||
return "昨天";
|
||||
} else {
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar.set(Calendar.MONTH, Calendar.JANUARY);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
|
||||
return sdf.format(currenTimeZone);
|
||||
} else {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间转化为聊天界面显示字符串
|
||||
*
|
||||
* @param timeStamp 单位为秒
|
||||
*/
|
||||
public static String getChatTimeStr(long timeStamp) {
|
||||
if (timeStamp == 0) return "";
|
||||
Calendar inputTime = Calendar.getInstance();
|
||||
inputTime.setTimeInMillis(timeStamp * 1000);
|
||||
Date currenTimeZone = inputTime.getTime();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (calendar.before(inputTime)) {
|
||||
//当前时间在输入时间之前
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||
calendar.set(Calendar.MINUTE, 0);
|
||||
calendar.set(Calendar.SECOND, 0);
|
||||
calendar.set(Calendar.MILLISECOND, 0);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -1);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||
return "昨天 " + sdf.format(currenTimeZone);
|
||||
} else {
|
||||
calendar.set(Calendar.DAY_OF_MONTH, 1);
|
||||
calendar.set(Calendar.MONTH, Calendar.JANUARY);
|
||||
if (calendar.before(inputTime)) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("M月d日" + " HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
} else {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日" + " HH:mm");
|
||||
return sdf.format(currenTimeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getYear() {
|
||||
return Calendar.getInstance().get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public static int getMonth() {
|
||||
return Calendar.getInstance().get(Calendar.MONTH) + 1;
|
||||
}
|
||||
|
||||
public static int getCurrentMonthDay() {
|
||||
return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串转为时间戳
|
||||
*/
|
||||
public static long getStringToDate(String time) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
|
||||
Date date = new Date();
|
||||
try {
|
||||
date = simpleDateFormat.parse(time);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return date.getTime();
|
||||
}
|
||||
|
||||
//获得当前日期与本周一相差的天数
|
||||
public static int getMondayPlus() {
|
||||
Calendar cd = Calendar.getInstance();
|
||||
// 获得今天是一周的第几天,星期日是第一天,星期二是第二天......
|
||||
int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
|
||||
if (dayOfWeek == 1) {
|
||||
return -6;
|
||||
} else {
|
||||
return 2 - dayOfWeek;
|
||||
}
|
||||
}
|
||||
|
||||
//获得本周星期一的日期
|
||||
public static Calendar getCurrentMonday() {
|
||||
int mondayPlus = getMondayPlus();
|
||||
GregorianCalendar currentDate = new GregorianCalendar();
|
||||
currentDate.add(GregorianCalendar.DATE, mondayPlus);
|
||||
Date monday = currentDate.getTime();
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(monday);
|
||||
return c;
|
||||
}
|
||||
|
||||
// 上/下 一月
|
||||
public static String getLastOrNextMonth(String timeStr, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月");
|
||||
Date date = new Date();
|
||||
if (!timeStr.equals("本月")) {
|
||||
try {
|
||||
date = dateFormat.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - value);
|
||||
date = calendar.getTime();
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
// 上/下 一周
|
||||
public static String getLastOrNextWeek(String timeStr, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年");
|
||||
Date date = new Date();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
if (!timeStr.equals("本周")) {
|
||||
try {
|
||||
date = dateFormat.parse(timeStr.substring(0, timeStr.indexOf("年") + 1));
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.WEEK_OF_YEAR, Integer.parseInt(timeStr
|
||||
.substring(timeStr.indexOf("年") + 1, timeStr.indexOf("周"))) - value);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.WEEK_OF_YEAR, calendar.get(Calendar.WEEK_OF_YEAR) - value);
|
||||
}
|
||||
date = calendar.getTime();
|
||||
if (calendar.get(Calendar.WEEK_OF_YEAR) > 9) {
|
||||
return dateFormat.format(date) + calendar.get(Calendar.WEEK_OF_YEAR) + "周";
|
||||
} else {
|
||||
return dateFormat.format(date) + "0" + calendar.get(Calendar.WEEK_OF_YEAR) + "周";
|
||||
}
|
||||
}
|
||||
|
||||
// 上/下 一日
|
||||
public static String getLastOrNextDay(String timeStr, int value) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = new Date();
|
||||
if (!timeStr.equals("今日")) {
|
||||
try {
|
||||
date = dateFormat.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date); // 设置为当前时间
|
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - value);
|
||||
date = calendar.getTime();
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
||||
// 是否是今日
|
||||
public static Boolean isToday(String timeStr) {
|
||||
return getDateEN(System.currentTimeMillis()).equals(timeStr);
|
||||
}
|
||||
//
|
||||
// // 是否是本周
|
||||
// public static Boolean isTswk(String timeStr) {
|
||||
//
|
||||
// Calendar calendar = Calendar.getInstance();
|
||||
// int year = Integer.parseInt(timeStr.substring(0, timeStr.indexOf("年")));
|
||||
// int week = Integer.parseInt(timeStr
|
||||
// .substring(timeStr.indexOf("年") + 1, timeStr.indexOf("周")));
|
||||
//
|
||||
// return calendar.get(Calendar.YEAR) == year && calendar.get(Calendar.WEEK_OF_YEAR) == week;
|
||||
// }
|
||||
|
||||
// 是否是本月
|
||||
public static Boolean isTsM(String timeStr) {
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月");
|
||||
String nowTime = dateFormat.format(new Date(System.currentTimeMillis()));
|
||||
|
||||
return timeStr.equals(nowTime);
|
||||
}
|
||||
|
||||
|
||||
public static String getDisparity(String timeStamp) {
|
||||
Long target = getDateByString(timeStamp);
|
||||
Long now = System.currentTimeMillis();
|
||||
if (target < now) {
|
||||
return "已截止";
|
||||
}
|
||||
Long l = target - now;
|
||||
long Minute = (l / (1000 * 60));
|
||||
long day = (l / (1000 * 60 * 60 * 24));
|
||||
long min = Minute - (day * 60 * 24);
|
||||
long hour = min / 60;
|
||||
long minute = min - (hour * 60);
|
||||
return day + "天" + hour + ":" + minute + "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.Key;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
public final class UtilEncrypt {
|
||||
|
||||
/**
|
||||
* 默认密钥,实际项目中可配置注入或数据库读取
|
||||
*/
|
||||
private final static String DEFAULT_KEY = "asla01slajf1ALlsdaf0987654321";
|
||||
|
||||
/**
|
||||
* 对字符串进行默认加密
|
||||
*/
|
||||
public static String encrypt(String str) {
|
||||
return encrypt(str, DEFAULT_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串加密
|
||||
*/
|
||||
public static String decrypt(String str) {
|
||||
return decrypt(str, DEFAULT_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串加密
|
||||
*/
|
||||
public static String encrypt(String plainText, String key) {
|
||||
|
||||
byte[] bytes = null;
|
||||
try {
|
||||
bytes = plainText.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
byte[] encryptedBytes = getCipher(Cipher.ENCRYPT_MODE, key).doFinal(bytes);
|
||||
return UtilHex.bytes2HexString(encryptedBytes);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字符串解密
|
||||
*/
|
||||
public static String decrypt(String encryptedText, String key) {
|
||||
byte[] arr = UtilHex.hexString2Bytes(encryptedText);
|
||||
try {
|
||||
byte[] decryptedBytes = getCipher(Cipher.DECRYPT_MODE, key).doFinal(arr);
|
||||
return new String(decryptedBytes);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Cipher getCipher(int mode, String key) {
|
||||
// Security.addProvider(new com.sun.crypto.provider.SunJCE());
|
||||
// Security.addProvider(new Provider.SunJCE());
|
||||
if (key == null) {
|
||||
key = DEFAULT_KEY;
|
||||
}
|
||||
byte[] arrBTmp = null;
|
||||
try {
|
||||
arrBTmp = key.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
// 创建一个空的length位字节数组(默认值为0)
|
||||
byte[] arrB = new byte[16];
|
||||
|
||||
// 将原始字节数组转换为8位
|
||||
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
|
||||
arrB[i] = arrBTmp[i];
|
||||
}
|
||||
// 生成密钥
|
||||
Key theKey = new javax.crypto.spec.SecretKeySpec(arrB, "AES");
|
||||
|
||||
// 生成Cipher对象,指定其支持的DES算法
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES");
|
||||
cipher.init(mode, theKey);
|
||||
return cipher;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
//业务:business.akrdinfo.cn
|
||||
//心跳:heartbeat.akrdinfo.cn
|
||||
// String value = encrypt("heartbeat.akrdinfo.cn");
|
||||
String value = encrypt("rdnss.cloud");
|
||||
System.out.println(value);
|
||||
// System.out.println(decrypt("7ae044016890d6862e2e343f9b735db1464f0b63c251cce2e9855af9c3c7f6be"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.android.api.encrytion;
|
||||
|
||||
/**
|
||||
* 16进制转换工具
|
||||
*
|
||||
* @author wulh create on 2018/5/20.
|
||||
*/
|
||||
public final class UtilHex {
|
||||
|
||||
/**
|
||||
* 16进制字符串转为字节数组
|
||||
* @param hexStr 长度必须为偶数,每个字节用两个字符表达
|
||||
* @return 对应字节数组
|
||||
*/
|
||||
public static byte[] hexString2Bytes(String hexStr) {
|
||||
if(hexStr == null || hexStr.length() == 0 || hexStr.length() % 2 > 0) {
|
||||
throw new IllegalArgumentException("参数长度必须为偶数");
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[hexStr.length() / 2];
|
||||
for(int i = 0, len = bytes.length; i < len; i++) {
|
||||
bytes[i] = (byte) (0xFF & Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 16进制字符串转为字节数组
|
||||
* @param hexStr 长度必须为偶数,每个字节用两个字符表达
|
||||
* @return 对应字节数组
|
||||
*/
|
||||
public static String bytes2HexString(byte[] bytes) {
|
||||
if(bytes == null || bytes.length == 0) {
|
||||
throw new IllegalArgumentException("参数必须非空");
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(byte b : bytes) {
|
||||
String s = Integer.toHexString(0xFF & b);
|
||||
if(s.length() == 1) {
|
||||
s = "0" + s;
|
||||
}
|
||||
sb.append(s);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.android.database;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractDaoMannager<T> {
|
||||
abstract void insert(Class<T> tClass, T t);
|
||||
abstract Long inserteq(Class<T> tClass, T t);
|
||||
|
||||
abstract void insert(Class<T> tClass, List<T> list);
|
||||
abstract void insertnew(Class<T> tClass, List<T> list);
|
||||
|
||||
abstract void update(Class<T> tClass, T t);
|
||||
|
||||
abstract void update(Class<T> tClass, List<T> list);
|
||||
|
||||
abstract T query(Class<T> tClass, T key);
|
||||
|
||||
abstract List<T> queryList(Class<T> tClass);
|
||||
|
||||
abstract List<T> queryListIn(Class<T> tClass, String key, Object[] value);
|
||||
|
||||
abstract List<T> queryByKeyList(Class<T> tClass, String key, String value);
|
||||
|
||||
abstract List<T> queryByKeyListDesc(Class<T> tClass, String key, String value,String descStr);
|
||||
|
||||
abstract List<T> queryByKeyListAsc(Class<T> tClass, String key, String value,String ascStr);
|
||||
|
||||
abstract List<T> queryByValueList(Class<T> tClass, String[] key, String[] value);
|
||||
|
||||
abstract List<T> queryByValueListDesc(Class<T> tClass, String[] key, String[] value,String descStr);
|
||||
|
||||
abstract List<T> queryByValueListAsc(Class<T> tClass, String[] key, String[] value,String ascStr);
|
||||
|
||||
abstract List<T> queryByDateLt(Class<T> tClass, String key, long date);
|
||||
|
||||
|
||||
abstract void delete(Class<T> tClass, T t);
|
||||
|
||||
abstract void deleteAll(Class<T> tClass);
|
||||
|
||||
|
||||
abstract void deleteByKey(Class<T> tClass, Long keyValue);
|
||||
|
||||
abstract void deleteByList(Class<T> tClass, List<T> values);
|
||||
|
||||
}
|
||||
294
nebula-sdk/src/main/java/com/android/database/DaoManager.java
Normal file
294
nebula-sdk/src/main/java/com/android/database/DaoManager.java
Normal file
@@ -0,0 +1,294 @@
|
||||
package com.android.database;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import org.greenrobot.greendao.AbstractDao;
|
||||
import org.greenrobot.greendao.Property;
|
||||
import org.greenrobot.greendao.query.QueryBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DaoManager<T> extends AbstractDaoMannager<T> {
|
||||
private static DaoManager mInstance;
|
||||
private static DaoMaster mDaoMaster;
|
||||
|
||||
public static void initeDao(Context mContext) {
|
||||
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(mContext, "sofa-db", null);
|
||||
mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
|
||||
}
|
||||
|
||||
private DaoManager() {
|
||||
|
||||
}
|
||||
|
||||
public DaoMaster getMaster() {
|
||||
return mDaoMaster;
|
||||
}
|
||||
|
||||
|
||||
public static DaoManager getInstance() {
|
||||
if (mInstance == null) {
|
||||
mInstance = new DaoManager();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
private AbstractDao<T, T> getDao(Class<T> tClass) {
|
||||
try {
|
||||
return (AbstractDao<T, T>) mDaoMaster.newSession().getDao(tClass);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
// dao.delete(t);
|
||||
long id= dao.insertOrReplace(t);
|
||||
LogUtils.e( "postServerAppUpdate--->====insertOrReplace===>"+id);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Long inserteq(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
// dao.delete(t);
|
||||
long id= dao.insertOrReplace(t);
|
||||
LogUtils.e("postServerAppUpdate--->insertOrReplace===>"+id);
|
||||
return id;
|
||||
}
|
||||
|
||||
return -1L;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void insert(Class<T> tClass, List<T> list) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
dao.deleteAll();
|
||||
dao.insertOrReplaceInTx(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertnew(Class<T> tClass, List<T> list) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null) {
|
||||
dao.insertOrReplaceInTx(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
dao.update(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Class<T> tClass, List<T> list) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
dao.updateInTx(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T query(Class<T> tClass, T key) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
return dao.load(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryList(Class<T> tClass) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao != null)
|
||||
return dao.loadAll();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryListIn(Class<T> tClass, String key,Object[] value) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.in(value)).build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByKeyList(Class<T> tClass, String key, String value) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.eq(value)).build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByKeyListDesc(Class<T> tClass, String key, String value, String descStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.eq(value)).orderRaw(descStr+" DESC").build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByKeyListAsc(Class<T> tClass, String key, String value, String ascStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.eq(value)).orderRaw(ascStr+" ASC").build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByValueList(Class<T> tClass, String[] key, String[] value) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
QueryBuilder queryBuilder =dao.queryBuilder();
|
||||
|
||||
for (Property property : properties) {
|
||||
for (int i=0;i<key.length; i++){
|
||||
if (property.name.equals(key[i])) {
|
||||
queryBuilder.where(property.eq(value[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return queryBuilder.build().list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByValueListDesc(Class<T> tClass, String[] key, String[] value, String descStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
QueryBuilder queryBuilder =dao.queryBuilder();
|
||||
|
||||
for (Property property : properties) {
|
||||
for (int i=0;i<key.length; i++){
|
||||
if (property.name.equals(key[i])) {
|
||||
queryBuilder.where(property.eq(value[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return queryBuilder.orderRaw(descStr+" DESC").build().list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByValueListAsc(Class<T> tClass, String[] key, String[] value, String ascStr) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
QueryBuilder queryBuilder =dao.queryBuilder();
|
||||
|
||||
for (Property property : properties) {
|
||||
for (int i=0;i<key.length; i++){
|
||||
if (property.name.equals(key[i])) {
|
||||
queryBuilder.where(property.eq(value[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return queryBuilder.orderRaw(ascStr+" ASC").build().list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> queryByDateLt(Class<T> tClass, String key, long date) {
|
||||
|
||||
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return null;
|
||||
|
||||
Property[] properties = dao.getProperties();
|
||||
if (properties == null || properties.length == 0) return null;
|
||||
for (Property property : properties) {
|
||||
if (property.name.equals(key)) {
|
||||
return dao.queryBuilder().where(property.lt(date)).build().list();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Class<T> tClass, T t) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return;
|
||||
dao.delete(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(Class<T> tClass) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return;
|
||||
dao.deleteAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByKey(Class<T> tClass, Long keyValue) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return;
|
||||
dao.deleteByKey((T) keyValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByList(Class<T> tClass, List<T> values) {
|
||||
AbstractDao<T, T> dao = getDao(tClass);
|
||||
if (dao == null)
|
||||
return ;
|
||||
dao.deleteInTx(values);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.android.database.lib;
|
||||
|
||||
import org.greenrobot.greendao.annotation.Entity;
|
||||
import org.greenrobot.greendao.annotation.Generated;
|
||||
|
||||
@Entity
|
||||
public class DomainEntry {
|
||||
public String domains;
|
||||
public String type;
|
||||
|
||||
|
||||
@Generated(hash = 820333504)
|
||||
public DomainEntry(String domains, String type) {
|
||||
this.domains = domains;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Generated(hash = 2071904502)
|
||||
public DomainEntry() {
|
||||
}
|
||||
|
||||
|
||||
public String getDomains() {
|
||||
return domains;
|
||||
}
|
||||
|
||||
public void setDomains(String domains) {
|
||||
this.domains = domains;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
package com.android.database.lib;
|
||||
|
||||
|
||||
import org.greenrobot.greendao.annotation.Entity;
|
||||
import org.greenrobot.greendao.annotation.Generated;
|
||||
import org.greenrobot.greendao.annotation.Id;
|
||||
import org.greenrobot.greendao.annotation.Transient;
|
||||
|
||||
@Entity
|
||||
public class DownLoadTaskBean {
|
||||
private String url;
|
||||
private long start;
|
||||
private long end;
|
||||
private long total;
|
||||
/**文件类型*/
|
||||
protected String minType;
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
private int taskType;
|
||||
|
||||
|
||||
/**taskid*/
|
||||
@Id(autoincrement = true)
|
||||
private Long taskId;
|
||||
private String fileName;
|
||||
private String path;
|
||||
private long currentProgress;
|
||||
private int status = 0;//-1、未下载;0、下载中;1、下载完成
|
||||
|
||||
//@Transient:表明这个字段不会被写入数据库,只是作为一个普通的java类字段,用来临时存储数据的,不会被持久化
|
||||
@Transient
|
||||
private DownLoad2Listener listener;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Generated(hash = 517545372)
|
||||
public DownLoadTaskBean(String url, long start, long end, long total,
|
||||
String minType, int taskType, Long taskId, String fileName, String path,
|
||||
long currentProgress, int status) {
|
||||
this.url = url;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.total = total;
|
||||
this.minType = minType;
|
||||
this.taskType = taskType;
|
||||
this.taskId = taskId;
|
||||
this.fileName = fileName;
|
||||
this.path = path;
|
||||
this.currentProgress = currentProgress;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
|
||||
public String getMinType() {
|
||||
return minType;
|
||||
}
|
||||
|
||||
public void setMinType(String minType) {
|
||||
this.minType = minType;
|
||||
}
|
||||
|
||||
@Generated(hash = 949446503)
|
||||
public DownLoadTaskBean() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public int getTaskType() {
|
||||
return taskType;
|
||||
}
|
||||
|
||||
public void setTaskType(int taskType) {
|
||||
this.taskType = taskType;
|
||||
}
|
||||
|
||||
|
||||
public String getUrl() {
|
||||
return this.url;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getStart() {
|
||||
return this.start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setStart(long start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getEnd() {
|
||||
return this.end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setEnd(long end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getTotal() {
|
||||
return this.total;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setTotal(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public Long getTaskId() {
|
||||
return this.taskId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setTaskId(Long taskId) {
|
||||
this.taskId = taskId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public String getFileName() {
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public long getCurrentProgress() {
|
||||
return this.currentProgress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setCurrentProgress(long currentProgress) {
|
||||
this.currentProgress = currentProgress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public int getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public DownLoad2Listener getListener() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
public void setListener(DownLoad2Listener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
||||
public interface DownLoad2Listener {
|
||||
void onStart(long totalSize);
|
||||
|
||||
void onError(String error);
|
||||
|
||||
void onProgress(String fileName,long taskId,long progress);
|
||||
|
||||
void onFinish(String minType,String dowanloadUrl,String filePath, int taskType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.download;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Global executor pools for the whole application.
|
||||
* <p>
|
||||
* Grouping tasks like this avoids the effects of task starvation (e.g. disk reads don't wait behind
|
||||
* webservice requests).
|
||||
*/
|
||||
public class AppExecutors {
|
||||
private static AppExecutors appExecutors;
|
||||
private final Executor diskIO;
|
||||
|
||||
private final Executor networkIO;
|
||||
|
||||
private final Executor mainThread;
|
||||
|
||||
private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) {
|
||||
this.diskIO = diskIO;
|
||||
this.networkIO = networkIO;
|
||||
this.mainThread = mainThread;
|
||||
}
|
||||
|
||||
private AppExecutors() {
|
||||
this(Executors.newSingleThreadExecutor(), Executors.newFixedThreadPool(3),
|
||||
new MainThreadExecutor());
|
||||
}
|
||||
|
||||
public static AppExecutors getAppExecutors() {
|
||||
if (appExecutors == null)
|
||||
return new AppExecutors();
|
||||
else
|
||||
return appExecutors;
|
||||
}
|
||||
|
||||
public Executor diskIO() {
|
||||
return diskIO;
|
||||
}
|
||||
|
||||
public Executor networkIO() {
|
||||
return networkIO;
|
||||
}
|
||||
|
||||
public Executor mainThread() {
|
||||
return mainThread;
|
||||
}
|
||||
|
||||
private static class MainThreadExecutor implements Executor {
|
||||
private Handler mainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
mainThreadHandler.post(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
package com.android.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.database.DaoManager;
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.android.util.GsonUtil;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class DownLoadManeger {
|
||||
|
||||
private static DownLoadManeger instance;
|
||||
private boolean isAuto = false;
|
||||
|
||||
private DownloadListener mDownloadListener;
|
||||
|
||||
/**
|
||||
* 网络异常码
|
||||
*/
|
||||
protected static final int ERROR_CODE_NETWORK = -1;
|
||||
/**
|
||||
* 读写异常码
|
||||
*/
|
||||
protected static final int ERROR_CODE_WRITE = -2;
|
||||
/**
|
||||
* 存储空间不够异常码
|
||||
*/
|
||||
protected static final int ERROR_CODE_STORAGE_ENOUGH = -3;
|
||||
/**
|
||||
* URL格式异常
|
||||
*/
|
||||
protected static final int ERROR_CODE_MALFORMEDURL = -4;
|
||||
|
||||
|
||||
public void registerDownloadListener(DownloadListener downloadListener) {
|
||||
this.mDownloadListener = downloadListener;
|
||||
}
|
||||
|
||||
public void unRegisterDownloadListener(DownloadListener downloadListener) {
|
||||
this.mDownloadListener = null;
|
||||
}
|
||||
|
||||
private DownLoadManeger(Context context) {
|
||||
DaoManager.initeDao(context);
|
||||
}
|
||||
|
||||
public static DownLoadManeger init(Context context) {
|
||||
if (instance == null)
|
||||
instance = new DownLoadManeger(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static DownLoadManeger getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加新的下载任务
|
||||
*/
|
||||
public void addDownloadTask(DownloadBuilder builder) {
|
||||
if (TextUtils.isEmpty(builder.url)) {
|
||||
return;
|
||||
}
|
||||
DownLoadTaskBean downLoadTaskBean = null;
|
||||
if (!isExistTask(builder.url)) {
|
||||
downLoadTaskBean = createTaskBean(builder);
|
||||
LogUtils.e("postServerAppUpdate--->新下载任务");
|
||||
} else {
|
||||
File file = new File(builder.path, builder.name + ".tmp");
|
||||
if (file.exists()) {
|
||||
if (file.length() == builder.total) {
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在并下载完成");
|
||||
return;
|
||||
} else {
|
||||
downLoadTaskBean = createTaskBean(builder);
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在但未完成,当前进度:" + file.length() + "--->" + builder.total);
|
||||
}
|
||||
} else {
|
||||
downLoadTaskBean = createTaskBean(builder);
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在并下载完成");
|
||||
}
|
||||
}
|
||||
//添加下载任务队列
|
||||
if (!TaskQueue.getInstance().isExistTask(downLoadTaskBean)) {
|
||||
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中
|
||||
} else {
|
||||
LogUtils.e("postServerAppUpdate--->该下载任务已存在:" + GsonUtil.GsonString(downLoadTaskBean));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下载没有完成的任务管理
|
||||
*/
|
||||
public void restDownloadTask() {
|
||||
List<DownLoadTaskBean> list = DaoManager.getInstance().queryList(DownLoadTaskBean.class); //未完成下载的任务
|
||||
|
||||
LogUtils.e("postServerAppUpdate--->restDownloadTask DownloadTask:" + GsonUtil.GsonString(list));
|
||||
if (list.size() > 0) {
|
||||
LogUtils.e("postServerAppUpdate--->start download");
|
||||
for (DownLoadTaskBean downLoadTaskBean : list) {
|
||||
//添加下载任务队列
|
||||
if (!TaskQueue.getInstance().isExistTask(downLoadTaskBean)) {
|
||||
TaskQueue.getInstance().add(new DownLoadTaskThread(downLoadTaskBean, observer));//添加到下载队列中
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LogUtils.e("postServerAppUpdate--->no download task");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除任务队列
|
||||
*/
|
||||
public void clear() {
|
||||
TaskQueue.getInstance().clear();
|
||||
}
|
||||
|
||||
public boolean isExistTask(String url) {//判断是否存在下载任务
|
||||
List<DownLoadTaskBean> downLoadTaskBeans = DaoManager.getInstance().queryByKeyList(DownLoadTaskBean.class, "url", url);
|
||||
if (downLoadTaskBeans != null && downLoadTaskBeans.size() == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private DownLoadTaskBean createTaskBean(DownloadBuilder builder) {//创建下载任务bean和创建下载任务
|
||||
DownLoadTaskBean bean = new DownLoadTaskBean();
|
||||
bean.setFileName(builder.name);
|
||||
bean.setPath(builder.path);
|
||||
bean.setUrl(builder.url);
|
||||
bean.setTaskId(System.currentTimeMillis());
|
||||
bean.setListener(builder.listener);
|
||||
bean.setTotal(builder.total);
|
||||
bean.setMinType(builder.minType);
|
||||
bean.setTaskType(builder.taskType);
|
||||
DownLoadTaskThread task = new DownLoadTaskThread(bean, observer);
|
||||
DaoManager.getInstance().insert(DownLoadTaskBean.class, bean);//保存到数据库
|
||||
return bean;
|
||||
}
|
||||
|
||||
|
||||
//自动下载
|
||||
public void setAutoDownLoad(boolean isAuto) {
|
||||
this.isAuto = isAuto;
|
||||
}
|
||||
|
||||
public void pauseAll() {//全部暂停
|
||||
TaskQueue.getInstance().pause();
|
||||
}
|
||||
|
||||
|
||||
public static class DownloadBuilder {//构造器
|
||||
protected String url;//下载地址
|
||||
protected String path;//下载路径
|
||||
protected String name;//文件名字
|
||||
protected long total;//现在总进度
|
||||
/**
|
||||
* 文件类型
|
||||
*/
|
||||
protected String minType;
|
||||
/**
|
||||
* 任务类型
|
||||
*/
|
||||
protected int taskType;
|
||||
protected DownLoadTaskBean.DownLoad2Listener listener;//下载监听
|
||||
|
||||
|
||||
public DownloadBuilder setMinType(String minType) {
|
||||
this.minType = minType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder url(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder filePath(String path) {
|
||||
this.path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder listener(DownLoadTaskBean.DownLoad2Listener listener) {
|
||||
this.listener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder fileName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder taskType(int taskType) {
|
||||
this.taskType = taskType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DownloadBuilder fileTotal(long fileSize) {
|
||||
this.total = fileSize;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface DownloadListener {
|
||||
public void onStart(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
public void onError(DownLoadTaskBean bean, long taskId, String erroMsg);
|
||||
|
||||
public void onProgress(DownLoadTaskBean bean, long taskId, long progress, long total);
|
||||
|
||||
public void onFinish(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//下载线程的观察者
|
||||
private DownLoadTaskThread.DownloadTaskObserver observer = new DownLoadTaskThread.DownloadTaskObserver() {
|
||||
@Override
|
||||
protected void onStart(DownLoadTaskBean bean, long taskId) {//下载开始,回调总进度给监听,方便设置进度大小
|
||||
LogUtils.e("postServerAppUpdate--->taskId=" + taskId + ">>>>>" + bean.getTotal());
|
||||
bean.setStatus(0);
|
||||
AppExecutors.getAppExecutors().mainThread().execute(() -> {//切换到主线程
|
||||
if (bean.getListener() != null) {
|
||||
bean.getListener().onStart(bean.getTotal());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgress(DownLoadTaskBean bean, long taskId, long progress, long total) {//进度调用
|
||||
synchronized (this) {//这里必须加同步代码块,因为这共用进度等变量
|
||||
|
||||
if (mDownloadListener != null) {
|
||||
mDownloadListener.onProgress(bean, taskId, progress, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish(DownLoadTaskBean bean, long taskId, long lastProgress) {
|
||||
synchronized (this) {
|
||||
TaskQueue.getInstance().remove(bean);//单个任务完成删除
|
||||
// DaoManager.getInstance().delete(DownLoadTaskBean.class, bean);
|
||||
if (mDownloadListener != null) {
|
||||
mDownloadListener.onFinish(bean, taskId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause(DownLoadTaskBean bean, long taskId, long currentProgress) {
|
||||
synchronized (this) {//暂停这里必须加上同步,不然会出现实际进度跟显示进度不一致问题,其实也就是缓存没存进去,第二个线程又来了
|
||||
// DaoManager.getInstance().update(DownLoadTaskBean.class, bean);//更新数据库,退出app再进来就不会从头下载
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onError(DownLoadTaskBean bean, long taskId, String erroMsg, int errorCode) {//错误提示
|
||||
TaskQueue.getInstance().remove(bean);
|
||||
switch (errorCode) {
|
||||
case ERROR_CODE_NETWORK:
|
||||
break;
|
||||
case ERROR_CODE_WRITE:
|
||||
case ERROR_CODE_MALFORMEDURL:
|
||||
case ERROR_CODE_STORAGE_ENOUGH:
|
||||
DaoManager.getInstance().delete(DownLoadTaskBean.class, bean);//删除数据库缓存
|
||||
File file = new File(bean.getPath(), bean.getFileName() + "-tmp"); //下载异常时删除临时文件
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
LogUtils.e("postServerAppUpdate--->errmsg:" + erroMsg);
|
||||
if (mDownloadListener != null) {
|
||||
mDownloadListener.onError(bean, taskId, erroMsg);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
package com.android.download;
|
||||
|
||||
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
|
||||
public class DownLoadTaskThread implements Runnable {
|
||||
private boolean pause;
|
||||
private DownLoadTaskBean bean;
|
||||
private long currentTotal = 0L;
|
||||
private DownloadTaskObserver observer;
|
||||
|
||||
public DownLoadTaskThread(DownLoadTaskBean bean, DownloadTaskObserver observer) {
|
||||
this.bean = bean;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
HttpURLConnection urlConnection = null;
|
||||
RandomAccessFile randomFile = null;
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
URL url = new URL(bean.getUrl());
|
||||
urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setConnectTimeout(20000); //设置连接超时事件为20秒
|
||||
urlConnection.setRequestMethod("GET"); //设置请求方式为GET
|
||||
//设置用户端可以接收的媒体类型
|
||||
urlConnection.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, " +
|
||||
"image/pjpeg, application/x-shockwave-flash, application/xaml+xml, " +
|
||||
"application/vnd.ms-xpsdocument, application/x-ms-xbap," +
|
||||
" application/x-ms-application, application/vnd.ms-excel," +
|
||||
" application/vnd.ms-powerpoint, application/msword, */*");
|
||||
|
||||
urlConnection.setRequestProperty("Accept-Language", "zh-CN"); //设置用户语言
|
||||
urlConnection.setRequestProperty("Charset", "UTF-8"); //设置客户端编码
|
||||
// //设置用户代理
|
||||
urlConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; " +
|
||||
"Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727;" +
|
||||
" .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
|
||||
|
||||
File dataFile = new File(bean.getPath(), bean.getFileName());
|
||||
if (dataFile.exists() && dataFile.length() == bean.getTotal()) { //判断该文件已下载无需再下载
|
||||
observer.onFinish(bean, bean.getTaskId(), dataFile.length());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//设置文件写入位置
|
||||
File file = new File(bean.getPath(), bean.getFileName() + ".tmp");
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
currentTotal = file.length();
|
||||
LogUtils.e("postServerAppUpdate--->downloadFile:" + bean.getPath() + "---->" + bean.getFileName() + "|" + bean.getStart()
|
||||
+ "start------" + currentTotal + ">>>>" + bean.getTotal());
|
||||
if (currentTotal == bean.getTotal()) {
|
||||
LogUtils.e("postServerAppUpdate--->下载完成");
|
||||
File targFile = new File(bean.getPath(), bean.getFileName());
|
||||
file.renameTo(targFile);//重命名
|
||||
file.delete();//删除临时文件
|
||||
observer.onFinish(bean, bean.getTaskId(), currentTotal);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentTotal > bean.getTotal()) {
|
||||
observer.onError(bean, bean.getTaskId(), "文件超出下载长度,下载异常", DownLoadManeger.ERROR_CODE_WRITE);
|
||||
return;
|
||||
}
|
||||
|
||||
long beginIndex = 0L;
|
||||
if (currentTotal == 0L) {
|
||||
beginIndex = 0L;
|
||||
} else {
|
||||
beginIndex = currentTotal - 1;
|
||||
}
|
||||
//设置下载位置
|
||||
urlConnection.setRequestProperty("Range", "bytes=" + beginIndex + "-" + (bean.getTotal() - 1));
|
||||
|
||||
randomFile = new RandomAccessFile(file, "rwd");
|
||||
LogUtils.e("postServerAppUpdate--->download onProgress:seek currentTotal--->" + beginIndex);
|
||||
randomFile.seek(beginIndex);
|
||||
|
||||
urlConnection.connect();
|
||||
if (observer != null) {
|
||||
observer.onStart(bean, bean.getTaskId());
|
||||
}
|
||||
|
||||
//获得文件流
|
||||
inputStream = urlConnection.getInputStream();
|
||||
byte[] buffer = new byte[1024 * 10];
|
||||
int len;
|
||||
long time = System.currentTimeMillis();
|
||||
while ((currentTotal != bean.getTotal()) && (len = inputStream.read(buffer)) != -1) {
|
||||
//写入文件
|
||||
randomFile.write(buffer, 0, len);
|
||||
currentTotal += len;
|
||||
//时间间隔大于500ms再发
|
||||
if (System.currentTimeMillis() - time > 5000) {
|
||||
time = System.currentTimeMillis();
|
||||
observer.onProgress(bean, bean.getTaskId(), currentTotal, bean.getTotal());
|
||||
}
|
||||
//判断是否是暂停状态.保存断点
|
||||
if (observer != null && pause) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
urlConnection.disconnect();
|
||||
urlConnection = null;
|
||||
randomFile.close();
|
||||
randomFile = null;
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
|
||||
observer.onProgress(bean, bean.getTaskId(), currentTotal, bean.getTotal());
|
||||
|
||||
if (observer != null && !pause) {
|
||||
if (currentTotal >= bean.getTotal()) {
|
||||
LogUtils.e("postServerAppUpdate--->下载完成");
|
||||
File targFile = new File(bean.getPath(), bean.getFileName());
|
||||
file.renameTo(targFile);//重命名
|
||||
file.delete();//删除临时文件
|
||||
observer.onFinish(bean, bean.getTaskId(), currentTotal);
|
||||
} else {
|
||||
LogUtils.e("postServerAppUpdate--->" + currentTotal + "|" + bean.getTotal() + "下载失败" + bean.getFileName());
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "下载失败,文件大小不一致", DownLoadManeger.ERROR_CODE_WRITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// LogUtils.loge("download Exception===>"+e.getMessage());
|
||||
// if (observer != null) {
|
||||
//// observer.onError(bean, bean.getTaskId(), e.getMessage());
|
||||
// }
|
||||
// }
|
||||
catch (FileNotFoundException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "文件无法创建或写入:" + e.getMessage(), DownLoadManeger.ERROR_CODE_WRITE);
|
||||
}
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "URL格式错误:" + e.getMessage(), DownLoadManeger.ERROR_CODE_MALFORMEDURL);
|
||||
}
|
||||
|
||||
} catch (SocketTimeoutException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "连接或读取超时:" + e.getMessage(), DownLoadManeger.ERROR_CODE_NETWORK);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (observer != null) {
|
||||
observer.onError(bean, bean.getTaskId(), "下载时IO 读写异常:" + e.getMessage(), DownLoadManeger.ERROR_CODE_NETWORK);//判定为网络异常,以便下次开机可以启动断点续传功能
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (urlConnection != null) {
|
||||
urlConnection.disconnect();
|
||||
urlConnection = null;
|
||||
}
|
||||
try {
|
||||
if (randomFile != null) {
|
||||
randomFile.close();
|
||||
randomFile = null;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DownLoadTaskBean getBean() {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void setBean(DownLoadTaskBean bean) {
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
public void setPause(boolean pause) {
|
||||
this.pause = pause;
|
||||
}
|
||||
|
||||
|
||||
protected static abstract class DownloadTaskObserver {
|
||||
|
||||
protected abstract void onStart(DownLoadTaskBean bean, long taskId);
|
||||
|
||||
protected abstract void onProgress(DownLoadTaskBean bean, long taskId, long progress, long total);
|
||||
|
||||
protected abstract void onFinish(DownLoadTaskBean bean, long taskId, long lastProgress);
|
||||
|
||||
protected abstract void onPause(DownLoadTaskBean bean, long taskId, long currentProgress);
|
||||
|
||||
protected abstract void onError(DownLoadTaskBean bean, long taskId, String erroMsg, int errorCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
package com.android.download;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.api.CoreKeys;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class DownloadService {
|
||||
|
||||
/**
|
||||
* 是否正在下载
|
||||
*/
|
||||
private boolean isDownloading = false;
|
||||
public static int progress;
|
||||
private String dowUrl = null;
|
||||
//下载状态
|
||||
private int status = -1;
|
||||
private int fileSize;
|
||||
private int readSize;
|
||||
private int downSize;
|
||||
private File downFile;
|
||||
private static DownloadService mInstance = null;
|
||||
private DownlaodProgressCallBack mDownlaodProgressCallBack;
|
||||
/**
|
||||
* 下载完成状态
|
||||
*/
|
||||
public static final int DOWNLOAD_COMPLETE = 0;
|
||||
/**
|
||||
* 下载完成状态
|
||||
*/
|
||||
public static final int DOWNLOAD_ERROR = -1;
|
||||
public static final String FEATURE_PATH = CoreKeys.down_file + "atv.apk";
|
||||
private Handler handler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
super.handleMessage(msg);
|
||||
switch (msg.what) {
|
||||
case 0:
|
||||
// //更新下载进度
|
||||
if (mDownlaodProgressCallBack != null) {
|
||||
int progress = (int) ((double) downSize / (double) fileSize * 100);
|
||||
mDownlaodProgressCallBack.onDownlaodProgress(progress);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
//下载完成进度
|
||||
mDownlaodProgressCallBack.onDownlaodStatus(DOWNLOAD_COMPLETE);
|
||||
break;
|
||||
case 2:
|
||||
//下载异常
|
||||
mDownlaodProgressCallBack.onDownlaodStatus(DOWNLOAD_ERROR);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private DownloadService() {
|
||||
}
|
||||
|
||||
public static DownloadService initDownloadService() {
|
||||
if (mInstance == null) {
|
||||
mInstance = new DownloadService();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public static DownloadService getInstance() {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public void initDownLoadUrl(String downloadUrl) {
|
||||
dowUrl = downloadUrl;
|
||||
}
|
||||
|
||||
public void setDownlaodProgressCallBack(DownlaodProgressCallBack downlaodProgressCallBack) {
|
||||
this.mDownlaodProgressCallBack = downlaodProgressCallBack;
|
||||
}
|
||||
|
||||
|
||||
public void startService() {
|
||||
if (isDownloading) {
|
||||
return;
|
||||
}
|
||||
new Thread(startDownload).start();
|
||||
}
|
||||
|
||||
public void stopService() {
|
||||
isDownloading = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载模块
|
||||
*/
|
||||
private Runnable startDownload = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
fileSize = 0;
|
||||
readSize = 0;
|
||||
downSize = 0;
|
||||
progress = 0;
|
||||
|
||||
InputStream is = null;
|
||||
FileOutputStream fos = null;
|
||||
LogUtils.e("postServerAppUpdate--->downUrl:" + dowUrl);
|
||||
try {
|
||||
URL myURL = new URL(dowUrl);
|
||||
URLConnection conn = myURL.openConnection();
|
||||
conn.connect();
|
||||
fileSize = conn.getContentLength();
|
||||
is = conn.getInputStream();
|
||||
|
||||
if (is == null) {
|
||||
Log.d("tag", "error");
|
||||
throw new RuntimeException("stream is null");
|
||||
}
|
||||
|
||||
File dir = new File(CoreKeys.down_file);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
downFile = new File(FEATURE_PATH);
|
||||
fos = new FileOutputStream(downFile);
|
||||
byte buf[] = new byte[1024 * 1024];
|
||||
isDownloading = true;
|
||||
while ((readSize = is.read(buf)) > 0) {
|
||||
if (!isDownloading) {
|
||||
return;
|
||||
}
|
||||
fos.write(buf, 0, readSize);
|
||||
downSize += readSize;
|
||||
Log.e("downSize", downSize + "");
|
||||
sendMessage(0, downSize);
|
||||
}
|
||||
sendMessage(1);
|
||||
isDownloading = false;
|
||||
|
||||
} catch (Exception e) {
|
||||
sendMessage(2);
|
||||
} finally {
|
||||
try {
|
||||
if (null != fos) fos.close();
|
||||
if (null != is) is.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private void sendMessage(int code) {
|
||||
handler.sendEmptyMessage(code);
|
||||
}
|
||||
|
||||
private void sendMessage(int code, int progress) {
|
||||
Message message = new Message();
|
||||
message.what = code;
|
||||
message.arg1 = progress;
|
||||
handler.sendMessage(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取进度
|
||||
*/
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public interface DownlaodProgressCallBack {
|
||||
|
||||
public void onDownlaodProgress(int progress);
|
||||
|
||||
public void onDownlaodStatus(int status);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
90
nebula-sdk/src/main/java/com/android/download/TaskQueue.java
Normal file
90
nebula-sdk/src/main/java/com/android/download/TaskQueue.java
Normal file
@@ -0,0 +1,90 @@
|
||||
package com.android.download;
|
||||
|
||||
|
||||
import com.android.database.lib.DownLoadTaskBean;
|
||||
import com.android.util.GsonUtil;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class TaskQueue {
|
||||
private static TaskQueue instance;
|
||||
private List<DownLoadTaskThread> mTaskQueue;
|
||||
private ExecutorService downloadThreadCache = Executors.newFixedThreadPool(3);//这里是写死最多5个线程
|
||||
|
||||
private TaskQueue() {
|
||||
mTaskQueue = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return mTaskQueue.size();
|
||||
}
|
||||
|
||||
public static TaskQueue getInstance() {
|
||||
if (instance == null)
|
||||
instance = new TaskQueue();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public List<DownLoadTaskThread> getAllTask() {
|
||||
return mTaskQueue;
|
||||
}
|
||||
|
||||
public void add(DownLoadTaskThread task) {
|
||||
mTaskQueue.add(task);
|
||||
downloadThreadCache.execute(task);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
mTaskQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void remove(DownLoadTaskBean p) {
|
||||
for (int i = 0; i < mTaskQueue.size(); i++) {
|
||||
DownLoadTaskThread task = mTaskQueue.get(i);
|
||||
if (task.getBean().getUrl().equals(p.getUrl())) {
|
||||
mTaskQueue.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isExistTask(DownLoadTaskBean p) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
LogUtils.e("postServerAppUpdate--->isExistTask111:"+ GsonUtil.GsonString(task));
|
||||
LogUtils.e("postServerAppUpdate--->isExistTask222:"+ GsonUtil.GsonString(p));
|
||||
if (task.getBean().getUrl().equals(p.getUrl()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void pause(String url) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
if (task.getBean().getUrl().equals(url)) {
|
||||
task.setPause(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
task.setPause(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void start(String url) {
|
||||
for (DownLoadTaskThread task : mTaskQueue) {
|
||||
if (task.getBean().getUrl().equals(url)) {
|
||||
task.setPause(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
nebula-sdk/src/main/java/com/android/nebulasdk/DConfig.java
Normal file
16
nebula-sdk/src/main/java/com/android/nebulasdk/DConfig.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.android.nebulasdk;
|
||||
|
||||
public class DConfig {
|
||||
|
||||
|
||||
public static final String ALLWINNER_PLM="allwinner";
|
||||
public static final String RK_PLM="rockchip";
|
||||
public static final String ARMLOGIC_PLM="amlogic";
|
||||
|
||||
public static final int API_VERSION_CODE=105;
|
||||
// public static final int API_VERSION_CODE=47;
|
||||
public static String PLATFORM_TAG=RK_PLM;
|
||||
|
||||
/**请求密钥*/
|
||||
public static final String REQUEST_SINGKEY="jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47";
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class AppInfoBean extends BaseValue{
|
||||
private int infraFileId;
|
||||
private String url;
|
||||
private long size;
|
||||
private String packageName;
|
||||
private int versionCode;
|
||||
private String versionName;
|
||||
private String platform;
|
||||
|
||||
public int getInfraFileId() {
|
||||
return infraFileId;
|
||||
}
|
||||
|
||||
public void setInfraFileId(int infraFileId) {
|
||||
this.infraFileId = infraFileId;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(long size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public int getVersionCode() {
|
||||
return versionCode;
|
||||
}
|
||||
|
||||
public void setVersionCode(int versionCode) {
|
||||
this.versionCode = versionCode;
|
||||
}
|
||||
|
||||
public String getVersionName() {
|
||||
return versionName;
|
||||
}
|
||||
|
||||
public void setVersionName(String versionName) {
|
||||
this.versionName = versionName;
|
||||
}
|
||||
|
||||
public String getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public void setPlatform(String platform) {
|
||||
this.platform = platform;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class AppUpdateResponse extends BaseBean{
|
||||
public String data;
|
||||
|
||||
public String getData(){
|
||||
return data;
|
||||
}
|
||||
public void setData(String data){
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
/**
|
||||
* Created by Administrator on 2018/5/11 0011.
|
||||
*/
|
||||
|
||||
public class BaseBean extends BaseValue {
|
||||
|
||||
public String msg;
|
||||
public int code;
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class BaseValue implements Serializable {
|
||||
|
||||
public BaseValue() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class DomainBean {
|
||||
private int type;
|
||||
private String domainNames;
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDomainNames() {
|
||||
return domainNames;
|
||||
}
|
||||
|
||||
public void setDomainNames(String domainNames) {
|
||||
this.domainNames = domainNames;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class TimeBean extends BaseBean{
|
||||
private long time;
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.android.nebulasdk.bean;
|
||||
|
||||
public class TimeResponse extends BaseBean{
|
||||
private TimeBean data;
|
||||
|
||||
public TimeBean getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(TimeBean data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
138
nebula-sdk/src/main/java/com/android/util/BitmapUtils.java
Normal file
138
nebula-sdk/src/main/java/com/android/util/BitmapUtils.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class BitmapUtils {
|
||||
|
||||
|
||||
/**
|
||||
* drawable to bitmap
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap drawableToBitmap(Drawable drawable){
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
drawable.setBounds(0,0,width,height);
|
||||
|
||||
Bitmap.Config config = drawable.getOpacity()!= PixelFormat.OPAQUE?Bitmap.Config.ARGB_8888:Bitmap.Config.RGB_565;
|
||||
Bitmap bitmap =Bitmap.createBitmap(width,height,config);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.draw(canvas);
|
||||
|
||||
return setRoundCornerBitmap(bitmap,10);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* drawable to bitmap
|
||||
* @param drawable
|
||||
* @return
|
||||
*/
|
||||
public static Bitmap drawableToBitmap(Drawable drawable,int mwidth, int mheight){
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
drawable.setBounds(0,0,width,height);
|
||||
|
||||
Bitmap.Config config = drawable.getOpacity()!= PixelFormat.OPAQUE?Bitmap.Config.ARGB_8888:Bitmap.Config.RGB_565;
|
||||
Bitmap bitmap =Bitmap.createBitmap(mwidth,mheight,config);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.draw(canvas);
|
||||
|
||||
return setRoundCornerBitmap(bitmap,10);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* drawable to bitmap
|
||||
* @return
|
||||
*/
|
||||
public static Drawable getWidthCircleBitmapbg(){
|
||||
|
||||
Bitmap dest = Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Canvas c = new Canvas(dest);
|
||||
|
||||
PaintFlagsDrawFilter pfd = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); //画图片时设置画布抗锯齿
|
||||
c.setDrawFilter(pfd);
|
||||
|
||||
Paint paint = new Paint();
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
paint.setColor(Color.GREEN);
|
||||
|
||||
c.drawCircle(50/2,50/2, 50/2, paint);
|
||||
|
||||
return new BitmapDrawable(dest);
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap setRoundCornerBitmap(Bitmap bitmap,float roundPx){
|
||||
int width = bitmap.getWidth();
|
||||
int height = bitmap.getHeight();
|
||||
|
||||
Bitmap outmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(outmap);
|
||||
final int color = 0xff424242;
|
||||
final Paint paint = new Paint();
|
||||
final Rect rect = new Rect(0,0,width,height);
|
||||
final RectF rectf = new RectF(rect);
|
||||
paint.setAntiAlias(true);
|
||||
canvas.drawARGB(0,0,0,0);
|
||||
paint.setColor(color);
|
||||
canvas.drawRoundRect(rectf,roundPx,roundPx,paint);
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
||||
canvas.drawBitmap(bitmap,rect,rect,paint);
|
||||
return outmap;
|
||||
}
|
||||
|
||||
|
||||
public static Bitmap getIconByPackageName(Context mContext,String packageName){
|
||||
|
||||
try {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);
|
||||
Drawable iconDrawable = applicationInfo.loadIcon(pm);//应用图标
|
||||
return BitmapUtils.drawableToBitmap(iconDrawable);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Bitmap getIconByPackageName(Context mContext,String packageName,int mwidth, int mheight){
|
||||
|
||||
try {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, 0);
|
||||
Drawable iconDrawable = applicationInfo.loadIcon(pm);//应用图标
|
||||
return BitmapUtils.drawableToBitmap(iconDrawable, mwidth, mheight);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
20
nebula-sdk/src/main/java/com/android/util/CommonUtils.java
Normal file
20
nebula-sdk/src/main/java/com/android/util/CommonUtils.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
|
||||
public class CommonUtils {
|
||||
|
||||
public static boolean isServiceRunning(Context context,Class<?> serviceClass) {
|
||||
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
assert manager != null;
|
||||
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||
if (serviceClass.getName().equals(service.service.getClassName())) {
|
||||
return true; // 服务已存在
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
21
nebula-sdk/src/main/java/com/android/util/DConfig.java
Normal file
21
nebula-sdk/src/main/java/com/android/util/DConfig.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.android.util;
|
||||
|
||||
public class DConfig {
|
||||
|
||||
|
||||
public static final String ALLWINNER_PLM = "allwinner";
|
||||
public static final String RK_PLM = "rk";
|
||||
public static final String ARMLOGIC_PLM = "armlogic";
|
||||
|
||||
/**
|
||||
* 当版本为47时,singKey为jdh2dh7hdbhu3hbfcyHvdhf87NFH67b47,encryptionKey为1234567887654347;
|
||||
* 版本为48时,singKey为jdh2dh7hdbhu3hbfcyHvdhf87NFH67b48,encryptionKey为1234567887654348
|
||||
*/
|
||||
public static final String API_VERSION_CODE = "47";
|
||||
|
||||
/**
|
||||
* 默认域名
|
||||
*/
|
||||
public static final String DOMAIN_HOST = "api.yudao.iocoder.cn";
|
||||
public static String PLATFORM_TAG = RK_PLM;
|
||||
}
|
||||
423
nebula-sdk/src/main/java/com/android/util/DateUtil.java
Normal file
423
nebula-sdk/src/main/java/com/android/util/DateUtil.java
Normal file
@@ -0,0 +1,423 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class DateUtil {
|
||||
/**
|
||||
* 预设不同的时间格式
|
||||
*/
|
||||
//精确到年月日(英文) eg:2019-12-31
|
||||
public static String FORMAT_LONOGRAM = "yyyy-MM-dd";
|
||||
|
||||
public static String FORMAT_LONOGRAM01 = "yyyyMMdd";
|
||||
|
||||
//精确到时分秒的完整时间(英文) eg:2010-11-11 12:12:12
|
||||
public static String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
|
||||
//精确到毫秒完整时间(英文) eg:2019-11-11 12:12:12.55
|
||||
public static String FORMAT_LONOGRAM_MILL = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
//精确到年月日(中文)eg:2019年11月11日
|
||||
public static String FORMAT_LONOGRAM_CN = "yyyy年MM月dd日";
|
||||
//精确到时分秒的完整时间(中文)eg:2019年11月11日 12时12分12秒
|
||||
public static String FORMAT_FULL_CN = "yyyy年MM月dd日 HH时MM分SS秒";
|
||||
//精确到毫秒完整时间(中文)
|
||||
public static String FORMAT_LONOGRAM_MILL_CN = "yyyy年MM月dd日HH时MM分SS秒SSS毫秒";
|
||||
/**
|
||||
* 预设默认的时间格式
|
||||
*/
|
||||
public static String getDefaultFormat() {
|
||||
return FORMAT_FULL;
|
||||
}
|
||||
/**
|
||||
* 预设格式格式化日期
|
||||
*/
|
||||
public static String format(Date date) {
|
||||
return format(date,getDefaultFormat());
|
||||
}
|
||||
/**
|
||||
* 自定义格式格式化日期
|
||||
*/
|
||||
public static String format(Date date, String format) {
|
||||
String value = "";
|
||||
if(date != null) {
|
||||
TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
sdf.setTimeZone(timeZone);
|
||||
value = sdf.format(date);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* 根据预设默认格式,返回当前日期
|
||||
*/
|
||||
public static String getNow() {
|
||||
return format(new Date());
|
||||
}
|
||||
/**
|
||||
* 自定义时间格式,返回当前日期
|
||||
*/
|
||||
public static String getNow(String format) {
|
||||
return format(new Date(),format);
|
||||
}
|
||||
/**
|
||||
*根据预设默认时间 String->Date
|
||||
*/
|
||||
public static Date parse(String strDate) {
|
||||
return parse(strDate,getDefaultFormat());
|
||||
}
|
||||
|
||||
|
||||
public static String getNowTime() {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
return simpleDateFormat.format(date);
|
||||
}
|
||||
public static String getNowDate() {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM");
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
return simpleDateFormat.format(date);
|
||||
}
|
||||
public static String getNowWeek() {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE");
|
||||
Date date = new Date(System.currentTimeMillis());
|
||||
return simpleDateFormat.format(date);
|
||||
}
|
||||
|
||||
public static String getAm() {
|
||||
String am="";
|
||||
long time = System.currentTimeMillis();
|
||||
final Calendar mCalendar = Calendar.getInstance();
|
||||
mCalendar.setTimeInMillis(time);
|
||||
int apm = mCalendar.get(Calendar.AM_PM);
|
||||
if (apm == 0) {
|
||||
am="AM";
|
||||
} else if (apm == 1) {
|
||||
am="PM";
|
||||
}
|
||||
Log.d("getam","am value"+am);
|
||||
return am;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 自定义时间格式:Stirng->Date
|
||||
*/
|
||||
public static Date parse(String strDate,String format) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(format);
|
||||
try {
|
||||
TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
|
||||
sdf.setTimeZone(timeZone);
|
||||
return sdf.parse(strDate);
|
||||
}catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加年
|
||||
* @param num 正数往后推,负数往前移
|
||||
* Calendar:它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR
|
||||
* 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
|
||||
*/
|
||||
public static Date addYear(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.YEAR, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加整月
|
||||
* @param date
|
||||
* @param num 整数往后推,负数往前移
|
||||
* @return
|
||||
*/
|
||||
public static Date addMonth(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.MONTH, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加天数
|
||||
* @param date
|
||||
* @param num 整数往后推,负数往前移
|
||||
* @return
|
||||
*/
|
||||
public static Date addDay(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.DATE, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 基于指定日期增加分钟
|
||||
* @param date
|
||||
* @param num 整数往后推,负数往前移
|
||||
* @return
|
||||
*/
|
||||
public static Date addMinute(Date date,int num) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.add(Calendar.MINUTE, num);
|
||||
return cal.getTime();
|
||||
}
|
||||
/**
|
||||
* 获取时间戳 eg:yyyy-MM-dd HH:mm:ss.S
|
||||
* @return
|
||||
*/
|
||||
public static String getTimeStamp() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_LONOGRAM_MILL);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
return sdf.format(cal.getTime());
|
||||
}
|
||||
/**
|
||||
* 获取日期的年份
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getYear(Date date) {
|
||||
return format(date).substring(0,4);
|
||||
}
|
||||
/**
|
||||
* 获取年份+月
|
||||
*/
|
||||
public static String getYearMonth(Date date) {
|
||||
return format(date).substring(0, 7);
|
||||
}
|
||||
/**
|
||||
*获取日期的小时数
|
||||
*/
|
||||
public static int getHour(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
return cal.get(Calendar.HOUR_OF_DAY);
|
||||
}
|
||||
/**
|
||||
* 自定义时间格式字符串距离今天的天数
|
||||
* @param strDate
|
||||
* @param format
|
||||
* @return
|
||||
*/
|
||||
public static int countDays(String strDate,String format) {
|
||||
long time = Calendar.getInstance().getTime().getTime();
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(parse(strDate,format));
|
||||
long diff = cal.getTime().getTime();
|
||||
long a = time/1000;
|
||||
long b = diff/1000;
|
||||
return (int) (a - b)/3600/24;
|
||||
}
|
||||
/**
|
||||
* 预设格式的字符串距离今天的天数
|
||||
* @param strDate
|
||||
* @return
|
||||
*/
|
||||
public static int countDays(String strDate) {
|
||||
return countDays(strDate,getDefaultFormat());
|
||||
}
|
||||
/**
|
||||
* 获取天数差值(依赖时间)
|
||||
* @param date1
|
||||
* @param date2
|
||||
* @return
|
||||
*/
|
||||
public static int diffDays(Date date1,Date date2) {
|
||||
if(date1 == null || date2 == null) {
|
||||
return 0;
|
||||
}
|
||||
return (int) (Math.abs(date1.getTime() - date2.getTime()) / (60 * 60 * 24 * 1000));
|
||||
}
|
||||
/**
|
||||
* 获取年份差值
|
||||
* @param year1
|
||||
* @param year2
|
||||
* @return
|
||||
*/
|
||||
public static int diffYear(Date year1,Date year2) {
|
||||
return diffDays(year1,year2) / 365;
|
||||
}
|
||||
/**
|
||||
* 获取天数差值(依赖Date类型的日期)
|
||||
* @param d1
|
||||
* @param d2
|
||||
* @return
|
||||
*/
|
||||
public static int diffByDays(Date d1,Date d2) {
|
||||
Date s1 = parse(format(d1,FORMAT_LONOGRAM),FORMAT_LONOGRAM);
|
||||
Date s2 = parse(format(d2,FORMAT_LONOGRAM),FORMAT_LONOGRAM);
|
||||
return diffDays(s1,s2);
|
||||
}
|
||||
// /**
|
||||
// * 获取时间分割集合
|
||||
// *
|
||||
// * @param date 查询日期
|
||||
// * @param strs 带拆分的时间点
|
||||
// * @return
|
||||
// */
|
||||
// public static List<Date> collectTimes(Date date, String[] strs){
|
||||
// List<Date> result = new ArrayList<Date>();
|
||||
// List<String> times = Arrays.asList(strs);
|
||||
// String dateStr = format(date,FORMAT_LONOGRAM);
|
||||
// String pattern = FORMAT_LONOGRAM + "K";
|
||||
// if(times.size() > 0 ) {
|
||||
// times.stream().forEach(t -> {
|
||||
// result.add(parse(date +" "+ t,pattern));
|
||||
// });
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 根据日期查询当前为周几
|
||||
* @param dt
|
||||
* @return
|
||||
*/
|
||||
public static String getWeekOfDate(Date dt) {
|
||||
String[] weekDays = {"7","1","2","3","4","5","6"};
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(dt);
|
||||
int w = cal.get(Calendar.DAY_OF_WEEK); //1--7的值,对应:星期日,星期一,星期二,星期三....星期六
|
||||
//System.out.println(w);
|
||||
return weekDays[w-1];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间转换成汉字
|
||||
* @param hour
|
||||
* @return
|
||||
*/
|
||||
public static String hourToCn(String hour) {
|
||||
String[] timeArray = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"};
|
||||
String[] hourArray = hour.split(":");
|
||||
int hourInt = Integer.parseInt(hourArray[0]);
|
||||
int minute = Integer.parseInt(hourArray[1]);
|
||||
String result = intToCn(hourInt,timeArray) + "点\n" + intToCn(minute,timeArray) + "分";
|
||||
return result;
|
||||
}
|
||||
private static String intToCn(int hourInt, String[] timeArray) {
|
||||
String result = "";
|
||||
if(hourInt >= 0 && hourInt <= 10) {
|
||||
result += timeArray[hourInt] + "\n";
|
||||
} else if (hourInt >= 11 && hourInt <= 19) {
|
||||
result += (timeArray[10] + "\n" + timeArray[hourInt % 10]) + "\n";
|
||||
}else {
|
||||
result += (timeArray[hourInt / 10] + "\n" + timeArray[10]) + "\n" + (hourInt % 10 == 0 ? "" : timeArray[hourInt % 10] + "\n");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 获取当前日期后的一周时间,并返回LinkedHashMap<String, Date>
|
||||
* @param startTime
|
||||
* @return
|
||||
*/
|
||||
public static LinkedHashMap<String, Date> dateAfterWeek(String startTime) {
|
||||
LinkedHashMap<String, Date> result = new LinkedHashMap<>();
|
||||
try {
|
||||
Date date = parse(startTime,FORMAT_LONOGRAM);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(calendar.DATE, i); //把日期往后增加一天,整数往后推,负数往前移动 时间戳转时间
|
||||
Date newDate = calendar.getTime();
|
||||
String str = new SimpleDateFormat("yyyy-MM-dd").format(newDate);
|
||||
result.put(str, newDate);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* 获取当前日期 后的一周时间,并返回yyyy-MM-dd字符串数组
|
||||
* @param startTime
|
||||
* @return
|
||||
*/
|
||||
public static String[] dateAfterWeekArray(String startTime) {
|
||||
String weekArray[] = new String[7];
|
||||
try {
|
||||
Date date = parse(startTime,FORMAT_LONOGRAM);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(calendar.DATE, i);//把日期往后增加一天,整数往后推,负数往前移动 时间戳转时间
|
||||
Date newDate = calendar.getTime();
|
||||
weekArray[i] = new SimpleDateFormat("yyyy-MM-dd").format(newDate);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return weekArray;
|
||||
}
|
||||
/**
|
||||
* 根据传入的时间获取本周开始(0-表示本周,1-表示下周,-1-表示上周 )
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getMonDayToDate(String date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(parse(date, "yyyy-MM-dd"));
|
||||
// N:0-表示本周,1-表示下周,-1-表示上周
|
||||
cal.add(Calendar.DATE, 0 * 7);
|
||||
// Calendar.MONDAY 表示获取周一的日期; Calendar.WEDNESDAY:表示周三的日期
|
||||
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
|
||||
return format(cal.getTime());
|
||||
}
|
||||
|
||||
|
||||
public static String getYesterDayDate(){
|
||||
|
||||
//获取当前日期
|
||||
Calendar calendar= Calendar.getInstance();
|
||||
// 将日期减一天
|
||||
calendar.add(Calendar.DAY_OF_MONTH,-1);
|
||||
return format(calendar.getTime(),FORMAT_LONOGRAM01);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
//String time = format(new Date());
|
||||
//String weekOfDate = getWeekOfDate(new Date());
|
||||
//int countDays = countDays("2019-12-22",FORMAT_LONOGRAM);
|
||||
//Calendar cal = Calendar.getInstance();
|
||||
// long time = cal.getTime().getTime();
|
||||
// System.out.println("星期:"+weekOfDate);
|
||||
// String hourToCn = hourToCn(format(new Date()).substring(11, 19));
|
||||
// System.out.print(hourToCn);
|
||||
// String[] dateAfterWeekArray = dateAfterWeekArray(format(new Date()));
|
||||
// for (int i = 0; i < dateAfterWeekArray.length; i++) {
|
||||
// System.out.println(dateAfterWeekArray[i]);
|
||||
// }
|
||||
String monDayToDate = getMonDayToDate(format(new Date()));
|
||||
System.out.println(monDayToDate);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// public static String getDeviceName( NodeInfo nodeInfo) {
|
||||
// DevicTypeModelBean deviceType = TelinkMeshApplication.mDeviceModel.getDeviceModel(nodeInfo.deviceModleType.toLowerCase());
|
||||
// if (deviceType != null) {
|
||||
// nodeInfo.deviceName = deviceType.getType() + "-" + nodeInfo.macAddress.replace(":", "");
|
||||
// }
|
||||
// return nodeInfo.deviceName;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
472
nebula-sdk/src/main/java/com/android/util/DeviceUtil.java
Normal file
472
nebula-sdk/src/main/java/com/android/util/DeviceUtil.java
Normal file
@@ -0,0 +1,472 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.StatFs;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class DeviceUtil {
|
||||
|
||||
public static String getDeviceId() {
|
||||
// String uuid =null;
|
||||
// TelephonyManager TelephonyMgr = (TelephonyManager) activity.getSystemService(TELEPHONY_SERVICE);
|
||||
// if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED) {
|
||||
// PermissionChecker.getInstance().requestReadPhoneState(activity);
|
||||
// return uuid;
|
||||
// }
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// /* LogUtils.e("$$$$$$$$------Build.getSerial()="+Build.getSerial());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getSimSerialNumber()="+TelephonyMgr.getSimSerialNumber());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getImei()="+TelephonyMgr.getImei());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getSubscriberId()="+TelephonyMgr.getSubscriberId());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getLine1Number()="+TelephonyMgr.getLine1Number());
|
||||
// LogUtils.e("$$$$$$$$------TelephonyMgr.getDeviceId()="+TelephonyMgr.getDeviceId());
|
||||
// LogUtils.e("$$$$$$$$------UUID="+UUID.randomUUID().toString());*/
|
||||
// uuid = Build.getSerial();//序列号
|
||||
// if(isEmpty(uuid)){//IMEI:国际移动设备识别码
|
||||
// uuid = TelephonyMgr.getImei();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//IMEI:国际移动设备识别码
|
||||
// uuid = TelephonyMgr.getDeviceId();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//ICCID:集成电路卡识别码(固化在手机SIM 卡中)
|
||||
// uuid = TelephonyMgr.getSimSerialNumber();
|
||||
// }
|
||||
// if(isEmpty(uuid)){//IMSI:国际移动用户识别码(sim卡运营商信息)
|
||||
// uuid = TelephonyMgr.getSubscriberId();
|
||||
// }
|
||||
// if(isEmpty(uuid)){
|
||||
// uuid = TelephonyMgr.getLine1Number();
|
||||
// }
|
||||
// //UUID.randomUUID().toString();
|
||||
// }else {
|
||||
// Class<?> c = null;
|
||||
// try {
|
||||
// c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// uuid = (String) get.invoke(c, "ro.serialno");
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (NoSuchMethodException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalAccessException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// if (isEmpty(uuid)){
|
||||
// UUID.randomUUID().toString();
|
||||
// }
|
||||
return "";
|
||||
}
|
||||
|
||||
// public static String getSerialNumber(){
|
||||
// String serial = null;
|
||||
// try {
|
||||
// if(Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1){//7.11+
|
||||
// serial = Build.getSerial();
|
||||
// LogUtils.e("===========7.11+=======================");
|
||||
// }else{
|
||||
// Class<?> c;
|
||||
// c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// serial = (String) get.invoke(c, "ro.serialno");
|
||||
// LogUtils.e("===========7.11-======================");
|
||||
// }
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (NoSuchMethodException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (SecurityException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalAccessException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (IllegalArgumentException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// } catch (InvocationTargetException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if (serial == null){
|
||||
// //serial = "000000";
|
||||
// }
|
||||
// return serial;
|
||||
// }
|
||||
|
||||
|
||||
public static String getSerialNum(Context context) {
|
||||
String serial = null;
|
||||
// try {
|
||||
// Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
// Method get = c.getMethod("get", String.class);
|
||||
// serial = (String) get.invoke(c, "ro.serialno");
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
|
||||
|
||||
// if (serial == null || serial.isEmpty() || serial.length() < 5) {
|
||||
// serial = getWifiMacAddress(context);
|
||||
// if (serial == null || serial.isEmpty()) serial = getBtMacAddress(context);
|
||||
// if (serial == null || serial.isEmpty()) serial = "serial No. error ";
|
||||
// }
|
||||
// return serial;
|
||||
return "BBBBBBBB";
|
||||
}
|
||||
|
||||
public static boolean isDeviceExist(Context context, String mac) {
|
||||
String deviceId = getEthernetMac();
|
||||
if (deviceId.equals(mac)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getEthernetMac() {
|
||||
String ethernetMac = null;
|
||||
try {
|
||||
NetworkInterface NIC = NetworkInterface.getByName("eth0");
|
||||
byte[] buf = NIC.getHardwareAddress();
|
||||
ethernetMac = byteHexString(buf);
|
||||
} catch (SocketException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// return "EC:2E:CC:81:0D:62"; //for test
|
||||
return ethernetMac;
|
||||
}
|
||||
|
||||
public static String getWifiMac(){
|
||||
String wifiMac = null;
|
||||
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/net/wlan0/address";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
wifiMac = line;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return wifiMac;
|
||||
}
|
||||
|
||||
/*
|
||||
* 字节数组转16进制字符串
|
||||
*/
|
||||
public static String byteHexString(byte[] array) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for(int i=0;i<array.length;i++){
|
||||
String hex = Integer.toHexString(array[i] & 0xFF);
|
||||
if (hex.length() == 1) {
|
||||
hex = '0' + hex;
|
||||
}
|
||||
if(i<array.length-1){
|
||||
builder.append(hex+":");
|
||||
}else {
|
||||
builder.append(hex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return builder.toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
public static String getBrand(){
|
||||
return Build.BRAND;
|
||||
}
|
||||
|
||||
public static String getBuild(){
|
||||
return Build.FINGERPRINT;
|
||||
}
|
||||
|
||||
public static String getDevice(){
|
||||
|
||||
return Build.DEVICE;
|
||||
}
|
||||
public static String getCpu(){
|
||||
String platform = getAllwinnerPlatform();
|
||||
if("sun8iw7".equals(platform)){
|
||||
return getH3CPUinfo();
|
||||
}
|
||||
return getH616And313CPUinfo();
|
||||
}
|
||||
|
||||
public static String getDdr(){
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getModel(){
|
||||
return Build.MODEL;
|
||||
}
|
||||
|
||||
public static String getPlatform(){
|
||||
return "allwinner";
|
||||
}
|
||||
|
||||
public static String getSystemVersion(){
|
||||
return Build.VERSION.RELEASE;
|
||||
}
|
||||
|
||||
|
||||
private static String getH3CPUinfo() {
|
||||
String cpuAddress = "";
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/sunxi_info/sys_info";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
if (line.contains("sunxi_chipid")) {
|
||||
String[] SerialStr = line.split(":");
|
||||
if (SerialStr.length == 2) {
|
||||
String mSerial = SerialStr[1];
|
||||
cpuAddress = mSerial.trim();
|
||||
return cpuAddress;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return cpuAddress;
|
||||
}
|
||||
|
||||
|
||||
private static String getH616And313CPUinfo() {
|
||||
String cpuAddress = "";
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/sunxi_info/sys_info";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
if (line.contains("sunxi_serial")) {
|
||||
String[] SerialStr = line.split(":");
|
||||
if (SerialStr.length == 2) {
|
||||
String mSerial = SerialStr[1];
|
||||
cpuAddress = mSerial.trim();
|
||||
return cpuAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return cpuAddress;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static String getAllwinnerPlatform() {
|
||||
String platform = "";
|
||||
String line = null;
|
||||
String cmd = "cat /sys/class/sunxi_info/sys_info";
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(cmd);
|
||||
// BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
// String error = null;
|
||||
// while ((error = ie.readLine()) != null && !error.equals("null")) {
|
||||
// Log.d("===========", "========error="+error);
|
||||
// }
|
||||
while ((line = in.readLine()) != null && !line.equals("null")) {
|
||||
if (line.contains("sunxi_platform")) {
|
||||
String[] SerialStr = line.split(":");
|
||||
if (SerialStr.length == 2) {
|
||||
String mSerial = SerialStr[1];
|
||||
platform = mSerial.trim();
|
||||
return platform;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统ram大小
|
||||
* @return
|
||||
*/
|
||||
public static String getSysteTotalMemorySize(Context context){
|
||||
//获得ActivityManager服务的对象
|
||||
ActivityManager mActivityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
//获得MemoryInfo对象
|
||||
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo() ;
|
||||
//获得系统可用内存,保存在MemoryInfo对象上
|
||||
mActivityManager.getMemoryInfo(memoryInfo) ;
|
||||
long memSize = memoryInfo.totalMem ;
|
||||
//字符类型转换
|
||||
String availMemStr = formateFileSize(memSize,true);
|
||||
return availMemStr ;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * 获取系统rom大小
|
||||
// * @return
|
||||
// */
|
||||
// @RequiresApi(api = Build.VERSION_CODES.O)
|
||||
// public static String getSysteTotalStorageSize(Context context){
|
||||
// //获得ActivityManager服务的对象
|
||||
// String availMemStr = null;
|
||||
// try {
|
||||
// StorageStatsManager storageManager = (StorageStatsManager)context.getSystemService(Context.STORAGE_STATS_SERVICE);
|
||||
// //字符类型转换
|
||||
// availMemStr = formateFileSize( storageManager.getTotalBytes(StorageManager.UUID_DEFAULT),true);
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return availMemStr ;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 获取系统rom大小
|
||||
* @return
|
||||
*/
|
||||
public static String getSysteTotalStorageSize(Context context){
|
||||
//获得ActivityManager服务的对象
|
||||
String availMemStr = null;
|
||||
try {
|
||||
// final StorageManager storageManager = (StorageManager)context.getSystemService(Context.STORAGE_SERVICE);
|
||||
// storageManager.getStorageVolumes()
|
||||
|
||||
StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath());
|
||||
long totalSize = statFs.getTotalBytes();
|
||||
//字符类型转换
|
||||
availMemStr = formateFileSize( totalSize,true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return availMemStr ;
|
||||
}
|
||||
|
||||
|
||||
// public static String getSysteTotalStorageSize(Context context) {
|
||||
// String dir = "/proc/meminfo";
|
||||
// try {
|
||||
// FileReader fr = new FileReader(dir);
|
||||
// BufferedReader br = new BufferedReader(fr, 2048);
|
||||
// String memoryLine = br.readLine();
|
||||
// String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
|
||||
// br.close();
|
||||
// return formateFileSize(Integer.parseInt(subMemoryLine.replaceAll("\\D+", "")) * 1024l,true);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return formateFileSize(0, true);
|
||||
// }
|
||||
|
||||
public static String formateFileSize(long size, boolean isInteger) {
|
||||
DecimalFormat df = isInteger ? new DecimalFormat("#0") : new DecimalFormat("#0.#");
|
||||
String fileSizeString = "0M";
|
||||
if (size < 1024 && size > 0) {
|
||||
fileSizeString = df.format((double) size) + "B";
|
||||
} else if (size < 1024 * 1024) {
|
||||
fileSizeString = df.format((double) size / 1024) + "K";
|
||||
} else if (size < 1024 * 1024 * 1024) {
|
||||
fileSizeString = df.format((double) size / (1024 * 1024)) + "M";
|
||||
} else {
|
||||
fileSizeString = df.format((double) size / (1024 * 1024 * 1024)) + "G";
|
||||
}
|
||||
return fileSizeString;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 获取本机默认的launcher
|
||||
* @return
|
||||
*/
|
||||
public static String getDefaultLauncherPackageName(Context context) {
|
||||
final UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
long time = System.currentTimeMillis();
|
||||
List<UsageStats> appList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000*1000, time);
|
||||
|
||||
if (appList != null && appList.size() > 0) {
|
||||
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<>();
|
||||
for (UsageStats usageStats : appList) {
|
||||
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
|
||||
}
|
||||
if (mySortedMap != null && !mySortedMap.isEmpty()) {
|
||||
return mySortedMap.get(mySortedMap.lastKey()).getPackageName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getLauncherPackageName(Context context) {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_HOME);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
|
||||
final List<ResolveInfo> resList = context.getPackageManager().queryIntentActivities(intent, 0);
|
||||
String tmp="";
|
||||
for (ResolveInfo res:resList) {
|
||||
if (res.activityInfo == null) {
|
||||
continue;
|
||||
}
|
||||
if("com.android.settings".equals(res.activityInfo.packageName)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if("com.android.tv.settings".equals(res.activityInfo.packageName)){
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp+=res.activityInfo.packageName+",";
|
||||
}
|
||||
return "".equals(tmp)?null:tmp;
|
||||
}
|
||||
}
|
||||
22
nebula-sdk/src/main/java/com/android/util/DomainBean.java
Normal file
22
nebula-sdk/src/main/java/com/android/util/DomainBean.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.android.util;
|
||||
|
||||
public class DomainBean {
|
||||
private int type;
|
||||
private String domainNames;
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDomainNames() {
|
||||
return domainNames;
|
||||
}
|
||||
|
||||
public void setDomainNames(String domainNames) {
|
||||
this.domainNames = domainNames;
|
||||
}
|
||||
}
|
||||
165
nebula-sdk/src/main/java/com/android/util/EncryptionUtils.java
Normal file
165
nebula-sdk/src/main/java/com/android/util/EncryptionUtils.java
Normal file
@@ -0,0 +1,165 @@
|
||||
package com.android.util;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
/**
|
||||
* 类内容描述
|
||||
*
|
||||
* @author 杨崇顺
|
||||
* @since 2025-06-19 17:26
|
||||
*/
|
||||
public class EncryptionUtils {
|
||||
/**
|
||||
* MD5签名
|
||||
*
|
||||
* @param domain 发起请求时使用的域名。从设备端的host请求头获取,设备端在请求时一般不用设置,web请求框架自动带入的。 请求头示例:host=api.yudao.iocoder.cn
|
||||
* @param mac 设备mac。请求头示例: mac=A8:20:06:B7:C8:B9
|
||||
* @param cpu 设备cpu。请求头示例:cpu= 02c0008145f0462078a3840038350b53
|
||||
* @param time 13位时间戳。 服务器有个获取时间戳的接口,通过那个接口获取后后续请求带上来。请求头示例:time=1750324247858
|
||||
* @param salt 加密的盐值。建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @param sdkVersion sdk版本 ,从请求头获取。请求头示例: api-version=46
|
||||
* @return 签名结果
|
||||
*/
|
||||
public static String sign(String domain, String mac, String cpu, Long time, String salt, int sdkVersion) {
|
||||
String sign = domain + salt + "8622Nbdf52" + mac + salt + "2d6fndw" + cpu + salt + "3hd73bx6g" + time + salt + "23jhY6DGVhbd";
|
||||
return getMD5(sign);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证签名
|
||||
*
|
||||
* @param domain 发起请求时使用的域名。从设备端的host请求头获取,设备端在请求时一般不用设置,web请求框架自动带入的。 请求头示例:host=api.yudao.iocoder.cn
|
||||
* @param mac 设备mac。请求头示例: mac=A8:20:06:B7:C8:B9
|
||||
* @param cpu 设备cpu。请求头示例:cpu= 02c0008145f0462078a3840038350b53
|
||||
* @param time 13位时间戳。 服务器有个获取时间戳的接口,通过那个接口获取后后续请求带上来。请求头示例:time=1750324247858
|
||||
* @param salt 加密的盐值。建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @param sdkVersion sdk版本 ,从请求头获取。请求头示例: api-version=46
|
||||
* @param receivedSign 和字段带上来的签名结果
|
||||
* @return 验证结果(true=有效,false=无效)
|
||||
*/
|
||||
public static boolean verify(String domain, String mac, String cpu, Long time, String salt, int sdkVersion, String receivedSign) {
|
||||
// 重新生成签名并与接收的签名对比
|
||||
long nowTime = System.currentTimeMillis();
|
||||
long timeDiff = nowTime - time;
|
||||
if (timeDiff > 60000) {
|
||||
// 时间差超过60秒则判断验签失败,防止恶意请求
|
||||
return false;
|
||||
}
|
||||
String computedSign = sign(domain, mac, cpu, time, salt, sdkVersion);
|
||||
return computedSign.equals(receivedSign);
|
||||
}
|
||||
|
||||
public static String getMD5(String input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
// 关键修复:强制使用 UTF-8 编码
|
||||
md.update(input.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] digest = md.digest();
|
||||
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte b : digest) {
|
||||
String hex = Integer.toHexString(0xff & b);
|
||||
if (hex.length() == 1) hexString.append('0');
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("MD5 algorithm not available", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
*
|
||||
* @param plainText 明文
|
||||
* @param secretKey 密钥。 建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @return 密文
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] encrypt(String plainText, String secretKey) throws Exception {
|
||||
// 将密钥转换为字节数组并验证长度
|
||||
byte[] keyBytes = validateKey(secretKey);
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
|
||||
// 生成随机初始化向量(IV)
|
||||
byte[] ivBytes = new byte[16];
|
||||
SecureRandom secureRandom = new SecureRandom();
|
||||
secureRandom.nextBytes(ivBytes);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
|
||||
|
||||
|
||||
// 初始化加密器
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
|
||||
|
||||
// 执行加密
|
||||
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
// 组合IV和密文(IV前置方案)
|
||||
byte[] combined = new byte[ivBytes.length + encryptedBytes.length];
|
||||
System.arraycopy(ivBytes, 0, combined, 0, ivBytes.length);
|
||||
System.arraycopy(encryptedBytes, 0, combined, ivBytes.length, encryptedBytes.length);
|
||||
|
||||
// 返回Base64编码的字符串
|
||||
return Base64.encode(combined, Base64.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密方法
|
||||
*
|
||||
* @param encryptedText 密文
|
||||
* @param secretKey 密钥。建议每个uota版本都不一样,uota写入程序内部后进行混淆处理;服务端通过配置管理和版本对应关系。根据【sdkVersion】从服务端获配置获取
|
||||
* @return 明文
|
||||
* @throws Exception
|
||||
*/
|
||||
// 解密方法
|
||||
public static String decrypt(String encryptedText, String secretKey) throws Exception {
|
||||
// 将密钥转换为字节数组并验证长度
|
||||
byte[] keyBytes = validateKey(secretKey);
|
||||
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
|
||||
|
||||
// Base64解码
|
||||
byte[] combined = Base64.decode(encryptedText, Base64.DEFAULT);
|
||||
|
||||
// 分离IV和密文(前16字节是IV)
|
||||
byte[] ivBytes = new byte[16];
|
||||
byte[] encryptedBytes = new byte[combined.length - ivBytes.length];
|
||||
System.arraycopy(combined, 0, ivBytes, 0, ivBytes.length);
|
||||
System.arraycopy(combined, ivBytes.length, encryptedBytes, 0, encryptedBytes.length);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
|
||||
|
||||
// 初始化解密器
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
|
||||
|
||||
// 执行解密并返回UTF-8字符串
|
||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
// 密钥验证(支持128/192/256位)
|
||||
private static byte[] validateKey(String key) {
|
||||
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||
if (keyBytes.length != 16 && keyBytes.length != 24 && keyBytes.length != 32) {
|
||||
throw new IllegalArgumentException("密钥长度必须是16、24或32字节(对应128/192/256位)");
|
||||
}
|
||||
return keyBytes;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
String sign = "12asbSDSHWEXSd7hdfh7AgdGS5kdg.mudhgAS";
|
||||
String md5 = getMD5(sign);
|
||||
System.out.println("md5=====" + md5);
|
||||
}
|
||||
}
|
||||
39
nebula-sdk/src/main/java/com/android/util/EventBusType.java
Normal file
39
nebula-sdk/src/main/java/com/android/util/EventBusType.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.android.util;
|
||||
|
||||
public class EventBusType{
|
||||
private Object mMessgae;
|
||||
private int mType;
|
||||
/**添加喜欢的应用到频道中去*/
|
||||
public static final int ADD_APP_TO_CHANNEL_TYPE=10;
|
||||
|
||||
/**频道设置关消息*/
|
||||
public static final int SWITCH_OFF_CHANNEL_TYPE=11;
|
||||
/**频道设置开消息*/
|
||||
public static final int SWITCH_ON_CHANNEL_TYPE=12;
|
||||
|
||||
|
||||
public static final int TYPE_USB_REMOVE=0;
|
||||
public static final int TYPE_SD_REMOVE=1;
|
||||
public static final int TYPE_SD_MOUNT=2;
|
||||
public static final int TYPE_USB_MOUNT=3;
|
||||
public static final int TYPE_ETHERNET=4;
|
||||
public static final int TYPE_WIFI=5;
|
||||
public static final int TYPE_NONET=6;
|
||||
public static final int TYPE_APP_REMOVE=7;
|
||||
public static final int TYPE_APP_INSTALL=8;
|
||||
/**app扫描完成*/
|
||||
public static final int SCANING_APP_COMPLETE =9;
|
||||
|
||||
|
||||
public EventBusType(int type,Object message){
|
||||
this.mType =type;
|
||||
this.mMessgae = message;
|
||||
};
|
||||
|
||||
public Object getMessgae() {
|
||||
return mMessgae;
|
||||
}
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
}
|
||||
352
nebula-sdk/src/main/java/com/android/util/FileSystem.java
Normal file
352
nebula-sdk/src/main/java/com/android/util/FileSystem.java
Normal file
@@ -0,0 +1,352 @@
|
||||
/********************************************************************************************************
|
||||
* @file FileSystem.java
|
||||
*
|
||||
* @brief for TLSR chips
|
||||
*
|
||||
* @author telink
|
||||
* @date Sep. 30, 2010
|
||||
*
|
||||
* @par Copyright (c) 2010, Telink Semiconductor (Shanghai) Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The information contained herein is confidential and proprietary property of Telink
|
||||
* Semiconductor (Shanghai) Co., Ltd. and is available under the terms
|
||||
* of Commercial License Agreement between Telink Semiconductor (Shanghai)
|
||||
* Co., Ltd. and the licensee in separate contract or the terms described here-in.
|
||||
* This heading MUST NOT be removed from this file.
|
||||
*
|
||||
* Licensees are granted free, non-transferable use of the information in this
|
||||
* file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
|
||||
*
|
||||
*******************************************************************************************************/
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
public class FileSystem {
|
||||
|
||||
public static boolean writeAsObject(Context context, String fileName, Object obj) {
|
||||
|
||||
File externalFilesDir = context.getExternalFilesDir(null);
|
||||
File file = new File(externalFilesDir, fileName);
|
||||
|
||||
FileOutputStream fos = null;
|
||||
ObjectOutputStream ops = null;
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
|
||||
fos = new FileOutputStream(file);
|
||||
ops = new ObjectOutputStream(fos);
|
||||
|
||||
ops.writeObject(obj);
|
||||
ops.flush();
|
||||
|
||||
success = true;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (ops != null)
|
||||
ops.close();
|
||||
if (ops != null)
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
public static boolean writeAsObject(Context context,String mkdir, String fileName, Object obj) {
|
||||
|
||||
File externalFilesDir = context.getExternalFilesDir(mkdir);
|
||||
File file = new File(externalFilesDir, fileName);
|
||||
|
||||
FileOutputStream fos = null;
|
||||
ObjectOutputStream ops = null;
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
|
||||
fos = new FileOutputStream(file);
|
||||
ops = new ObjectOutputStream(fos);
|
||||
|
||||
ops.writeObject(obj);
|
||||
ops.flush();
|
||||
|
||||
success = true;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (ops != null)
|
||||
ops.close();
|
||||
if (ops != null)
|
||||
fos.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Object readAsObject(Context context, String fileName) {
|
||||
|
||||
File dir = context.getExternalFilesDir(null);
|
||||
File file = new File(dir, fileName);
|
||||
|
||||
if (!file.exists())
|
||||
return null;
|
||||
|
||||
FileInputStream fis = null;
|
||||
ObjectInputStream ois = null;
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
|
||||
fis = new FileInputStream(file);
|
||||
ois = new ObjectInputStream(fis);
|
||||
|
||||
result = ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.e("postServerAppUpdate--->read object error : " + e.toString());
|
||||
} finally {
|
||||
try {
|
||||
if (ois != null)
|
||||
ois.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static Object readAsObject(Context context, String mkdir,String fileName) {
|
||||
|
||||
File dir = context.getExternalFilesDir(mkdir);
|
||||
File file = new File(dir, fileName);
|
||||
|
||||
if (!file.exists())
|
||||
return null;
|
||||
|
||||
FileInputStream fis = null;
|
||||
ObjectInputStream ois = null;
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
|
||||
fis = new FileInputStream(file);
|
||||
ois = new ObjectInputStream(fis);
|
||||
|
||||
result = ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.e("postServerAppUpdate--->read object error : " + e.toString());
|
||||
} finally {
|
||||
try {
|
||||
if (ois != null)
|
||||
ois.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**获取指定目录下的所有文件*/
|
||||
public static File[] getListFileByMkdir(Context context,String mkdir){
|
||||
File dir = context.getExternalFilesDir(mkdir);
|
||||
if(dir.exists()){
|
||||
return dir.listFiles();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Object readTestAsObject(Context context, String filePath) {
|
||||
|
||||
// File dir = context.getFilesDir();
|
||||
File file = new File(filePath);
|
||||
|
||||
if (!file.exists())
|
||||
return null;
|
||||
|
||||
FileInputStream fis = null;
|
||||
ObjectInputStream ois = null;
|
||||
|
||||
Object result = null;
|
||||
try {
|
||||
|
||||
fis = new FileInputStream(file);
|
||||
ois = new ObjectInputStream(fis);
|
||||
|
||||
result = ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.e("postServerAppUpdate--->read object error : " + e.toString());
|
||||
} finally {
|
||||
try {
|
||||
if (ois != null)
|
||||
ois.close();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static File getSettingPath() {
|
||||
File root = Environment.getExternalStorageDirectory();
|
||||
return new File(root.getAbsolutePath() + File.separator + "Godox-BleMesh");
|
||||
}
|
||||
|
||||
//
|
||||
public static File writeString(File dir, String filename, String content) {
|
||||
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
File file = new File(dir, filename);
|
||||
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
fos = new FileOutputStream(file);
|
||||
fos.write(content.getBytes());
|
||||
fos.flush();
|
||||
fos.close();
|
||||
return file;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String readString(File file) {
|
||||
if (!file.exists())
|
||||
return "";
|
||||
try {
|
||||
FileReader fr = new FileReader(file);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
String line = null;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while ((line = br.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
|
||||
br.close();
|
||||
fr.close();
|
||||
return sb.toString();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 跟新替换文件
|
||||
* @param filePath
|
||||
* @param newFilePath
|
||||
*/
|
||||
public static void copyFile(String filePath,String newFilePath){
|
||||
File file = new File(newFilePath);
|
||||
//复制到的位置
|
||||
File toFile = new File(filePath);
|
||||
try {
|
||||
copy(file,toFile);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void copy(File file,File toFile) throws Exception {
|
||||
byte[] b = new byte[1024];
|
||||
int a;
|
||||
FileInputStream fis;
|
||||
FileOutputStream fos;
|
||||
try {
|
||||
if (file.isDirectory()) {
|
||||
String filepath = file.getAbsolutePath();
|
||||
filepath = filepath.replaceAll("\\\\", "/");
|
||||
String toFilepath = toFile.getAbsolutePath();
|
||||
toFilepath = toFilepath.replaceAll("\\\\", "/");
|
||||
int lastIndexOf = filepath.lastIndexOf("/");
|
||||
toFilepath = toFilepath + filepath.substring(lastIndexOf, filepath.length());
|
||||
File copy = new File(toFilepath);
|
||||
//复制文件夹
|
||||
if (!copy.exists()) {
|
||||
copy.mkdir();
|
||||
}
|
||||
//遍历文件夹
|
||||
for (File f : file.listFiles()) {
|
||||
copy(f, copy);
|
||||
}
|
||||
} else {
|
||||
if (toFile.isDirectory()) {
|
||||
String filepath = file.getAbsolutePath();
|
||||
filepath = filepath.replaceAll("\\\\", "/");
|
||||
String toFilepath = toFile.getAbsolutePath();
|
||||
toFilepath = toFilepath.replaceAll("\\\\", "/");
|
||||
int lastIndexOf = filepath.lastIndexOf("/");
|
||||
toFilepath = toFilepath + filepath.substring(lastIndexOf, filepath.length());
|
||||
|
||||
//写文件
|
||||
File newFile = new File(toFilepath);
|
||||
fis = new FileInputStream(file);
|
||||
fos = new FileOutputStream(newFile);
|
||||
while ((a = fis.read(b)) != -1) {
|
||||
fos.write(b,0, a);
|
||||
}
|
||||
} else {
|
||||
//写文件
|
||||
fis = new FileInputStream(file);
|
||||
fos = new FileOutputStream(toFile);
|
||||
while ((a = fis.read(b)) != -1) {
|
||||
fos.write(b,0, a);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
144
nebula-sdk/src/main/java/com/android/util/FileUtil.java
Normal file
144
nebula-sdk/src/main/java/com/android/util/FileUtil.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
|
||||
|
||||
public static final String ADVERT_DIR="ADVERT";
|
||||
public static final String APP_DIR="APP";
|
||||
public static final String LAUNCHER_DIR="LAUNCHER";
|
||||
|
||||
public static final String OTA_DIR="OTA";
|
||||
/**广告类型*/
|
||||
public static final int ADVERT_TYPE=0;
|
||||
/**app类型*/
|
||||
public static final int APP_TYPE=1;
|
||||
/**Launcher类型*/
|
||||
public static final int LAUNCHER_TYPE=2;
|
||||
|
||||
public static final int OTA_TYPE=3;
|
||||
public static String getBakPath(Context context,int type){
|
||||
|
||||
String bakDir = null;
|
||||
switch (type){
|
||||
case ADVERT_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+ADVERT_DIR;//获取跟目录
|
||||
break;
|
||||
case APP_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+APP_DIR;//获取跟目录
|
||||
break;
|
||||
case LAUNCHER_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+LAUNCHER_DIR;//获取跟目录
|
||||
break;
|
||||
case OTA_TYPE:
|
||||
bakDir = context.getExternalCacheDir().getPath()+File.separator+OTA_DIR;//获取跟目录
|
||||
break;
|
||||
}
|
||||
|
||||
File file=new File(bakDir);
|
||||
if(file.exists()){
|
||||
if(file.isFile()){
|
||||
file.delete();
|
||||
file.mkdir();
|
||||
}
|
||||
}else {
|
||||
file.mkdir();
|
||||
}
|
||||
return file.getPath();
|
||||
}
|
||||
|
||||
|
||||
public static String getLauncherBakPath(Context context){
|
||||
|
||||
return context.getExternalCacheDir().getPath()+File.separator+LAUNCHER_DIR;
|
||||
}
|
||||
public static String getAppBakPath(Context context){
|
||||
|
||||
return context.getExternalCacheDir().getPath()+File.separator+APP_DIR;
|
||||
}
|
||||
|
||||
public static String getAdvertBakPath(Context context){
|
||||
|
||||
return context.getExternalCacheDir().getPath()+File.separator+ADVERT_DIR;
|
||||
}
|
||||
|
||||
|
||||
public static void deleteFile(String filePath){
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
if(file.exists()){
|
||||
file.delete();
|
||||
}
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy file
|
||||
* @param targetFile
|
||||
* @param sourceFile
|
||||
*/
|
||||
public static void copyFilesFromTo(File targetFile, File sourceFile,long targetFilePoint) {
|
||||
|
||||
try {
|
||||
if(!targetFile.exists()){
|
||||
return;
|
||||
}
|
||||
if(!sourceFile.exists()){
|
||||
return;
|
||||
}
|
||||
InputStream inputStream = new FileInputStream(sourceFile);
|
||||
// 1.建立通道对象
|
||||
RandomAccessFile randomFile = new RandomAccessFile(targetFile, "rwd");
|
||||
randomFile.seek(targetFilePoint);
|
||||
// 2.create read data buffer
|
||||
byte[] buffer = new byte[1024*1024*10];
|
||||
// 3.开始读文件
|
||||
int lenght = 0;
|
||||
long copyFileSize=0;
|
||||
while ((lenght = inputStream.read(buffer)) != -1) {// 循环从输入流读取buffer字节
|
||||
// 将Buffer中的数据写到outputStream对象中
|
||||
|
||||
randomFile.write(buffer, 0, lenght);
|
||||
copyFileSize+=lenght;
|
||||
}
|
||||
|
||||
LogUtils.e("postServerAppUpdate--->copyFileSize===:"+copyFileSize);
|
||||
// 4.关闭流
|
||||
randomFile.close();
|
||||
inputStream.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getFileName(String url){
|
||||
if(url!=null&&url.contains(".")){
|
||||
return url.substring(url.lastIndexOf("/"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
/**
|
||||
* Created by Administrator on 2018/5/24 0024.
|
||||
* 获取APP版本号
|
||||
*/
|
||||
|
||||
public class GetEditionCode {
|
||||
/**
|
||||
* 获取版本信息
|
||||
*
|
||||
* @throws PackageManager.NameNotFoundException
|
||||
*/
|
||||
public static String getVersionNameCode(Context context) {
|
||||
//获取包管理对象
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
//获取包信息
|
||||
PackageInfo packageInfo = null;
|
||||
try {
|
||||
packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return packageInfo.versionName; //获取版本码
|
||||
}
|
||||
}
|
||||
130
nebula-sdk/src/main/java/com/android/util/GsonUtil.java
Normal file
130
nebula-sdk/src/main/java/com/android/util/GsonUtil.java
Normal file
@@ -0,0 +1,130 @@
|
||||
package com.android.util;
|
||||
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GsonUtil {
|
||||
|
||||
private static Gson gson = null;
|
||||
|
||||
static {
|
||||
if (gson == null) {
|
||||
gson = new Gson();
|
||||
}
|
||||
}
|
||||
|
||||
private GsonUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成json
|
||||
*
|
||||
* @param object
|
||||
* @return
|
||||
*/
|
||||
public static String GsonString(Object object) {
|
||||
String gsonString = null;
|
||||
if (gson != null) {
|
||||
gsonString = gson.toJson(object);
|
||||
}
|
||||
return gsonString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成bean
|
||||
*
|
||||
* @param gsonString
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
public static <T> T GsonToBean(String gsonString, Class<T> cls) {
|
||||
T t = null;
|
||||
if (gson != null) {
|
||||
t = gson.fromJson(gsonString, cls);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成带list的bean
|
||||
*
|
||||
* @param gsonString
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
|
||||
public static <T> T GsonToListBean(String gsonString, Class<T> cls) {
|
||||
T t = null;
|
||||
if (gson != null) {
|
||||
t = gson.fromJson(gsonString, cls);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成list
|
||||
*
|
||||
* @param gsonString
|
||||
* @param cls
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> GsonToList(String gsonString, Class<T> cls) {
|
||||
ArrayList<T> mList = new ArrayList<>();
|
||||
JsonArray array = new JsonParser().parse(gsonString).getAsJsonArray();
|
||||
for (final JsonElement elem : array) {
|
||||
mList.add(gson.fromJson(elem, cls));
|
||||
}
|
||||
return mList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成list中有map的
|
||||
*
|
||||
* @param gsonString
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<Map<String, T>> GsonToListMaps(String gsonString) {
|
||||
List<Map<String, T>> list = null;
|
||||
if (gson != null) {
|
||||
list = gson.fromJson(gsonString,
|
||||
new TypeToken<List<Map<String, T>>>() {
|
||||
}.getType());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成map的
|
||||
*
|
||||
* @param gsonString
|
||||
* @return
|
||||
*/
|
||||
public static <T> Map<String, T> GsonToMaps(String gsonString) {
|
||||
Map<String, T> map = null;
|
||||
if (gson != null) {
|
||||
map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
|
||||
}.getType());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static boolean isJson(String content){
|
||||
try {
|
||||
JSONObject jsonStr= new JSONObject(content);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
238
nebula-sdk/src/main/java/com/android/util/LogManager.java
Normal file
238
nebula-sdk/src/main/java/com/android/util/LogManager.java
Normal file
@@ -0,0 +1,238 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
public class LogManager {
|
||||
|
||||
private Context mContext;
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private static final String FILE_NALE = "nebula_log.txt";
|
||||
/**
|
||||
* 文件路径
|
||||
*/
|
||||
private String LOG_FILE_PATH = null;
|
||||
private FileOutputStream mFileOutputStream;
|
||||
private FileInputStream mFileInputStream;
|
||||
private static LogManager mInstance = null;
|
||||
private ReadLogCallBack mReadLogCallBack;
|
||||
// private boolean isReadLog =false;
|
||||
private boolean isReadLog = true;
|
||||
|
||||
private static final String LOGCONFIG = "/system/logconfig.json";
|
||||
|
||||
private LogManager(Context context) {
|
||||
this.mContext = context;
|
||||
this.LOG_FILE_PATH = context.getExternalCacheDir().getPath() + File.separator + FILE_NALE;
|
||||
mFileOutputStream = createWriterStream();
|
||||
mFileInputStream = createReadStream();
|
||||
isReadLog = getLogSwitch();
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
if (mInstance == null) {
|
||||
mInstance = new LogManager(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static LogManager getmInstance() {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
|
||||
public boolean isReadLog() {
|
||||
return isReadLog;
|
||||
// return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean getLogSwitch() {
|
||||
String json = getAssertData(mContext, LOGCONFIG);
|
||||
if (json == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Map<String, Boolean> logConfigMap = GsonUtil.GsonToMaps(json);
|
||||
logConfigMap.get("Logswitch");
|
||||
return logConfigMap.get("Logswitch");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String getAssertData(Context context, String filepath) {
|
||||
File file = new File(filepath);
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
// InputStream is = context.getResources().openRawResource(R.raw.setting_system_update);
|
||||
|
||||
// if (Build.MODEL.equals("Z10Plus")||Build.MODEL.equals("Z10Pro")){
|
||||
// is = context.getResources().openRawResource(R.raw.setting_system_update_z10pro);
|
||||
// }
|
||||
String resultString = "";
|
||||
try {
|
||||
InputStream is = new FileInputStream(file);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
|
||||
String jsonString = "";
|
||||
while ((jsonString = bufferedReader.readLine()) != null) {
|
||||
|
||||
resultString += jsonString;
|
||||
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return resultString;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 写日志
|
||||
*/
|
||||
public void logWriterMsg(String logMsg) {
|
||||
try {
|
||||
|
||||
if (!isReadLog) {
|
||||
return;
|
||||
}
|
||||
|
||||
logMsg = DateUtil.format(new Date()) + ": " + logMsg + "\n";
|
||||
if (mReadLogCallBack != null) {
|
||||
mReadLogCallBack.onLogMsg(logMsg);
|
||||
}
|
||||
if (mFileOutputStream != null) {
|
||||
|
||||
mFileOutputStream.write(logMsg.getBytes());
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
try {
|
||||
mFileOutputStream.close();
|
||||
} catch (IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
mFileOutputStream = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 读日志
|
||||
*/
|
||||
public void logReadMsg(ReadLogCallBack readLogCallBack) {
|
||||
mReadLogCallBack = readLogCallBack;
|
||||
isReadLog = true;
|
||||
}
|
||||
|
||||
public void stopRecordLogMsg() {
|
||||
isReadLog = false;
|
||||
}
|
||||
|
||||
|
||||
private FileOutputStream createWriterStream() {
|
||||
try {
|
||||
File file = new File(LOG_FILE_PATH);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
mFileOutputStream = new FileOutputStream(LOG_FILE_PATH);
|
||||
return mFileOutputStream;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private FileInputStream createReadStream() {
|
||||
try {
|
||||
mFileInputStream = new FileInputStream(LOG_FILE_PATH);
|
||||
return mFileInputStream;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public interface ReadLogCallBack {
|
||||
public void onLogMsg(String msg);
|
||||
}
|
||||
|
||||
|
||||
// class ReadMsgThread extends Thread{
|
||||
//
|
||||
//
|
||||
// private boolean isRuning=false;
|
||||
// private ReadLogCallBack mReadLogCallBack;
|
||||
//
|
||||
// public ReadMsgThread(ReadLogCallBack readLogCallBack){
|
||||
// this.mReadLogCallBack = readLogCallBack;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void run() {
|
||||
// super.run();
|
||||
// isRuning =true;
|
||||
// byte[] bytes = new byte[1024];
|
||||
// try {
|
||||
// while (isRuning){
|
||||
// int len= mFileInputStream.read(bytes);
|
||||
// if(len>0) {
|
||||
// if (mReadLogCallBack != null) {
|
||||
// String msg = new String(bytes, "utf-8");
|
||||
// mReadLogCallBack.onLogMsg(msg);
|
||||
// }
|
||||
// try {
|
||||
// sleep(500);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }else {
|
||||
// try {
|
||||
// sleep(3000);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public void stopThread(){
|
||||
// isRuning = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.EditText;
|
||||
|
||||
/*
|
||||
* 监听输入内容是否超出最大长度,并设置光标位置
|
||||
* */
|
||||
public class MaxLengthWatcher implements TextWatcher {
|
||||
|
||||
private int maxLen = 0;
|
||||
private EditText editText = null;
|
||||
|
||||
|
||||
public MaxLengthWatcher(int maxLen, EditText editText) {
|
||||
this.maxLen = maxLen;
|
||||
this.editText = editText;
|
||||
}
|
||||
|
||||
public MaxLengthWatcher() {
|
||||
|
||||
}
|
||||
|
||||
public void afterTextChanged(Editable arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
|
||||
int arg3) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
|
||||
// TODO Auto-generated method stub
|
||||
Editable editable = editText.getText();
|
||||
int len = editable.length();
|
||||
|
||||
if(len > maxLen)
|
||||
{
|
||||
int selEndIndex = Selection.getSelectionEnd(editable);
|
||||
String str = editable.toString();
|
||||
//截取新字符串
|
||||
String newStr = str.substring(0,maxLen);
|
||||
editText.setText(newStr);
|
||||
editable = editText.getText();
|
||||
|
||||
//新字符串的长度
|
||||
int newLen = editable.length();
|
||||
//旧光标位置超过字符串长度
|
||||
if(selEndIndex > newLen)
|
||||
{
|
||||
selEndIndex = editable.length();
|
||||
}
|
||||
//设置新光标所在的位置
|
||||
Selection.setSelection(editable, selEndIndex);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
113
nebula-sdk/src/main/java/com/android/util/MimeType.java
Normal file
113
nebula-sdk/src/main/java/com/android/util/MimeType.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package com.android.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MimeType {
|
||||
|
||||
public static final int VIDEO_MIME_TYPE=0x01;
|
||||
public static final int IMAGE_MIME_TYPE=0x02;
|
||||
public static final int APP_MIME_TYPE=0x03;
|
||||
public static final int UNKNOWN_MIME_TYPE=0x04;
|
||||
private static Map<String,String> map=new HashMap<>();
|
||||
static final String[][] MIME_MapTable={
|
||||
//{后缀名, MIME类型}
|
||||
{".3gp", "video/3gpp"},
|
||||
{".apk", "application/vnd.android.package-archive"},
|
||||
{".asf", "video/x-ms-asf"},
|
||||
{".avi", "video/x-msvideo"},
|
||||
{".bin", "application/octet-stream"},
|
||||
{".bmp", "image/bmp"},
|
||||
{".c", "text/plain"},
|
||||
{".class", "application/octet-stream"},
|
||||
{".conf", "text/plain"},
|
||||
{".cpp", "text/plain"},
|
||||
{".doc", "application/msword"},
|
||||
{".exe", "application/octet-stream"},
|
||||
{".gif", "image/gif"},
|
||||
{".gtar", "application/x-gtar"},
|
||||
{".gz", "application/x-gzip"},
|
||||
{".h", "text/plain"},
|
||||
{".htm", "text/html"},
|
||||
{".html", "text/html"},
|
||||
{".jar", "application/java-archive"},
|
||||
{".java", "text/plain"},
|
||||
{".jpeg", "image/jpeg"},
|
||||
{".jpg", "image/jpeg"},
|
||||
{".js", "application/x-javascript"},
|
||||
{".log", "text/plain"},
|
||||
{".m3u", "audio/x-mpegurl"},
|
||||
{".m4a", "audio/mp4a-latm"},
|
||||
{".m4b", "audio/mp4a-latm"},
|
||||
{".m4p", "audio/mp4a-latm"},
|
||||
{".m4u", "video/vnd.mpegurl"},
|
||||
{".m4v", "video/x-m4v"},
|
||||
{".mov", "video/quicktime"},
|
||||
{".mp2", "audio/x-mpeg"},
|
||||
{".mp3", "audio/x-mpeg"},
|
||||
{".mp4", "video/mp4"},
|
||||
{".mpc", "application/vnd.mpohun.certificate"},
|
||||
{".mpe", "video/mpeg"},
|
||||
{".mpeg", "video/mpeg"},
|
||||
{".mpg", "video/mpeg"},
|
||||
{".mpg4", "video/mpg4"},
|
||||
{".mpga", "audio/mpeg"},
|
||||
{".msg", "application/vnd.ms-outlook"},
|
||||
{".ogg", "audio/ogg"},
|
||||
{".pdf", "application/pdf"},
|
||||
{".png", "image/png"},
|
||||
{".pps", "application/vnd.ms-powerpoint"},
|
||||
{".ppt", "application/vnd.ms-powerpoint"},
|
||||
{".prop", "text/plain"},
|
||||
{".rar", "application/x-rar-compressed"},
|
||||
{".rc", "text/plain"},
|
||||
{".rmvb", "audio/x-pn-realaudio"},
|
||||
{".rtf", "application/rtf"},
|
||||
{".sh", "text/plain"},
|
||||
{".tar", "application/x-tar"},
|
||||
{".tgz", "application/x-compressed"},
|
||||
{".txt", "text/plain"},
|
||||
{".wav", "audio/x-wav"},
|
||||
{".wma", "audio/x-ms-wma"},
|
||||
{".wmv", "audio/x-ms-wmv"},
|
||||
{".wps", "application/vnd.ms-works"},
|
||||
//{".xml", "text/xml"},
|
||||
{".xml", "text/plain"},
|
||||
{".z", "application/x-compress"},
|
||||
{".zip", "application/zip"},
|
||||
{"", "*/*"}
|
||||
};
|
||||
static{
|
||||
for (int i=0;i<MIME_MapTable.length;i++){
|
||||
String[] tmpArray= MIME_MapTable[i];
|
||||
map.put(tmpArray[1],tmpArray[0]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static String getMimeTypeSuffix(String mimeType){
|
||||
return map.get(mimeType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static int checkFileMimeType(String mimeType){
|
||||
if(mimeType==null||"".equals(mimeType)){
|
||||
return UNKNOWN_MIME_TYPE;
|
||||
}
|
||||
if(mimeType.contains("video/")){
|
||||
return VIDEO_MIME_TYPE;
|
||||
}else if(mimeType.contains("image/")){
|
||||
return IMAGE_MIME_TYPE;
|
||||
}else if(mimeType.contains("application/")){
|
||||
return APP_MIME_TYPE;
|
||||
}else {
|
||||
return UNKNOWN_MIME_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
51
nebula-sdk/src/main/java/com/android/util/NetUtil.java
Normal file
51
nebula-sdk/src/main/java/com/android/util/NetUtil.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package com.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
|
||||
/**
|
||||
* Created by hanbin on 2017/9/12.
|
||||
*/
|
||||
|
||||
public class NetUtil {
|
||||
/**
|
||||
* 没有网络
|
||||
*/
|
||||
public static final int NETWORK_NONE = -1;
|
||||
/**
|
||||
* 移动网络
|
||||
*/
|
||||
public static final int NETWORK_MOBILE = 0;
|
||||
/**
|
||||
* 无线网络
|
||||
*/
|
||||
public static final int NETWORK_WIFI = 1;
|
||||
/**
|
||||
* 以太网
|
||||
*/
|
||||
public static final int NETWORK_ETHERNET = 2;
|
||||
|
||||
public static int getNetWorkState(Context context) {
|
||||
//得到连接管理器对象
|
||||
ConnectivityManager connectivityManager = (ConnectivityManager) context
|
||||
.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
NetworkInfo activeNetworkInfo = connectivityManager
|
||||
.getActiveNetworkInfo();
|
||||
//如果网络连接,判断该网络类型
|
||||
if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
|
||||
if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_WIFI)) {
|
||||
return NETWORK_WIFI;//wifi
|
||||
} else if (activeNetworkInfo.getType() == (ConnectivityManager.TYPE_MOBILE)) {
|
||||
return NETWORK_MOBILE;//mobile
|
||||
}else if(activeNetworkInfo.getType() ==(ConnectivityManager.TYPE_ETHERNET) ){
|
||||
return NETWORK_ETHERNET;//ethernet
|
||||
}
|
||||
} else {
|
||||
//网络异常
|
||||
return NETWORK_NONE;
|
||||
}
|
||||
return NETWORK_NONE;
|
||||
}
|
||||
}
|
||||
22
nebula-sdk/src/main/java/com/android/util/NetworkType.java
Normal file
22
nebula-sdk/src/main/java/com/android/util/NetworkType.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.android.util;
|
||||
|
||||
public enum NetworkType {
|
||||
NETWORK_WIFI("WiFi"),
|
||||
NETWORK_4G("4G"),
|
||||
NETWORK_2G("2G"),
|
||||
NETWORK_3G("3G"),
|
||||
NETWORK_ETHERNET("Ethernet"),
|
||||
NETWORK_UNKNOWN("Unknown"),
|
||||
NETWORK_NO("No network");
|
||||
|
||||
private String desc;
|
||||
NetworkType(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user