From 0c27e60b29ec286ef8bfc65ccaf9476945b9b650 Mon Sep 17 00:00:00 2001 From: fanhuitong <981964879@qq.com> Date: Fri, 17 Sep 2021 18:26:42 +0800 Subject: [PATCH] =?UTF-8?q?version:2.2.6=20update:=20fix:=E5=9C=A8?= =?UTF-8?q?=E7=BA=BF=E7=8A=B6=E6=80=81=E6=9B=B4=E6=96=B0=20add:=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=B8=85=E9=99=A4=E6=9E=81=E5=85=89=E5=88=AB=E5=90=8D?= =?UTF-8?q?=E8=BF=87=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/CMakeLists.txt | 44 +++ app/build.gradle | 51 ++-- app/src/main/AndroidManifest.xml | 14 +- .../myappstore/activity/HomeActivity.java | 35 +-- .../myappstore/activity/MainActivity.java | 18 +- .../myappstore/activity/MainPresenter.java | 231 ++++++++++----- .../mjsheng/myappstore/base/BaseActivity.java | 5 +- .../myappstore/base/BaseApplication.java | 65 ++++- .../manager/NetInterfaceManager.java | 13 +- .../myappstore/network/HTTPInterface.java | 131 ++++++--- .../myappstore/network/URLAddress.java | 6 + .../myappstore/receiver/BootReceiver.java | 62 +++- .../myappstore/receiver/MyJPushReceiver.java | 54 +++- .../myappstore/receiver/NewAppReceiver.java | 5 + .../myappstore/service/GuardService.java | 4 +- .../myappstore/service/MainService.java | 36 ++- .../myappstore/service/StepService.java | 145 +++++++--- .../mjsheng/myappstore/utils/ApkUtils.java | 2 +- .../myappstore/utils/ForegroundAppUtil.java | 22 ++ .../mjsheng/myappstore/utils/JGYUtils.java | 39 ++- .../myappstore/utils/ServiceAliveUtils.java | 4 +- .../myappstore/utils/SysSettingUtils.java | 9 +- .../mjsheng/myappstore/utils/ToastUtil.java | 47 ++- .../mjsheng/myappstore/utils/URLUtils.java | 89 ++++-- app/src/main/jni/jgy.cpp | 44 +++ .../main/res/drawable-hdpi/main_device.png | Bin 0 -> 2583 bytes app/src/main/res/drawable-hdpi/main_grade.png | Bin 0 -> 3632 bytes app/src/main/res/drawable-hdpi/main_mac.png | Bin 0 -> 2996 bytes .../main/res/drawable-hdpi/main_nickname.png | Bin 0 -> 3525 bytes .../main/res/drawable-hdpi/main_school.png | Bin 0 -> 2988 bytes .../main/res/drawable-hdpi/main_version.png | Bin 0 -> 3288 bytes .../main/res/layout-land/activity_main.xml | 235 +++++++++------ .../main/res/layout-port/activity_main.xml | 267 ++++++++++-------- 33 files changed, 1189 insertions(+), 488 deletions(-) create mode 100644 app/CMakeLists.txt create mode 100644 app/src/main/jni/jgy.cpp create mode 100644 app/src/main/res/drawable-hdpi/main_device.png create mode 100644 app/src/main/res/drawable-hdpi/main_grade.png create mode 100644 app/src/main/res/drawable-hdpi/main_mac.png create mode 100644 app/src/main/res/drawable-hdpi/main_nickname.png create mode 100644 app/src/main/res/drawable-hdpi/main_school.png create mode 100644 app/src/main/res/drawable-hdpi/main_version.png diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..d914d8d --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,44 @@ +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html + +# Sets the minimum version of CMake required to build the native library. + +cmake_minimum_required(VERSION 3.4.1) + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. + +add_library( # Sets the name of the library. + jgy + + # Sets the library as a shared library. + SHARED + + # Provides a relative path to your source file(s). + src/main/jni/jgy.cpp ) + +# Searches for a specified prebuilt library and stores the path as a +# variable. Because CMake includes system libraries in the search path by +# default, you only need to specify the name of the public NDK library +# you want to add. CMake verifies that the library exists before +# completing its build. + +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + log ) + +# Specifies libraries CMake should link to your target library. You +# can link multiple libraries, such as libraries you define in this +# build script, prebuilt third-party libraries, or system libraries. + +target_link_libraries( # Specifies the target library. + jgy + + # Links the target library to the log library + # included in the NDK. + ${log-lib} ) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 4488782..789823c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,47 +41,48 @@ android { //新平台正式 newly { flavorDimensions "default" - versionCode 623 + versionCode 626 //versionCode 1037 - versionName "2.2.3" + versionName "2.2.6" /*********************************极光推送************************************/ manifestPlaceholders = [ JPUSH_PKGNAME: "com.jiaoguanyi.appstore", JPUSH_APPKEY : "20f70bbeb78bad23eddd08d0", //JPush上注册的包名对应的appkey. JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可. - channel_value: "newly" , + channel_value: "newly", // AMAP_KEY: "546eb5646a65ac6a5b7d1c7456466e05" ] /*********************************极光推送end************************************/ buildConfigField "String", "ROOT_URL", '"http://name.jiaoguanyi.cn/api/"' - buildConfigField "String", "WebsocketURL", '"ws://47.119.147.245:2345"' +// buildConfigField "String", "WebsocketURL", '"ws://47.119.147.245:2345"' + buildConfigField "String", "WebsocketURL", '"wss://name.jiaoguanyi.cn:2018"' buildConfigField "String", "SCREEN_URL", '"https://name.jiaoguanyi.cn:2018/wm/is_online"' } MTKnewly { flavorDimensions "default" - versionCode 717 + versionCode 719 //versionCode 1037 - versionName "2.1.7" + versionName "2.1.9" /*********************************极光推送************************************/ manifestPlaceholders = [ JPUSH_PKGNAME: "com.jiaoguanyi.appstore", JPUSH_APPKEY : "20f70bbeb78bad23eddd08d0", //JPush上注册的包名对应的appkey. JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可. - channel_value: "newly" , + channel_value: "newly", // AMAP_KEY: "546eb5646a65ac6a5b7d1c7456466e05" ] /*********************************极光推送end************************************/ buildConfigField "String", "ROOT_URL", '"http://name.jiaoguanyi.cn/api/"' - buildConfigField "String", "WebsocketURL", '"ws://47.119.147.245:2345"' + buildConfigField "String", "WebsocketURL", '"wss://name.jiaoguanyi.cn:2018"' buildConfigField "String", "SCREEN_URL", '"https://name.jiaoguanyi.cn:2018/wm/is_online"' } //新平台测试 beta { flavorDimensions "default" - versionCode 2 - versionName "1.1" + versionCode 4 + versionName "1.3" // versionCode 633 // versionName "2.2.3" /*********************************极光推送************************************/ @@ -89,12 +90,12 @@ android { JPUSH_PKGNAME: "com.jiaoguanyi.appstore", JPUSH_APPKEY : "52d81643665bb2cadacf0e9e", //JPush上注册的包名对应的appkey. JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可. - channel_value: "beta" , + channel_value: "beta", // AMAP_KEY: "5b68c8ee39800ff700a3762b6e028b78" ] /*********************************极光推送end************************************/ buildConfigField "String", "ROOT_URL", '"http://name.uiuios.com/api/"' - buildConfigField "String", "WebsocketURL", '"ws://39.108.116.195:2345"' + buildConfigField "String", "WebsocketURL", '"wss://name.uiuios.com:2018"' buildConfigField "String", "SCREEN_URL", '"https://name.uiuios.com:2018/wm/is_online"' versionNameSuffix "-beta" } @@ -185,16 +186,16 @@ android { // Disable release builds for now android.variantFilter { variant -> if (variant.buildType.name.endsWith('zhanRuiRelease')) { - variant.setIgnore(variant.getFlavors().get(0).name.equals('official')||variant.getFlavors().get(0).name.equals('zhongyou')) + variant.setIgnore(variant.getFlavors().get(0).name.equals('official') || variant.getFlavors().get(0).name.equals('zhongyou')) } if (variant.buildType.name.endsWith('zhanRuiDebug')) { - variant.setIgnore(variant.getFlavors().get(0).name.equals('official')||variant.getFlavors().get(0).name.equals('zhongyou')) + variant.setIgnore(variant.getFlavors().get(0).name.equals('official') || variant.getFlavors().get(0).name.equals('zhongyou')) } - if (name.contains("MTKnewly")){ - variant.setIgnore(variant.buildType.name.endsWith("zhanRuiRelease")||variant.buildType.name.endsWith("zhanRuiDebug")||variant.buildType.name.endsWith("zhanRuiUserdebug") - ||variant.buildType.name.endsWith("zhanRuiUserdebugReleas")) + if (name.contains("MTKnewly")) { + variant.setIgnore(variant.buildType.name.endsWith("zhanRuiRelease") || variant.buildType.name.endsWith("zhanRuiDebug") || variant.buildType.name.endsWith("zhanRuiUserdebug") + || variant.buildType.name.endsWith("zhanRuiUserdebugReleas")) } - if (name.endsWith("newlyDebug")||name.endsWith("newlyRelease")){ + if (name.endsWith("newlyDebug") || name.endsWith("newlyRelease")) { variant.setIgnore(!name.contains("MTK")) } @@ -297,10 +298,15 @@ android { } } } + externalNativeBuild { + cmake { + path file('CMakeLists.txt') + } + } } dependencies { - //implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation fileTree(dir: "libs", include: ["*.jar"]) compileOnly files('src/main/libs/classes.jar') implementation 'androidx.appcompat:appcompat:1.3.1' @@ -336,7 +342,8 @@ dependencies { //okhttp框架 implementation 'com.github.liujingxing.rxhttp:rxhttp:2.6.5' //implementation 'com.squareup.okhttp3:okhttp:4.9.1' //rxhttp v2.2.2版本起,需要手动依赖okhttp - annotationProcessor 'com.github.liujingxing.rxhttp:rxhttp-compiler:2.6.5' //生成RxHttp类,纯Java项目,请使用annotationProcessor代替kapt + annotationProcessor 'com.github.liujingxing.rxhttp:rxhttp-compiler:2.6.5' + //生成RxHttp类,纯Java项目,请使用annotationProcessor代替kapt implementation 'com.github.liujingxing.rxlife:rxlife-coroutine:2.1.0' //管理协程生命周期,页面销毁,关闭请求 //rxjava2 (RxJava2/Rxjava3二选一,使用asXxx方法时必须) //implementation 'io.reactivex.rxjava2:rxjava:2.2.8' @@ -350,6 +357,10 @@ dependencies { implementation 'com.amap.api:location:5.1.0' //压缩文件解压 implementation 'org.zeroturnaround:zt-zip:1.13' + //生命周期管理 + implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.2' + implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.2' + implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.2' } preBuild { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 88dda0f..8259288 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -125,7 +125,19 @@ + android:exported="true" > + + + + + + + + + + + + provider; + + public void setProvider(LifecycleProvider provider) { + this.provider = provider; + } + + public LifecycleProvider getProvider() { + return provider; + } + public MainPresenter(Context context) { this.mContext = context; Logutils.e(TAG, "MainPresenter: " + context.getClass()); @@ -119,6 +132,7 @@ public class MainPresenter implements MainContact.Presenter { setState(); NetInterfaceManager.getInstance() .getStudesInfoObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -220,10 +234,17 @@ public class MainPresenter implements MainContact.Presenter { } } + private long lastgetLockedTime; + @Override public void getLockedState() { +// if (System.currentTimeMillis() - lastgetLockedTime < 600 * 1000) { +// return; +// } +// lastgetLockedTime = System.currentTimeMillis(); NetInterfaceManager.getInstance() .getDevicesLockedStateObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -272,6 +293,7 @@ public class MainPresenter implements MainContact.Presenter { Logutils.e(TAG + ":" + "getLockedState", "onComplete: "); } }); +// lastgetLockedTime = System.currentTimeMillis(); } /** @@ -292,11 +314,24 @@ public class MainPresenter implements MainContact.Presenter { } + private long lastSendMACTime; + @Override public void sendMACAddress() { + if (System.currentTimeMillis() - lastSendMACTime < 60 * 60 * 1000) { + mView.sendMACFinished(); + return; + } + lastSendMACTime = System.currentTimeMillis(); + String macJson = (String) SPUtils.get(mContext, "macJson", ""); + if (macJson.equals(JGYUtils.getInstance().getMacJson())) { + mView.sendMACFinished(); + return; + } NetInterfaceManager.getInstance() .sendMACAddressObservable() .observeOn(Schedulers.io()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -307,6 +342,7 @@ public class MainPresenter implements MainContact.Presenter { public void onNext(@NonNull BaseResponse response) { if (response.code == OK) { Logutils.e(TAG + ":" + "sendMACAddress", response.msg); + SPUtils.put(mContext, "macJson", JGYUtils.getInstance().getMacJson()); } else { Logutils.e(TAG + ":" + "sendMACAddress", response.toString()); } @@ -321,6 +357,7 @@ public class MainPresenter implements MainContact.Presenter { @Override public void onComplete() { Logutils.e(TAG + ":" + "sendMACAddress", "onComplete: "); + lastSendMACTime = System.currentTimeMillis(); mView.sendMACFinished(); } }); @@ -359,6 +396,7 @@ public class MainPresenter implements MainContact.Presenter { add) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -396,6 +434,7 @@ public class MainPresenter implements MainContact.Presenter { } NetInterfaceManager.getInstance() .getSnTimeObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -443,7 +482,9 @@ public class MainPresenter implements MainContact.Presenter { @Override public void getEBagCode() { - NetInterfaceManager.getInstance().getEBagCodeControl() + NetInterfaceManager.getInstance() + .getEBagCodeControl() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { @@ -502,6 +543,7 @@ public class MainPresenter implements MainContact.Presenter { public void setJpushTags() { NetInterfaceManager.getInstance() .getJpushTagsObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -579,6 +621,7 @@ public class MainPresenter implements MainContact.Presenter { JGYUtils.getInstance().checkAppPlatform()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -620,6 +663,7 @@ public class MainPresenter implements MainContact.Presenter { JGYUtils.getInstance().checkAppPlatform()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -655,8 +699,8 @@ public class MainPresenter implements MainContact.Presenter { @Override public void buttonCheckUpdate(View view) { -// if ((SystemClock.elapsedRealtime() - buttonCheckUpdateTime) < 10000) { -// buttonCheckUpdateTime = SystemClock.elapsedRealtime(); +// if ((System.currentTimeMillis() - buttonCheckUpdateTime) < 10000) { +// buttonCheckUpdateTime = System.currentTimeMillis(); // ToastUtil.show("正在检查更新"); // } else { // ToastUtil.show("你已经过检查,请稍后再来"); @@ -671,6 +715,7 @@ public class MainPresenter implements MainContact.Presenter { JGYUtils.getInstance().checkAppPlatform()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -720,6 +765,7 @@ public class MainPresenter implements MainContact.Presenter { public void checkTestUpdate() { NetInterfaceManager.getInstance() .getTestUpdateObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer>>() { @Override public void onSubscribe(Disposable d) { @@ -764,6 +810,7 @@ public class MainPresenter implements MainContact.Presenter { public void getAppLimit() { NetInterfaceManager.getInstance() .getAppLimitObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -878,6 +925,7 @@ public class MainPresenter implements MainContact.Presenter { public void getForceDownload() { NetInterfaceManager.getInstance() .getForceDownloadObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -939,59 +987,59 @@ public class MainPresenter implements MainContact.Presenter { @Override public void getBrowserList() { // NetInterfaceManager.getInstance() -// .getBrowserListSettingObservable() -// .observeOn(Schedulers.io()) -// .subscribe(new Observer>() { -// @Override -// public void onSubscribe(@NonNull Disposable d) { -// Logutils.e(TAG + ":" + "getBrowserList", "onSubscribe: "); -// } -// -// @Override -// public void onNext(@NonNull BaseResponse browserDataBaseResponse) { -// Logutils.e(TAG + ":" + "getBrowserList", "onNext: "); -// if (browserDataBaseResponse.code == OK) { -// String white = browserDataBaseResponse.data.getWhite(); -// -// if (!TextUtils.isEmpty(white)) { -// String homePage = Settings.System.getString(mContext.getContentResolver(), "homepagURL"); -// if (!TextUtils.isEmpty(homePage) && !white.contains(homePage)) { -// white += "," + homePage; -// } -// boolean whiteList = Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", white); -// Logutils.e(TAG + ":" + "getBrowserList", "setBrowserList white: " + white + ":" + whiteList); -// mView.getBrowserListFinished(white); -// } else { -// Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", " "); -// mView.getBrowserListFinished(""); -// } -// String black = browserDataBaseResponse.data.getBlack(); -// if (!TextUtils.isEmpty(black)) { -// boolean blackList = Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url", black); -// Logutils.e(TAG + ":" + "getBrowserList", "setBrowserList black: " + black + ":" + blackList); -// } else { -// Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url", " "); -// } -// } else { -// mView.getBrowserListFinished(""); -// } -// } -// -// @Override -// public void onError(@NonNull Throwable e) { -// Logutils.e(TAG + ":" + "getBrowserList", "onError: " + e.getMessage()); -// String whiteURLList = Settings.System.getString(mContext.getContentResolver(), "DeselectBrowserArray"); -// Logutils.e(TAG + ":" + "getBrowserList", "whiteURLList: " + whiteURLList); -// mView.getBrowserListFinished(whiteURLList); -// onComplete(); -// } -// -// @Override -// public void onComplete() { -// Logutils.e(TAG + ":" + "getBrowserList", "onComplete: "); -// } -// }); - //获取书签后会获取黑白名单 + //// .getBrowserListSettingObservable() + //// .observeOn(Schedulers.io()) + //// .subscribe(new Observer>() { + //// @Override + //// public void onSubscribe(@NonNull Disposable d) { + //// Logutils.e(TAG + ":" + "getBrowserList", "onSubscribe: "); + //// } + //// + //// @Override + //// public void onNext(@NonNull BaseResponse browserDataBaseResponse) { + //// Logutils.e(TAG + ":" + "getBrowserList", "onNext: "); + //// if (browserDataBaseResponse.code == OK) { + //// String white = browserDataBaseResponse.data.getWhite(); + //// + //// if (!TextUtils.isEmpty(white)) { + //// String homePage = Settings.System.getString(mContext.getContentResolver(), "homepagURL"); + //// if (!TextUtils.isEmpty(homePage) && !white.contains(homePage)) { + //// white += "," + homePage; + //// } + //// boolean whiteList = Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", white); + //// Logutils.e(TAG + ":" + "getBrowserList", "setBrowserList white: " + white + ":" + whiteList); + //// mView.getBrowserListFinished(white); + //// } else { + //// Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", " "); + //// mView.getBrowserListFinished(""); + //// } + //// String black = browserDataBaseResponse.data.getBlack(); + //// if (!TextUtils.isEmpty(black)) { + //// boolean blackList = Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url", black); + //// Logutils.e(TAG + ":" + "getBrowserList", "setBrowserList black: " + black + ":" + blackList); + //// } else { + //// Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url", " "); + //// } + //// } else { + //// mView.getBrowserListFinished(""); + //// } + //// } + //// + //// @Override + //// public void onError(@NonNull Throwable e) { + //// Logutils.e(TAG + ":" + "getBrowserList", "onError: " + e.getMessage()); + //// String whiteURLList = Settings.System.getString(mContext.getContentResolver(), "DeselectBrowserArray"); + //// Logutils.e(TAG + ":" + "getBrowserList", "whiteURLList: " + whiteURLList); + //// mView.getBrowserListFinished(whiteURLList); + //// onComplete(); + //// } + //// + //// @Override + //// public void onComplete() { + //// Logutils.e(TAG + ":" + "getBrowserList", "onComplete: "); + //// } + //// }); + // //获取书签后会获取黑白名单 Log.e(TAG, "getBrowserList: "); mView.getBrowserListFinished(""); } @@ -1000,6 +1048,7 @@ public class MainPresenter implements MainContact.Presenter { NetInterfaceManager.getInstance() .getBrowserListSettingObservable() .observeOn(Schedulers.io()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1061,6 +1110,7 @@ public class MainPresenter implements MainContact.Presenter { NetInterfaceManager.getInstance() .getBrowserListSettingObservable() .observeOn(Schedulers.io()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1223,14 +1273,25 @@ public class MainPresenter implements MainContact.Presenter { @Override public void onComplete() { Logutils.e(TAG + ":" + "getBrowserBookmarks", "onComplete: "); - mView.getBrowserBookmarksFinished(); +// String homepagURL = Settings.System.getString(mContext.getContentResolver(), "homepagURL"); +// HashSet hashSet = new HashSet<>(Arrays.asList(whitelist.split(","))); +// hashSet.add(homepagURL); +// String DeselectBrowserArray = String.join(",", hashSet); +// if (Utils.isEmpty(DeselectBrowserArray)) { +// Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", " "); +// } else { +// Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", DeselectBrowserArray); +// } + if (mView != null) { + mView.getBrowserBookmarksFinished(); + } } }); } @Override public void getBrowserWhiteList() { - new URLUtils(mContext).setBrowserWhiteList(); +// new URLUtils(mContext).setBrowserWhiteList(); new URLUtils(mContext).setBrowserBlackList(); // try { @@ -1252,6 +1313,7 @@ public class MainPresenter implements MainContact.Presenter { NetInterfaceManager.getInstance() .getDesktopIconObservable() .observeOn(Schedulers.io()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1313,6 +1375,7 @@ public class MainPresenter implements MainContact.Presenter { .getAppAutoStartUpdateAndNetObservable() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1348,6 +1411,7 @@ public class MainPresenter implements MainContact.Presenter { NetInterfaceManager.getInstance() .getAppIDControlObservable() .observeOn(Schedulers.io()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1402,7 +1466,9 @@ public class MainPresenter implements MainContact.Presenter { @Override public void onComplete() { Log.e(TAG, "setAppinsideWeb: " + "onComplete"); - mView.setAppinsideWebFinished(); + if (mView != null) { + mView.setAppinsideWebFinished(); + } } }); } @@ -1413,6 +1479,7 @@ public class MainPresenter implements MainContact.Presenter { NetInterfaceManager.getInstance() .getSystemSettingObservable() .observeOn(Schedulers.io()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1469,6 +1536,7 @@ public class MainPresenter implements MainContact.Presenter { public void getDefaultApp() { NetInterfaceManager.getInstance() .getDefaultAppApi() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer>() { @Override public void onSubscribe(Disposable d) { @@ -1482,6 +1550,9 @@ public class MainPresenter implements MainContact.Presenter { if (code == OK) { DefaultApp defaultApp = defaultAppBaseResponse.data; JGYUtils.getInstance().setDefaultDesktop(defaultApp.getDefault_launcher()); + if (defaultApp.getDefault_launcher() != null) { + SPUtils.put(mContext, "default_launcher", defaultApp.getDefault_launcher()); + } } else { Log.e("getDefaultApp", "onNext: " + defaultAppBaseResponse.msg); } @@ -1509,6 +1580,7 @@ public class MainPresenter implements MainContact.Presenter { .getROMApp(NetInterfaceManager.HTTP_KEY, customVersion) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { @@ -1545,7 +1617,9 @@ public class MainPresenter implements MainContact.Presenter { @Override public void getDeveloper() { - NetInterfaceManager.getInstance().getDeveloperControl() + NetInterfaceManager.getInstance() + .getDeveloperControl() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { @@ -1592,6 +1666,7 @@ public class MainPresenter implements MainContact.Presenter { } NetInterfaceManager.getInstance() .getLogoImgObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1638,7 +1713,9 @@ public class MainPresenter implements MainContact.Presenter { mView.setTopAppFinished(); return; } - NetInterfaceManager.getInstance().getTopAppControl() + NetInterfaceManager.getInstance() + .getTopAppControl() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { @@ -1651,9 +1728,11 @@ public class MainPresenter implements MainContact.Presenter { if (response.code == OK) { JSONObject jsonObject = (JSONObject) JSON.toJSON(response.data); String app_package = jsonObject.getString("app_package"); + ForegroundAppUtil.setTopAppClass(mContext, app_package); SPUtils.put(mContext, ForegroundAppUtil.TOPAPP_KEY, app_package); ForegroundAppUtil.openTopApp(mContext); } else { + ForegroundAppUtil.setTopAppClass(mContext, ""); SPUtils.put(mContext, ForegroundAppUtil.TOPAPP_KEY, ""); } } @@ -1673,8 +1752,16 @@ public class MainPresenter implements MainContact.Presenter { }); } + //上次运行的时间 + private long lastRunTime; + @Override synchronized public void getScreenLockState() { + if (System.currentTimeMillis() - lastRunTime < 60 * 1000) { + Log.e(TAG, "getScreenLockState: " + lastRunTime); + return; + } + lastRunTime = System.currentTimeMillis(); int locked = Settings.System.getInt(mContext.getContentResolver(), "qch_unlock_ipad", 0); if (JGYUtils.isOfficialVersion() || locked == 1) { mView.setScreenLockStateFinished(false, ""); @@ -1682,6 +1769,7 @@ public class MainPresenter implements MainContact.Presenter { } NetInterfaceManager.getInstance() .getScreenLockObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1706,11 +1794,15 @@ public class MainPresenter implements MainContact.Presenter { @Override public void onError(@NonNull Throwable e) { Logutils.e(TAG + ":" + "getScreenLockState", "onError: " + e.getMessage()); + boolean is_screen_lock = (boolean) SPUtils.get(mContext, "is_screen_lock", false); + String screen_tips = (String) SPUtils.get(mContext, "screen_tips", ""); + mView.setScreenLockStateFinished(is_screen_lock, screen_tips); onComplete(); } @Override public void onComplete() { + lastRunTime = System.currentTimeMillis(); Logutils.e(TAG + ":" + "getScreenLockState", "onComplete: "); } }); @@ -1725,6 +1817,7 @@ public class MainPresenter implements MainContact.Presenter { } NetInterfaceManager.getInstance() .getDesktopObservable() + .compose(getProvider().bindUntilEvent(ActivityEvent.DESTROY)) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -1742,10 +1835,18 @@ public class MainPresenter implements MainContact.Presenter { JGYUtils.getInstance().installDesktop(data); } else { Logutils.e(TAG + ":" + "getDefaultDesktop", "onNext: " + "删除定制桌面"); - ApkUtils.UninstallAPP(mContext, ApkUtils.desktopAPP.get(0)); - ApkUtils.UninstallAPP(mContext, ApkUtils.desktopAPP.get(1)); + String whiteList = Settings.System.getString(mContext.getContentResolver(), "only_jgy_shortcut_list"); + if (!TextUtils.isEmpty(whiteList)) { + if (!whiteList.contains(ApkUtils.desktopAPP.get(0))) { + ApkUtils.UninstallAPP(mContext, ApkUtils.desktopAPP.get(0)); + Log.e(TAG + ":" + "getDefaultDesktop", "skip: " + ApkUtils.desktopAPP.get(0)); + } + if (!whiteList.contains(ApkUtils.desktopAPP.get(1))) { + ApkUtils.UninstallAPP(mContext, ApkUtils.desktopAPP.get(1)); + Log.e(TAG + ":" + "getDefaultDesktop", "skip: " + ApkUtils.desktopAPP.get(1)); + } + } } - } catch (IOException e) { e.printStackTrace(); Logutils.e(TAG + ":" + "getDefaultDesktop", "onNext: IOException: " + e.getMessage()); @@ -1761,7 +1862,7 @@ public class MainPresenter implements MainContact.Presenter { @Override public void onComplete() { Logutils.e(TAG + ":" + "getDefaultDesktop", "onComplete: "); - HTTPInterface.getAllAppList(); + HTTPInterface.getAllAppList(mContext); mView.getDefaultDesktopFinished(); } }); diff --git a/app/src/main/java/com/mjsheng/myappstore/base/BaseActivity.java b/app/src/main/java/com/mjsheng/myappstore/base/BaseActivity.java index 819fb84..d277a34 100644 --- a/app/src/main/java/com/mjsheng/myappstore/base/BaseActivity.java +++ b/app/src/main/java/com/mjsheng/myappstore/base/BaseActivity.java @@ -3,9 +3,10 @@ package com.mjsheng.myappstore.base; import android.os.Bundle; import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -public abstract class BaseActivity extends AppCompatActivity { +import com.trello.rxlifecycle2.components.support.RxAppCompatActivity; + +public abstract class BaseActivity extends RxAppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/app/src/main/java/com/mjsheng/myappstore/base/BaseApplication.java b/app/src/main/java/com/mjsheng/myappstore/base/BaseApplication.java index dc737e3..8aa152c 100644 --- a/app/src/main/java/com/mjsheng/myappstore/base/BaseApplication.java +++ b/app/src/main/java/com/mjsheng/myappstore/base/BaseApplication.java @@ -4,6 +4,7 @@ import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Process; +import android.util.Log; import androidx.multidex.MultiDexApplication; @@ -34,6 +35,9 @@ import com.mjsheng.myappstore.utils.ToastUtil; import com.mjsheng.myappstore.utils.Utils; import com.mjsheng.myappstore.utils.XAPKUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -47,6 +51,9 @@ import io.reactivex.ObservableOnSubscribe; import io.reactivex.Observer; import io.reactivex.disposables.Disposable; import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; import okhttp3.Response; /** @@ -149,11 +156,6 @@ public class BaseApplication extends MultiDexApplication { HTTPInterface.setJpushTags(context); } - synchronized public static void clean() { - //alias的绑定的设备超过10个,但是alias应该是一个设备对应一个,在重置设备后jpush的regid会变动,所以需要清除 - //https://docs.jiguang.cn/jpush/server/push/rest_api_v3_device/#_5 - HTTPInterface.cleanJpushAlias(Utils.getSerial()); - } private static void initAliasObservable() { Logutils.e(TAG, "initAliasObservable: "); @@ -168,7 +170,7 @@ public class BaseApplication extends MultiDexApplication { } }; } - }).throttleLast(30, TimeUnit.SECONDS) + }).throttleLast(1, TimeUnit.HOURS) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { @@ -216,7 +218,7 @@ public class BaseApplication extends MultiDexApplication { case 6017: case 6027: Logutils.e("jiguangInterface", s + "别名绑定的设备数超过限制"); - clean(); + cleanJpushAlias(); setJpushAlias(); break; default: @@ -237,6 +239,52 @@ public class BaseApplication extends MultiDexApplication { }); } + synchronized public static void cleanJpushAlias() { + //alias的绑定的设备超过10个,但是alias应该是一个设备对应一个,在重置设备后jpush的regid会变动,所以需要清除 + //https://docs.jiguang.cn/jpush/server/push/rest_api_v3_device/#_5 + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder() + .url(URLAddress.DELETE_JPUSH_ALIAS + Utils.getSerial()) + .header("Authorization", JGYUtils.getAuthorization()) + .delete() + .build(); + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + Log.e("cleanJpushAlias", "onFailure: " + e.getMessage()); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + Log.e("cleanJpushAlias", "onResponse: " + response.toString()); + Log.e(TAG, "onResponse: "+"清除Alias成功" ); + } + }); + } + + synchronized public static void cleanJpushTag() { + OkHttpClient client = new OkHttpClient(); + Request request = new Request.Builder() + .url(URLAddress.DELETE_JPUSH_TAG + Utils.getSerial()) + .header("Authorization", JGYUtils.getAuthorization()) + .delete() + .build(); + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + Log.e("cleanJpushTag", "onFailure: " + e.getMessage()); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + Log.e("cleanJpushTag", "onResponse: " + response.toString()); + Log.e(TAG, "onResponse: "+"清除Tag成功" ); + } + }); + } + private static void initTagObservable() { Logutils.e(TAG, "initTagObservable: "); Observable.create(new ObservableOnSubscribe() { @@ -250,7 +298,7 @@ public class BaseApplication extends MultiDexApplication { } }; } - }).throttleLast(30, TimeUnit.SECONDS) + }).throttleLast(1, TimeUnit.HOURS) .subscribe(new Observer() { @Override public void onSubscribe(Disposable d) { @@ -293,6 +341,7 @@ public class BaseApplication extends MultiDexApplication { break; case 6018: Logutils.e("jiguangInterface", s + "Tags 过多"); + cleanJpushTag(); ToastUtil.show("设备标签数量超出限制,联系管理员修改\t" + "code:6018"); break; case 6021: diff --git a/app/src/main/java/com/mjsheng/myappstore/manager/NetInterfaceManager.java b/app/src/main/java/com/mjsheng/myappstore/manager/NetInterfaceManager.java index 4a52361..3766048 100644 --- a/app/src/main/java/com/mjsheng/myappstore/manager/NetInterfaceManager.java +++ b/app/src/main/java/com/mjsheng/myappstore/manager/NetInterfaceManager.java @@ -4,6 +4,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.os.Environment; +import com.google.gson.JsonObject; import com.mjsheng.myappstore.BuildConfig; import com.mjsheng.myappstore.bean.Appground; import com.mjsheng.myappstore.bean.BaseResponse; @@ -50,6 +51,7 @@ import com.mjsheng.myappstore.network.api.newapi.SnTimeControl; import com.mjsheng.myappstore.network.api.newapi.StudentsInfosApi; import com.mjsheng.myappstore.network.api.newapi.TopAppControlApi; import com.mjsheng.myappstore.network.api.newapi.UpdateDeviceInfoApi; +import com.mjsheng.myappstore.utils.SPUtils; import com.mjsheng.myappstore.utils.Utils; import java.io.File; @@ -75,6 +77,7 @@ public class NetInterfaceManager { private static NetInterfaceManager INSTANCE; private Context mContext; private static Retrofit mRetrofit; + private static Retrofit jiguangRetrofit; public static final String ROOT_URL = BuildConfig.ROOT_URL; public static final String WEBSOCKET_URL = BuildConfig.WebsocketURL; @@ -90,6 +93,14 @@ public class NetInterfaceManager { .addCallAdapterFactory(rxJavaCallAdapterFactory) .build(); } + if (null == jiguangRetrofit) { + jiguangRetrofit = new Retrofit.Builder() + .client(okHttpClient) + .baseUrl(ROOT_URL) + .addConverterFactory(gsonConverterFactory) + .addCallAdapterFactory(rxJavaCallAdapterFactory) + .build(); + } } public static void init(Context context) { @@ -158,7 +169,7 @@ public class NetInterfaceManager { * @return */ public Observable sendMACAddressObservable() { - return mRetrofit + return mRetrofit .create(MACAddressApi.class) .sendMACaddress(Utils.getSerial(), Utils.getAndroid10MAC(mContext), diff --git a/app/src/main/java/com/mjsheng/myappstore/network/HTTPInterface.java b/app/src/main/java/com/mjsheng/myappstore/network/HTTPInterface.java index a0e7576..e6ee62f 100644 --- a/app/src/main/java/com/mjsheng/myappstore/network/HTTPInterface.java +++ b/app/src/main/java/com/mjsheng/myappstore/network/HTTPInterface.java @@ -8,6 +8,7 @@ import android.content.pm.PackageManager; import android.os.Build; import android.os.Handler; import android.os.Message; +import android.os.SystemClock; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; @@ -16,11 +17,17 @@ import android.util.Log; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; +import com.arialyy.aria.core.Aria; +import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import com.mjsheng.myappstore.base.BaseApplication; import com.mjsheng.myappstore.bean.AppListInfo; import com.mjsheng.myappstore.bean.BrowserBookmarks; import com.mjsheng.myappstore.bean.BrowserData; +import com.mjsheng.myappstore.bean.ForceDownloadBean; +import com.mjsheng.myappstore.bean.ForceDownloadData; import com.mjsheng.myappstore.utils.CacheUtils; import com.mjsheng.myappstore.utils.JGYUtils; import com.mjsheng.myappstore.utils.Logutils; @@ -42,8 +49,11 @@ import com.mjsheng.myappstore.utils.Logger; import com.mjsheng.myappstore.utils.SPUtils; import com.mjsheng.myappstore.utils.TimeUtils; import com.mjsheng.myappstore.utils.Utils; +import com.trello.rxlifecycle2.LifecycleProvider; +import com.trello.rxlifecycle2.android.ActivityEvent; import java.io.IOException; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -344,7 +354,7 @@ public class HTTPInterface { final com.alibaba.fastjson.JSONObject object = new com.alibaba.fastjson.JSONObject(); object.put("app_name", app_name); object.put("app_package", packageName); - object.put("MD5",app_md5); + object.put("MD5", app_md5); PackageManager pm = context.getPackageManager(); PackageInfo packageInfo = null; try { @@ -393,28 +403,6 @@ public class HTTPInterface { }); } - public static void cleanJpushAlias(String alias) { - OkGo.post(URLAddress.DELETE_GEDEVICE_ALIAS) - .params("sn", alias) - .execute(new StringCallback() { - @Override - public void onSuccess(String s, Call call, Response response) { - String body = response.body().toString(); - if ("200".equals(body)) { - Logutils.e("jiguangInterface", "alias清除成功"); - } else { - Logutils.e("jiguangInterface", "alias清除失败"); - } - } - - @Override - public void onError(Call call, Response response, Exception e) { - super.onError(call, response, e); - Logutils.e("cleanJpushAlias", e.getMessage() + "???"); - } - }); - } - public interface GetAppinsideWebCallback { void onComplete(); } @@ -882,21 +870,6 @@ public class HTTPInterface { // Logutils.e("getHomePageBookmarks", "onNext: homepagURL: homepagURL = " + homepagURL + "write: " + white); // } - //主页 - Intent homepag = new Intent("qch_app_brower_homepage"); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - homepag.setPackage("com.android.settings") - .setPackage("com.android.browser"); - } - if (!TextUtils.isEmpty(homepagURL)) { - String newHomePage = JGYUtils.getPrefixHttpsURL(homepagURL); - Logutils.e("getHomePageBookmarks", "onNext: newHomePage: " + newHomePage); - homepag.putExtra("homepage", newHomePage); - } else { - homepag.putExtra("homepage", "Invalid"); - } - context.sendBroadcast(homepag); - //书签 String labelpage = browserBookmarksBaseResponse.data.getLabelpage(); Intent websiteBookMark = new Intent("qch_app_brower_website"); @@ -917,6 +890,25 @@ public class HTTPInterface { websiteBookMark.putExtra("websiteBookMark", "Invalid"); } context.sendBroadcast(websiteBookMark); + context.sendBroadcast(websiteBookMark); + context.sendBroadcast(websiteBookMark); + + //主页 + Intent homepag = new Intent("qch_app_brower_homepage"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + homepag.setPackage("com.android.settings") + .setPackage("com.android.browser"); + } + if (!TextUtils.isEmpty(homepagURL)) { +// String newHomePage = JGYUtils.getPrefixHttpsURL(homepagURL); + Logutils.e("getHomePageBookmarks", "onNext: newHomePage: " + homepagURL); + homepag.putExtra("homepage", homepagURL); + } else { + homepag.putExtra("homepage", "Invalid"); + } + context.sendBroadcast(homepag); + context.sendBroadcast(homepag); + context.sendBroadcast(homepag); } else { Intent intent1 = new Intent("qch_app_brower_homepage"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -1159,9 +1151,11 @@ public class HTTPInterface { JSONObject jsonObject = (JSONObject) JSON.toJSON(response.data); String app_package = jsonObject.getString("app_package"); SPUtils.put(context, ForegroundAppUtil.TOPAPP_KEY, app_package); + ForegroundAppUtil.setTopAppClass(context, app_package); ForegroundAppUtil.openTopApp(context); } else { SPUtils.put(context, ForegroundAppUtil.TOPAPP_KEY, ""); + ForegroundAppUtil.setTopAppClass(context, ""); } } @@ -1200,11 +1194,8 @@ public class HTTPInterface { boolean write = Settings.System.putString(context.getContentResolver(), "only_jgy_shortcut_list", data); Logutils.e(TAG, "onNext: only_jgy_shortcut_list: " + write); JGYUtils.getInstance().writeAppPackageList(context, data); + JGYUtils.getInstance().deleteOtherApp(); } else { - //为错误的时候不删除 -// boolean write = Settings.System.putString(context.getContentResolver(), "only_jgy_shortcut_list", ""); -// Settings.System.putString(context.getContentResolver(), "qch_app_forbid", " "); -// Logutils.e(TAG, "onNext: only_jgy_shortcut_list: " + write); Logutils.e("getAppLimit", "onNext: " + bodyString); } } catch (IOException e) { @@ -1222,13 +1213,13 @@ public class HTTPInterface { @Override public void onComplete() { Logutils.e("getAppLimit", "onComplete: "); - getAllAppList(); + getAllAppList(context); } }); } - public static void getAllAppList() { + public static void getAllAppList(Context context) { NetInterfaceManager.getInstance().GetAllAppApi() .getAllAppList(NetInterfaceManager.HTTP_KEY, Utils.getSerial()) .subscribeOn(Schedulers.io()) @@ -1241,7 +1232,7 @@ public class HTTPInterface { @Override public void onNext(BaseResponse> listBaseResponse) { - Logutils.e("getAllAppList", "onNext: " + listBaseResponse.toString()); + Logutils.e("getAllAppList", "onNext: " + JSONObject.toJSONString(listBaseResponse)); int code = listBaseResponse.code; if (code == 200) { List appListInfos = listBaseResponse.data; @@ -1255,15 +1246,65 @@ public class HTTPInterface { @Override public void onError(Throwable e) { Logutils.e("getAllAppList", "onError: " + e.getMessage()); + onComplete(); } @Override public void onComplete() { Logutils.e("getAllAppList", "onComplete: "); + getForceDownload(context); } }); } + public static void getForceDownload(Context context) { + NetInterfaceManager.getInstance() + .getForceDownloadObservable() + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Logutils.e(TAG + ":" + "getForceDownload", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull ForceDownloadBean forceDownloadBean) { + Logutils.e(TAG + ":" + "getForceDownload", "onNext: "); + switch (forceDownloadBean.getCode()) { + case 200: + Logutils.e(TAG + ":" + "getForceDownload", "isDownloading=" + BaseApplication.getInstance().isDownloading()); + BaseApplication.getInstance().checkIsDownloading(); + if (!BaseApplication.getInstance().isDownloading()) { + Type type = new TypeToken>() { + }.getType(); + Gson gson = new Gson(); + List forceDownloadData = gson.fromJson(gson.toJson(forceDownloadBean.getData()), type); + JGYUtils.getInstance().forceDownload(forceDownloadData); + } else { + Aria.download(this).resumeAllTask(); + } + break; + case -200: + boolean qch_force_app = Settings.System.putString(context.getContentResolver(), "qch_force_app", "invalid"); + Logutils.e(TAG + ":" + "getForceDownload", "qch_force_app:" + qch_force_app); + break; + default: + Logutils.e(TAG + ":" + "getForceDownload", forceDownloadBean.getMsg()); + break; + } + } + + @Override + public void onError(@NonNull Throwable e) { + Logutils.e(TAG + ":" + "getForceDownload", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Logutils.e(TAG + ":" + "getForceDownload", "onComplete: "); + } + }); + } public static void getAppAutoStartUpdateAndNet(List appListInfos) { NetInterfaceManager.getInstance() diff --git a/app/src/main/java/com/mjsheng/myappstore/network/URLAddress.java b/app/src/main/java/com/mjsheng/myappstore/network/URLAddress.java index c258143..4fe03bd 100644 --- a/app/src/main/java/com/mjsheng/myappstore/network/URLAddress.java +++ b/app/src/main/java/com/mjsheng/myappstore/network/URLAddress.java @@ -2,6 +2,7 @@ package com.mjsheng.myappstore.network; import com.mjsheng.myappstore.BuildConfig; import com.mjsheng.myappstore.manager.NetInterfaceManager; +import com.mjsheng.myappstore.utils.Utils; import rxhttp.wrapper.annotation.DefaultDomain; @@ -72,4 +73,9 @@ public class URLAddress { public final static String GET_EBAG_CODE = "And/getEbagCode"; //获取系统默认程序 public final static String GET_DEFAULT_APP = "app/getDefaultApp"; + + //删除alias + public static final String DELETE_JPUSH_ALIAS = "https://device.jpush.cn/v3/aliases/" ; + //删除tags + public static final String DELETE_JPUSH_TAG = "https://device.jpush.cn/v3/tags/" ; } diff --git a/app/src/main/java/com/mjsheng/myappstore/receiver/BootReceiver.java b/app/src/main/java/com/mjsheng/myappstore/receiver/BootReceiver.java index a5a92ea..fd75034 100644 --- a/app/src/main/java/com/mjsheng/myappstore/receiver/BootReceiver.java +++ b/app/src/main/java/com/mjsheng/myappstore/receiver/BootReceiver.java @@ -3,16 +3,69 @@ package com.mjsheng.myappstore.receiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.SystemClock; +import android.util.Log; import com.mjsheng.myappstore.service.MainService; import com.mjsheng.myappstore.utils.BootManager; import com.mjsheng.myappstore.utils.JGYUtils; import com.mjsheng.myappstore.utils.Logutils; +import java.util.concurrent.TimeUnit; + +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + public class BootReceiver extends BroadcastReceiver { - private String TAG = BootReceiver.class.getSimpleName() + ":myappstore"; + private static String TAG = BootReceiver.class.getSimpleName() + ":myappstore"; public static final String BOOT_COMPLETED = "com.jiaoguanyi.appstore.intent.action.BOOT_COMPLETED"; + static { + getLockedState(); + } + + private static void getLockedState() { + Observable.create((ObservableOnSubscribe) emitter -> start = emitter::onNext) + .throttleLast(1, TimeUnit.HOURS) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("getLockedState", "onSubscribe: "); + } + + @Override + public void onNext(Long aLong) { + Log.e("getLockedState", "onNext: "); + if (MainService.mPresenter != null) { + MainService.mPresenter.getLockedState(); + Logutils.e("getLockedState", "mPresenter: " + "getLockedState"); + } else { + Logutils.e("getLockedState", "mPresenter is NULL"); + } + } + + @Override + public void onError(Throwable e) { + Log.e("getLockedState", "onError: "+e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getLockedState", "onComplete: "); + } + }); + } + + private interface Start { + void onstar(long time); + } + + private static Start start; + + @Override public void onReceive(Context context, Intent intent) { Logutils.e(TAG, "action:" + intent.getAction()); @@ -24,12 +77,7 @@ public class BootReceiver extends BroadcastReceiver { new BootManager(context).start(); break; case BOOT_COMPLETED: - if (MainService.mPresenter != null) { - MainService.mPresenter.getLockedState(); - Logutils.e(TAG, "mPresenter: " + "getLockedState"); - } else { - Logutils.e(TAG, "mPresenter is NULL"); - } + start.onstar(SystemClock.elapsedRealtime()); case Intent.ACTION_BATTERY_CHANGED: case Intent.ACTION_BATTERY_LOW: case Intent.ACTION_BATTERY_OKAY: diff --git a/app/src/main/java/com/mjsheng/myappstore/receiver/MyJPushReceiver.java b/app/src/main/java/com/mjsheng/myappstore/receiver/MyJPushReceiver.java index 1819f94..a32b07e 100644 --- a/app/src/main/java/com/mjsheng/myappstore/receiver/MyJPushReceiver.java +++ b/app/src/main/java/com/mjsheng/myappstore/receiver/MyJPushReceiver.java @@ -22,6 +22,7 @@ import com.alibaba.fastjson.JSONObject; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationClient; import com.amap.api.location.AMapLocationListener; +import com.arialyy.aria.core.Aria; import com.blankj.utilcode.util.PathUtils; import com.mjsheng.myappstore.R; import com.mjsheng.myappstore.utils.CacheUtils; @@ -135,6 +136,9 @@ public class MyJPushReceiver extends BroadcastReceiver { private final String EBAG_CODE = "35"; //更新白名单 private final String UPDATE_WHITELIST = "36"; + //更换批次不恢复出厂 + private final String UPDATE_BATCH = "37"; + private Context mContext; @@ -172,7 +176,7 @@ public class MyJPushReceiver extends BroadcastReceiver { //在这里根据 JPushInterface.EXTRA_EXTRA 的内容处理代码,比如打开新的Activity, 打开一个网页等.. } else if (JPushInterface.ACTION_CONNECTION_CHANGE.equals(intent.getAction())) { boolean connected = intent.getBooleanExtra(JPushInterface.EXTRA_CONNECTION_CHANGE, false); - Logutils.e(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected); + Logutils.i(TAG, "[MyReceiver]" + intent.getAction() + " connected state change to " + connected); } else { Logutils.e(TAG, "[MyReceiver] Unhandled intent - " + intent.getAction()); } @@ -286,8 +290,20 @@ public class MyJPushReceiver extends BroadcastReceiver { Utils.ariaDownload(mContext, url, packageObj); break; case SET_HOMEPAG_TAG: - ToastUtil.betaShow("收到管控:浏览器主页书签设置"); - setHomepagtag(extras); + Handler.getMain().postDelayed(new Runnable() { + @Override + public void run() { + try { + new CacheUtils().cleanApplicationUserData(mContext, "com.android.browser"); + } catch (Exception e) { + e.printStackTrace(); + Logutils.e(TAG, "setHomepagtag: " + e.getMessage()); + } + setHomepagtag(extras); + ToastUtil.betaShow("收到管控:浏览器主页书签设置"); + } + }, 2000); + break; case APP_WEBSITE: ToastUtil.betaShow("收到管控:APP内部网页管控"); @@ -414,7 +430,18 @@ public class MyJPushReceiver extends BroadcastReceiver { ToastUtil.betaShow("收到管控:更新白名单"); HTTPInterface.getAppLimit(mContext); break; + case UPDATE_BATCH: + ToastUtil.betaShow("收到管控:更换批次不恢复出厂设置"); + Aria.download(this).removeAllTask(true); + if (MainService.mPresenter != null) { + MainService.mPresenter.getLockedState(); + Logutils.e("getLockedState", "mPresenter: " + "getLockedState"); + } else { + Logutils.e("getLockedState", "mPresenter is NULL"); + } + break; } + } private void setLock_screen(int state, Context context, String name) { @@ -845,12 +872,7 @@ public class MyJPushReceiver extends BroadcastReceiver { private void setHomepagtag(String s) { //设置主页和标签 // HTTPInterface.setHomepagtag(mContext);//设置主页和标签 - try { - new CacheUtils().cleanApplicationUserData(mContext, "com.android.browser"); - } catch (Exception e) { - e.printStackTrace(); - Logutils.e(TAG, "setHomepagtag: " + e.getMessage()); - } + HTTPInterface.getHomePageBookmarks(mContext, null); // if (TextUtils.isEmpty(s)) { // Logutils.e(TAG, "setHomepagtag extras is null"); @@ -1033,8 +1055,15 @@ public class MyJPushReceiver extends BroadcastReceiver { // if (TextUtils.isEmpty(packageName)) { // return; // } - SPUtils.put(context, ForegroundAppUtil.TOPAPP_KEY, packageName); - ForegroundAppUtil.openTopApp(context); + if (TextUtils.isEmpty(packageName)) { + SPUtils.put(context, ForegroundAppUtil.TOPAPP_KEY, ""); + ForegroundAppUtil.setTopAppClass(context, ""); + } else { + SPUtils.put(context, ForegroundAppUtil.TOPAPP_KEY, packageName); + ForegroundAppUtil.setTopAppClass(context, packageName); + ForegroundAppUtil.openTopApp(context); + } + } private void setBootanimation(Context context, String extras) { @@ -1057,8 +1086,11 @@ public class MyJPushReceiver extends BroadcastReceiver { String default_launcher = jsonObject.getString("default_launcher"); if (TextUtils.isEmpty(default_launcher)) { JGYUtils.getInstance().setDefaultDesktop(""); + SPUtils.put(context, "default_launcher", ""); + } else { JGYUtils.getInstance().setDefaultDesktop(default_launcher); + SPUtils.put(context, "default_launcher", default_launcher); } } } diff --git a/app/src/main/java/com/mjsheng/myappstore/receiver/NewAppReceiver.java b/app/src/main/java/com/mjsheng/myappstore/receiver/NewAppReceiver.java index 75b9a7a..51fc47b 100644 --- a/app/src/main/java/com/mjsheng/myappstore/receiver/NewAppReceiver.java +++ b/app/src/main/java/com/mjsheng/myappstore/receiver/NewAppReceiver.java @@ -15,6 +15,7 @@ import com.mjsheng.myappstore.utils.ApkUtils; import com.mjsheng.myappstore.utils.CacheUtils; import com.mjsheng.myappstore.utils.JGYUtils; import com.mjsheng.myappstore.utils.Logutils; +import com.mjsheng.myappstore.utils.SPUtils; import com.mjsheng.myappstore.utils.SaveListUtils; import java.util.concurrent.TimeUnit; @@ -124,6 +125,10 @@ public class NewAppReceiver extends BroadcastReceiver { //HTTPInterface.getNetAndLaunchSetting(mContext); HTTPInterface.getAppLimit(mContext); // HTTPInterface.getAppinsideWeb(mContext, () -> Logutils.e(TAG, "onNext: setAPPinsideWebsite")); + String oldDesktop = (String) SPUtils.get(mContext, "default_launcher", ""); + if (s.equals(oldDesktop)){ + ApkUtils.openApp(mContext, s); + } } @Override diff --git a/app/src/main/java/com/mjsheng/myappstore/service/GuardService.java b/app/src/main/java/com/mjsheng/myappstore/service/GuardService.java index d332b2f..55d6641 100644 --- a/app/src/main/java/com/mjsheng/myappstore/service/GuardService.java +++ b/app/src/main/java/com/mjsheng/myappstore/service/GuardService.java @@ -81,7 +81,7 @@ public class GuardService extends Service { private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { - Logutils.e(TAG, "GuardService:建立链接"); + Logutils.w(TAG, "GuardService:建立链接"); boolean isServiceRunning = ServiceAliveUtils.isServiceAlive(GuardService.this, StepService.class.getName()); if (!isServiceRunning) { startService(new Intent(GuardService.this, StepService.class)); @@ -373,7 +373,7 @@ public class GuardService extends Service { // 最大电量 int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0); int elec = (level * 100) / scale; - Logutils.e(TAG, "electricity:=" + elec + "%"); +// Logutils.e(TAG, "electricity:=" + elec + "%"); if (elec == 50) { start.onstar(SystemClock.elapsedRealtime()); } diff --git a/app/src/main/java/com/mjsheng/myappstore/service/MainService.java b/app/src/main/java/com/mjsheng/myappstore/service/MainService.java index 95cc297..e9d1fec 100644 --- a/app/src/main/java/com/mjsheng/myappstore/service/MainService.java +++ b/app/src/main/java/com/mjsheng/myappstore/service/MainService.java @@ -41,6 +41,11 @@ import com.mjsheng.myappstore.utils.SaveListUtils; import com.mjsheng.myappstore.utils.SysSettingUtils; import com.mjsheng.myappstore.utils.TimeUtils; import com.mjsheng.myappstore.utils.ToastUtil; +import com.trello.rxlifecycle2.LifecycleProvider; +import com.trello.rxlifecycle2.LifecycleTransformer; +import com.trello.rxlifecycle2.RxLifecycle; +import com.trello.rxlifecycle2.android.ActivityEvent; +import com.trello.rxlifecycle2.android.RxLifecycleAndroid; import java.util.Arrays; import java.util.HashSet; @@ -52,8 +57,9 @@ import io.reactivex.ObservableEmitter; import io.reactivex.ObservableOnSubscribe; import io.reactivex.Observer; import io.reactivex.disposables.Disposable; +import io.reactivex.subjects.BehaviorSubject; -public class MainService extends Service implements MainContact.MainView, NetworkUtils.OnNetworkStatusChangedListener { +public class MainService extends Service implements MainContact.MainView, NetworkUtils.OnNetworkStatusChangedListener, LifecycleProvider { @SuppressLint("StaticFieldLeak") public static MainPresenter mPresenter; private static final String TAG = MainService.class.getSimpleName(); @@ -71,13 +77,24 @@ public class MainService extends Service implements MainContact.MainView, Networ runningTime = SystemClock.elapsedRealtime(); //直接获取数据 ToastUtil.betaShow("网络已连接"); - mPresenter.getLockedState(); + start.onstar(SystemClock.elapsedRealtime()); + } + + private final BehaviorSubject lifecycleSubject = BehaviorSubject.create(); + + @Override + public Observable lifecycle() { + return lifecycleSubject.hide(); } @Override - public Resources getResources() { - //1920是设计稿的宽(单位p:x) - return AdaptScreenUtils.adaptWidth(super.getResources(), 1920); + public LifecycleTransformer bindUntilEvent(ActivityEvent event) { + return RxLifecycle.bindUntilEvent(lifecycleSubject, event); + } + + @Override + public LifecycleTransformer bindToLifecycle() { + return RxLifecycleAndroid.bindActivity(lifecycleSubject); } private interface Start { @@ -129,8 +146,11 @@ public class MainService extends Service implements MainContact.MainView, Networ @Override public void onCreate() { + lifecycleSubject.onNext(ActivityEvent.CREATE); mPresenter = new MainPresenter(this); mPresenter.attachView(this); + mPresenter.setProvider(this); + lifecycleSubject.onNext(ActivityEvent.CREATE); if ((int) SPUtils.get(this, "first_connect", 0) == 0) { // TODO: 2021/5/26 待底层修改,临时解决办法 Logutils.e(TAG, "onCreate: " + "Disable All Settings"); @@ -159,6 +179,7 @@ public class MainService extends Service implements MainContact.MainView, Networ super.onDestroy(); unRegisterReceivers(); NetworkUtils.unregisterNetworkStatusChangedListener(this); + lifecycleSubject.onNext(ActivityEvent.DESTROY); mPresenter.detachView(); } @@ -399,6 +420,7 @@ public class MainService extends Service implements MainContact.MainView, Networ @SuppressLint("NewApi") @Override public void onReceive(Context context, Intent intent) { + Log.e(TAG, "onReceive: " + intent.getAction()); if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) { Logutils.e("TimeChangedReceiver", "onReceive:" + "data changed"); } else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { @@ -728,11 +750,15 @@ public class MainService extends Service implements MainContact.MainView, Networ showFloatingWindow(tips); } screenlocked = true; + SPUtils.put(MainService.this, "is_screen_lock", true); + SPUtils.put(MainService.this, "screen_tips", tips); } else { if (!timelocked) { hideFloatingWindow(); } screenlocked = false; + SPUtils.put(MainService.this, "is_screen_lock", false); + SPUtils.put(MainService.this, "screen_tips", ""); } } } diff --git a/app/src/main/java/com/mjsheng/myappstore/service/StepService.java b/app/src/main/java/com/mjsheng/myappstore/service/StepService.java index e87fd88..f74d76b 100644 --- a/app/src/main/java/com/mjsheng/myappstore/service/StepService.java +++ b/app/src/main/java/com/mjsheng/myappstore/service/StepService.java @@ -8,16 +8,23 @@ package com.mjsheng.myappstore.service; */ import android.app.Service; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.ServiceConnection; import android.os.Binder; import android.os.Handler; import android.os.IBinder; +import android.os.PowerManager; +import android.text.TextUtils; +import android.util.Log; import androidx.annotation.Nullable; +import com.alibaba.fastjson.JSONObject; +import com.blankj.utilcode.util.NetworkUtils; import com.mjsheng.myappstore.KeepAliveConnection; import com.mjsheng.myappstore.manager.NetInterfaceManager; import com.mjsheng.myappstore.utils.Logutils; @@ -34,12 +41,22 @@ import java.net.URI; * @author LiGuangMin * @time Created by 2018/8/17 11:26 */ -public class StepService extends Service { +public class StepService extends Service implements NetworkUtils.OnNetworkStatusChangedListener { private final static String TAG = StepService.class.getSimpleName(); public JWebSocketClient client; private JWebSocketClientBinder mBinder = new JWebSocketClientBinder(); + @Override + public void onDisconnected() { + + } + + @Override + public void onConnected(NetworkUtils.NetworkType networkType) { + connect(); + } + //用于Activity和service通讯 public class JWebSocketClientBinder extends Binder { public StepService getService() { @@ -50,7 +67,7 @@ public class StepService extends Service { private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { - Logutils.e(TAG, "StepService:建立链接"); + Logutils.w(TAG, "StepService:建立链接"); boolean isServiceRunning = ServiceAliveUtils.isServiceAlive(StepService.this, GuardService.class.getName()); if (!isServiceRunning) { Intent i = new Intent(StepService.this, GuardService.class); @@ -74,34 +91,78 @@ public class StepService extends Service { }; } + @Override + public void onCreate() { + super.onCreate(); + NetworkUtils.registerNetworkStatusChangedListener(this); + registerScreenLockReceiver(); + //初始化websocket + initSocketClient(); + mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测 + } + @Override public int onStartCommand(Intent intent, int flags, int startId) { // startForeground(1, new Notification()); // 绑定建立链接 -// try { -// final String filePath = intent.getStringExtra("filePath"); -// final String packageName = intent.getStringExtra("packageName"); -// Logutils.e("fht", filePath); -// Logutils.e("fht", packageName); -// FileData fileData = new FileData(filePath, packageName); -// MyApplication.getInstance().addFileData(fileData); -// -// } catch (Exception e) { -// Logutils.e("fht", e.getMessage()); -// } - - //初始化websocket - Logutils.e(TAG, "onStartCommand: "); -// initSocketClient(); -// mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测 + Logutils.e("JWebSocketClientService", "onStartCommand: "); bindService(new Intent(this, GuardService.class), mServiceConnection, Context.BIND_IMPORTANT); return START_STICKY; } + private ScreenLockReceiver screenLockReceiver; + + private void registerScreenLockReceiver() { + if (null == screenLockReceiver) { + screenLockReceiver = new ScreenLockReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_BOOT_COMPLETED); + filter.addAction(Intent.ACTION_USER_PRESENT); + filter.addAction(Intent.ACTION_SHUTDOWN); + filter.addAction(Intent.ACTION_FACTORY_RESET); + filter.addAction(Intent.ACTION_MASTER_CLEAR); + registerReceiver(screenLockReceiver, filter); + } + + private class ScreenLockReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.e(TAG, "onReceive:" + action); + if (TextUtils.isEmpty(action)) { + Log.e(TAG, "onReceive: is NULL"); + return; + } + switch (action) { + case Intent.ACTION_BOOT_COMPLETED: + case Intent.ACTION_USER_PRESENT: + case Intent.ACTION_SCREEN_ON: + sendMsg(1); + break; + case Intent.ACTION_SCREEN_OFF: + case Intent.ACTION_SHUTDOWN: + case Intent.ACTION_FACTORY_RESET: + case Intent.ACTION_MASTER_CLEAR: + sendMsg(2); + break; + default: + break; + } + } + } + @Override public void onDestroy() { super.onDestroy(); + NetworkUtils.unregisterNetworkStatusChangedListener(this); closeConnect(); + if (screenLockReceiver != null) { + unregisterReceiver(screenLockReceiver); + } } /** @@ -114,13 +175,14 @@ public class StepService extends Service { client = new JWebSocketClient(uri) { @Override public void onMessage(String message) { - Logutils.i("JWebSocketClientService", "收到服务器发来的消息:" + message + "?"); + Logutils.i("JWebSocketClientService", "收到服务器发来的消息:" + message); } @Override public void onOpen(ServerHandshake handshakedata) { super.onOpen(handshakedata); Logutils.i("JWebSocketClientService", "websocket连接成功"); + sendMsg(1); } @Override @@ -129,17 +191,17 @@ public class StepService extends Service { Logutils.i("JWebSocketClientService", "websocket连接关闭"); // client.close(); // initSocketClient(); -// mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测 + mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测 } @Override public void onError(Exception ex) { super.onError(ex); - Logutils.i("JWebSocketClientService", "websocket连接错误"); + Logutils.i("JWebSocketClientService", "websocket连接错误:" + ex.getMessage()); // client.close(); // initSocketClient(); -// mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测 + mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测 } }; @@ -168,13 +230,32 @@ public class StepService extends Service { /** * 发送消息 - * - * @param msg */ - public void sendMsg(String msg) { + public void sendMsg() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("sn", Utils.getSerial()); + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + if (!pm.isScreenOn()) { + jsonObject.put("online", 2); + //熄屏状态 + } else { + jsonObject.put("online", 1); + } if (null != client) { - Logutils.i("JWebSocketClientService", "发送的消息:" + msg); - client.send(msg); + Logutils.i("JWebSocketClientService", "发送的消息:" + jsonObject.toJSONString()); + client.send(jsonObject.toJSONString()); + } + } + + public void sendMsg(int state) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("sn", Utils.getSerial()); + jsonObject.put("online", state); + if (null != client) { + Logutils.i("JWebSocketClientService", "发送的消息:" + jsonObject.toJSONString()); + client.send(jsonObject.toJSONString()); + } else { + Logutils.i("JWebSocketClientService", "未连接"); } } @@ -194,7 +275,7 @@ public class StepService extends Service { } // -------------------------------------websocket心跳检测------------------------------------------------ - private static final long HEART_BEAT_RATE = 50 * 1000;//每隔50秒进行一次对长连接的心跳检测 + private static final long HEART_BEAT_RATE = 30 * 1000;//每隔50秒进行一次对长连接的心跳检测 private Handler mHandler = new Handler(); private Runnable heartBeatRunnable = new Runnable() { @Override @@ -203,10 +284,10 @@ public class StepService extends Service { if (client != null) { if (client.isOpen()) { Logutils.i("JWebSocketClientService", "websocket已连接"); - sendMsg(Utils.getSerial()); + sendMsg(); } else if (client.isClosed()) { Logutils.i("JWebSocketClientService", "websocket重连中"); -// reconnectWs(); + reconnectWs(); } } else { //如果client已为空,重新初始化连接 @@ -214,7 +295,7 @@ public class StepService extends Service { initSocketClient(); } //每隔一定的时间,对长连接进行一次心跳检测 -// mHandler.postDelayed(this, HEART_BEAT_RATE); + mHandler.postDelayed(this, HEART_BEAT_RATE); } }; @@ -229,7 +310,7 @@ public class StepService extends Service { try { Logutils.i("JWebSocketClientService", "开启重连"); client.reconnectBlocking(); - } catch (InterruptedException e) { + } catch (Exception e) { e.printStackTrace(); } } diff --git a/app/src/main/java/com/mjsheng/myappstore/utils/ApkUtils.java b/app/src/main/java/com/mjsheng/myappstore/utils/ApkUtils.java index 5f6a278..ef34d29 100644 --- a/app/src/main/java/com/mjsheng/myappstore/utils/ApkUtils.java +++ b/app/src/main/java/com/mjsheng/myappstore/utils/ApkUtils.java @@ -1121,7 +1121,7 @@ public class ApkUtils { installedListBuilder.append(","); } installedListBuilder.append(s); - Logutils.e("addShortcut", "packages: " + s); + Logutils.i("addShortcut", "packages: " + s); } String installedList = installedListBuilder.toString(); boolean qch_force_app = Settings.System.putString(context.getContentResolver(), "qch_launcher_icon_app", installedList); diff --git a/app/src/main/java/com/mjsheng/myappstore/utils/ForegroundAppUtil.java b/app/src/main/java/com/mjsheng/myappstore/utils/ForegroundAppUtil.java index 3c65ab6..99b9a70 100644 --- a/app/src/main/java/com/mjsheng/myappstore/utils/ForegroundAppUtil.java +++ b/app/src/main/java/com/mjsheng/myappstore/utils/ForegroundAppUtil.java @@ -8,6 +8,7 @@ import android.content.Intent; import android.os.Build; import android.provider.Settings; import android.text.TextUtils; +import android.util.Log; import java.util.List; @@ -18,6 +19,7 @@ public class ForegroundAppUtil { private static final long START_TIME = END_TIME - TIME_INTERVAL; public static final String TOPAPP_KEY = "TOP_ALWAYS_SHOW_APP_NAME"; + private static String TAG = ForegroundAppUtil.class.getSimpleName(); public static String getForegroundPackageName(Context context) { //系统应用可以直接获取 @@ -43,6 +45,26 @@ public class ForegroundAppUtil { } } + public static void setTopAppClass(Context context, String pkg) { + if (TextUtils.isEmpty(pkg)) { + boolean always_top_packagename = Settings.System.putString(context.getContentResolver(), "always_top_packagename", "Invalid"); + boolean always_top_classname = Settings.System.putString(context.getContentResolver(), "always_top_classname", "Invalid"); + Log.e(TAG, "setTopAppClass: always_top_packagename = " + always_top_packagename); + Log.e(TAG, "setTopAppClass: always_top_classname = " + always_top_classname); + } else { + String ClassName = JGYUtils.getInstance().getStartClassName(pkg); + setTopAppClass(context, pkg, ClassName); + } + } + + public static void setTopAppClass(Context context, String pkg, String ClassName) { + boolean always_top_packagename = Settings.System.putString(context.getContentResolver(), "always_top_packagename", pkg); + boolean always_top_classname = Settings.System.putString(context.getContentResolver(), "always_top_classname", ClassName); + Log.e(TAG, "setTopAppClass: always_top_packagename = " + always_top_packagename); + Log.e(TAG, "setTopAppClass: always_top_classname = " + always_top_classname); + ApkUtils.openApp(context, pkg); + } + /** * 获取栈顶的应用包名 diff --git a/app/src/main/java/com/mjsheng/myappstore/utils/JGYUtils.java b/app/src/main/java/com/mjsheng/myappstore/utils/JGYUtils.java index c75fea1..b94f37c 100644 --- a/app/src/main/java/com/mjsheng/myappstore/utils/JGYUtils.java +++ b/app/src/main/java/com/mjsheng/myappstore/utils/JGYUtils.java @@ -81,10 +81,13 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; +import cn.jpush.android.api.JPushInterface; + import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE; @@ -100,6 +103,9 @@ public class JGYUtils { public static String ZhanruiTag = "展锐"; public static String Other = "其他"; + static { + System.loadLibrary("jgy"); + } private JGYUtils(Context context) { this.mContext = context; @@ -119,6 +125,8 @@ public class JGYUtils { return sInstance; } + public static native String getAuthorization(); + public static boolean isOfficialVersion() { String channelValue = JGYUtils.getInstance().getStringMetaData(); return "official".equals(channelValue); @@ -1754,19 +1762,28 @@ public class JGYUtils { } } + private String Launcher3 = "com.android.launcher3"; + private String Launcher3Class = "com.android.launcher3.Launcher"; + + //设置默认桌面 public void setDefaultDesktop(String pkg) { if (TextUtils.isEmpty(pkg)) { - setDefaultDesktop("", ""); + openLauncher3(); } else { String className = getStartClassName(pkg); if (TextUtils.isEmpty(className)) { - setDefaultDesktop("", ""); + openLauncher3(); } else { setDefaultDesktop(pkg, className); } } } + private void openLauncher3() { + setDefaultDesktop(Launcher3, Launcher3Class); + ApkUtils.openApp(mContext, Launcher3); + } + public String getStartClassName(String pkg) { PackageInfo packageInfo = null; try { @@ -1803,11 +1820,29 @@ public class JGYUtils { } public void setDefaultDesktop(String pkg, String className) { + String oldDesktop = (String) SPUtils.get(mContext, "default_launcher", ""); + if (Objects.equals(oldDesktop, pkg)) { + Log.e(TAG, "setDefaultDesktop: " + "数据一致"); + return; + } Intent intent = new Intent("setDefaultLauncher"); intent.putExtra("package", pkg); intent.putExtra("className", className); intent.setPackage("com.android.settings"); mContext.sendBroadcast(intent); + ApkUtils.openApp(mContext, pkg); Log.e(TAG, "setDefaultDesktop: " + pkg + ":" + className); } + + public String getMacJson() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("sn", Utils.getSerial()); + jsonObject.addProperty("mac", Utils.getAndroid10MAC(mContext)); + jsonObject.addProperty("jpush_id", JPushInterface.getRegistrationID(mContext)); + jsonObject.addProperty("devices_version", Utils.getCustomVersion()); + jsonObject.addProperty("appstore_version", BuildConfig.VERSION_NAME); + jsonObject.addProperty("store_version", Utils.getAPPVersionName(mContext)); + jsonObject.addProperty("local_mac", Utils.getAndroid7MAC()); + return jsonObject.toString(); + } } diff --git a/app/src/main/java/com/mjsheng/myappstore/utils/ServiceAliveUtils.java b/app/src/main/java/com/mjsheng/myappstore/utils/ServiceAliveUtils.java index b84bd55..8207853 100644 --- a/app/src/main/java/com/mjsheng/myappstore/utils/ServiceAliveUtils.java +++ b/app/src/main/java/com/mjsheng/myappstore/utils/ServiceAliveUtils.java @@ -16,7 +16,7 @@ public class ServiceAliveUtils { isServiceRunning = true; } } - Logutils.e("ServiceAliveUtils", mContext.getClass().getName() + "isServiceAlice: " + isServiceRunning); + Logutils.i("ServiceAliveUtils", mContext.getClass().getName() + "isServiceAlice: " + isServiceRunning); return isServiceRunning; } @@ -32,7 +32,7 @@ public class ServiceAliveUtils { isServiceRunning = true; } } - Logutils.e("ServiceAliveUtils", serviceName + " :isServiceAlice: " + isServiceRunning); + Logutils.i("ServiceAliveUtils", serviceName + " :isServiceAlice: " + isServiceRunning); return isServiceRunning; } } diff --git a/app/src/main/java/com/mjsheng/myappstore/utils/SysSettingUtils.java b/app/src/main/java/com/mjsheng/myappstore/utils/SysSettingUtils.java index 91001cd..397521e 100644 --- a/app/src/main/java/com/mjsheng/myappstore/utils/SysSettingUtils.java +++ b/app/src/main/java/com/mjsheng/myappstore/utils/SysSettingUtils.java @@ -135,7 +135,6 @@ public class SysSettingUtils { } private static void setPhoneList(Context context, JSONObject jsonObject) { - Logutils.e(TAG, "setPhoneList: " + jsonObject.toJSONString()); try { //设置电话功能,电话白名单 //电话通话开关 @@ -471,8 +470,7 @@ public class SysSettingUtils { /** * @param context - * @param jsonObject - * tfmedia开关 + * @param jsonObject tfmedia开关 */ private static void setTF(Context context, JSONObject jsonObject) { try { @@ -590,6 +588,11 @@ public class SysSettingUtils { ApkUtils.hideSystemSettingAPP(context, "com.android.documentsui"); } Logutils.e(TAG, "qch_app_filemanager" + filemanager); + //浏览器 + int browser = changeNum(jsonObject.getInteger("setting_browser")); + Settings.System.putInt(context.getContentResolver(), "qch_app_browser", browser); + Logutils.e(TAG, "qch_app_browser" + browser); + } catch (Exception e) { Logutils.e(TAG, "setIcon: " + e.getMessage()); } diff --git a/app/src/main/java/com/mjsheng/myappstore/utils/ToastUtil.java b/app/src/main/java/com/mjsheng/myappstore/utils/ToastUtil.java index 84bff17..bf1b4e1 100644 --- a/app/src/main/java/com/mjsheng/myappstore/utils/ToastUtil.java +++ b/app/src/main/java/com/mjsheng/myappstore/utils/ToastUtil.java @@ -2,12 +2,18 @@ package com.mjsheng.myappstore.utils; import android.annotation.SuppressLint; import android.content.Context; +import android.graphics.Color; import android.os.Build; import android.os.Handler; import android.os.Looper; +import android.util.Log; +import android.view.Gravity; import android.widget.Toast; +import com.blankj.utilcode.util.ColorUtils; +import com.blankj.utilcode.util.ToastUtils; import com.mjsheng.myappstore.BuildConfig; +import com.mjsheng.myappstore.R; /** @@ -15,12 +21,14 @@ import com.mjsheng.myappstore.BuildConfig; */ public class ToastUtil { + private static final String TAG = ToastUtil.class.getSimpleName(); @SuppressLint("StaticFieldLeak") private static Context mContext; private static Handler mainHandler = new Handler(Looper.getMainLooper()); private static Toast debugToast; private static Toast toast; + @SuppressLint("ShowToast") public static void init(Context context) { mContext = context; @@ -33,34 +41,25 @@ public class ToastUtil { private static long time2 = 0L; public static void show(final String msg) { - mainHandler.post(() -> { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - time2 = System.currentTimeMillis(); - if ((time2 - time1) > 3500) { - showToast(mContext, msg, Toast.LENGTH_SHORT); - time1 = time2; - } - } else { - if (toast != null) { - toast.setText(msg); - toast.show(); - } - } - }); + ToastUtils.make() +// .setBgColor(ColorUtils.getColor(R.color.toast_color)) + .setTextColor(Color.DKGRAY) +// .setGravity(Gravity.CENTER, 0, 0) + .setNotUseSystemToast() + .show(msg); } public static void betaShow(final String msg) { if (JGYUtils.isBetaVersion() || BuildConfig.DEBUG) { - mainHandler.post(() -> { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - showToast(mContext, msg, Toast.LENGTH_SHORT); - } else { - if (debugToast != null) { - debugToast.setText(msg); - debugToast.show(); - } - } - }); + ToastUtils.make() +// .setBgColor(ColorUtils.getColor(R.color.toast_color)) + .setTextColor(Color.RED) +// .setGravity(Gravity.CENTER, 0, 0) + .setNotUseSystemToast() + .setDurationIsLong(true) + .show(msg); + } else { + Log.e(TAG, "debugShow: " + msg); } } diff --git a/app/src/main/java/com/mjsheng/myappstore/utils/URLUtils.java b/app/src/main/java/com/mjsheng/myappstore/utils/URLUtils.java index 690e00c..bd3e943 100644 --- a/app/src/main/java/com/mjsheng/myappstore/utils/URLUtils.java +++ b/app/src/main/java/com/mjsheng/myappstore/utils/URLUtils.java @@ -11,6 +11,8 @@ import java.io.IOException; import java.net.URI; import java.util.Arrays; import java.util.HashSet; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -27,20 +29,25 @@ import okhttp3.Request; import okhttp3.Response; public class URLUtils { - private static String TAG = URLUtils.class.getSimpleName(); + private static final String TAG = URLUtils.class.getSimpleName(); private Context mContext; private HashSet baseURLList = new HashSet<>(); + private HashSet nohttpURLList = new HashSet<>(); + + private long time1; + private long time2; public URLUtils(Context context) { this.mContext = context; } public void setBrowserWhiteList() { + time1 = System.currentTimeMillis(); //会写入两次,第一次是不带前缀的,第二次会把实际的地址写入进去 String oldwhiteList = Settings.System.getString(mContext.getContentResolver(), "DeselectBrowserArray"); if (TextUtils.isEmpty(oldwhiteList)) { Logutils.e(TAG, "getBrowserWhiteList: " + "oldwhiteList is empty"); - Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray","Invalid"); + Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", "Invalid"); } else { Logutils.e(TAG, "getBrowserWhiteList: " + "oldwhiteList is : " + oldwhiteList); HashSet URLList = new HashSet<>(Arrays.asList(oldwhiteList.trim().split(","))); @@ -66,8 +73,11 @@ public class URLUtils { // } // }else { // } + nohttpURLList.add("m." + getDomain(url)); +// nohttpURLList.add(getDomain(url)); if (!url.startsWith("http")) { + nohttpURLList.add(url); String httpsUrl = "https://" + url; String httpUrl = "http://" + url; emitter.onNext(getOkHttpURL(httpsUrl)); @@ -77,14 +87,25 @@ public class URLUtils { Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(httpsUrl); while (m.find()) { + Log.e(TAG, "matcher1: " + m.group()); baseURLList.add(m.group()); } - }else { + } else { + if (url.endsWith("/")) { + baseURLList.add(url.substring(0, url.length() - 1)); + } + //临时 + if (baseURLList.size() != 0) { + Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", String.join(",", baseURLList)); + } + Log.e(TAG, "subscribe: baseURLList: " + baseURLList); + Log.e(TAG, "subscribe: DeselectBrowserArray: " + Settings.System.getString(mContext.getContentResolver(), "DeselectBrowserArray")); String pattern = "[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\\.?"; Pattern r = Pattern.compile(pattern); Matcher m = r.matcher(url); if (m.find()) { - Log.e(TAG, "matcher: " + m.group()); + nohttpURLList.add(m.group()); + Log.e(TAG, "matcher2: " + m.group()); String httpsUrl = "https://" + m.group(); String httpUrl = "http://" + m.group(); emitter.onNext(getOkHttpURL(httpsUrl)); @@ -161,18 +182,14 @@ public class URLUtils { @Override public void onComplete() { - Logutils.e(TAG, "onComplete: " + baseURLList); - StringBuilder stringBuilder = new StringBuilder(); - for (String s : baseURLList) { - if (stringBuilder.length() > 0) { - stringBuilder.append(","); - } - stringBuilder.append(s); - } - String DeselectBrowserArray = stringBuilder.toString(); + Logutils.i(TAG, "onComplete: " + baseURLList); + baseURLList.addAll(nohttpURLList); + baseURLList.removeIf(TextUtils::isEmpty); + String DeselectBrowserArray = String.join(",", baseURLList); Logutils.e(TAG, "onComplete: " + "white list: " + DeselectBrowserArray); boolean write = Settings.System.putString(mContext.getContentResolver(), "DeselectBrowserArray", DeselectBrowserArray); - Logutils.e(TAG, "onComplete: " + "write :" + write); + Logutils.i(TAG, "onComplete: " + "write :" + write + " time = " + (System.currentTimeMillis() - time1)); + } }); } @@ -184,7 +201,7 @@ public class URLUtils { String qch_webblack_url = Settings.System.getString(mContext.getContentResolver(), "qch_webblack_url"); Logutils.e(TAG, "setBrowserBlackList: qch_webblack_url = " + qch_webblack_url); if (TextUtils.isEmpty(qch_webblack_url)) { - Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url","Invalid"); + Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url", "Invalid"); return; } HashSet URLList = new HashSet<>(Arrays.asList(qch_webblack_url.trim().split(","))); @@ -204,15 +221,9 @@ public class URLUtils { blackList.add("https://" + url); } } - StringBuilder stringBuilder = new StringBuilder(); - for (String url : blackList) { - if (stringBuilder.length() > 0) { - stringBuilder.append(","); - } - stringBuilder.append(url); - } + Logutils.e(TAG, "setBrowserBlackList: blackList: " + blackList); - boolean write = Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url", stringBuilder.toString()); + boolean write = Settings.System.putString(mContext.getContentResolver(), "qch_webblack_url", String.join(",", blackList)); Logutils.e(TAG, "setBrowserBlackList: write: " + write); } @@ -220,7 +231,12 @@ public class URLUtils { if (!URL.startsWith("http")) { return ""; } - OkHttpClient okHttpClient = new OkHttpClient(); + + OkHttpClient okHttpClient = new OkHttpClient.Builder() + .connectTimeout(1, TimeUnit.SECONDS) + .writeTimeout(1, TimeUnit.SECONDS) + .readTimeout(1, TimeUnit.SECONDS) + .build(); final Request request = new Request.Builder() .url(URL) .removeHeader("User-Agent") @@ -249,7 +265,7 @@ public class URLUtils { } } catch (IOException e) { e.printStackTrace(); - Logutils.e(TAG, "getOkHttpURL: " + e.getMessage() + " : " + URL); + Logutils.w(TAG, "getOkHttpURL: " + e.getMessage() + " : " + URL); return ""; } } @@ -259,10 +275,31 @@ public class URLUtils { //https://blog.csdn.net/liehuo123/article/details/81509486?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-1&spm=1001.2101.3001.4242 //https://www.cnblogs.com/breakdown/archive/2012/09/17/2689101.html + + /** + * 获取主机名 + * + * @param url 网址 + * @return + */ + //https://blog.csdn.net/smallnetvisitor/article/details/84516347 + public String getDomain(String url) { + String regexStr = "(?<=//|)((\\w)+(\\.cn|\\.com.cn|\\.org.cn|\\.com|\\.net|\\.org|\\.cc|\\.biz|\\.uk|\\.info|\\.in|\\.eu))+"; + Pattern p = Pattern.compile(regexStr); + Matcher m = p.matcher(url); + String domainVal = ""; + if (m.find()) { + domainVal = m.group(); + } + return domainVal; + } + + /** * Gets ip. * 通过url获取到域名 - *https://www.cnblogs.com/shizhijie/p/8277092.html + * https://www.cnblogs.com/shizhijie/p/8277092.html + * * @param url the url * @return the ip */ diff --git a/app/src/main/jni/jgy.cpp b/app/src/main/jni/jgy.cpp new file mode 100644 index 0000000..d04fa5d --- /dev/null +++ b/app/src/main/jni/jgy.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +// 日志打印 +#include + +#define LOG_TAG "TAG_LOG" +#define LOGI(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +extern "C" +JNIEXPORT jstring JNICALL +Java_com_mjsheng_myappstore_utils_JGYUtils_getAuthorization(JNIEnv *env, jobject thiz) { + // TODO: implement getAuthorization() + std::string hello; + + // 1. 获取 SDK 版本号 , 存储于 C 字符串 sdk_verison_str 中 + char sdk[128] = "0"; + + // 获取版本号方法 + __system_property_get("ro.build.version.sdk", sdk); + //将版本号转为 int 值 + int sdk_verison = atoi(sdk); + jclass cls = env->FindClass("com/mjsheng/myappstore/BuildConfig"); + jfieldID jfieldId_text = env->GetStaticFieldID(cls, "FLAVOR", "Ljava/lang/String;"); + jstring text = (jstring) env->GetStaticObjectField(cls, jfieldId_text); + const char *char_name = env->GetStringUTFChars(text, JNI_FALSE); + std::string s = char_name; + if (s.compare("newly") == 0) { + LOGI("newly"); + hello = "Basic MjBmNzBiYmViNzhiYWQyM2VkZGQwOGQwOjU0ZWRjYzczYzU4NWRkOGIyMjJlZjY4MA=="; + } else if (s.compare("MTKnewly") == 0) { + LOGI("MTKnewly"); + hello = "Basic MjBmNzBiYmViNzhiYWQyM2VkZGQwOGQwOjU0ZWRjYzczYzU4NWRkOGIyMjJlZjY4MA=="; + } else if (s.compare("beta") == 0) { + LOGI("beta"); + hello = "Basic NTJkODE2NDM2NjViYjJjYWRhY2YwZTllOmI5N2RkZTYwNjdhY2ZhMjY5MDlhZjQ1Nw=="; + } +// LOGI("%s", char_name); +// LOGI("dasdasd"); +// LOGI("%s", hello.c_str()); + return env->NewStringUTF(hello.c_str()); +} + + diff --git a/app/src/main/res/drawable-hdpi/main_device.png b/app/src/main/res/drawable-hdpi/main_device.png new file mode 100644 index 0000000000000000000000000000000000000000..ca364c98a49c4f49bc7b6dba6b910fbb32ae648d GIT binary patch literal 2583 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/main_nickname.png b/app/src/main/res/drawable-hdpi/main_nickname.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3e046195fe443a09a15da1aa7ba70b7587f82f GIT binary patch literal 3525 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 - @@ -140,203 +139,254 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView" /> - + + + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/imageView2" + app:layout_constraintTop_toTopOf="parent" + /> - + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/textView2" /> + - + + + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/imageView3" + app:layout_constraintTop_toTopOf="parent" /> - + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + - + + + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/imageView4" + app:layout_constraintTop_toTopOf="parent" /> - + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + - + + + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/imageView5" + app:layout_constraintTop_toTopOf="parent" /> - + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + - + + + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/imageView6" + app:layout_constraintTop_toTopOf="parent" /> - + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + - + + + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/imageView7" + app:layout_constraintTop_toTopOf="parent" /> - + android:textSize="@dimen/sp_12" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> +