diff --git a/app/build.gradle b/app/build.gradle index 36a5121..b53923d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' def appName() { - return "XwadOS" + return "XwadOSHonor" } def releaseTime() { @@ -17,8 +17,8 @@ android { minSdkVersion 23 targetSdkVersion 29 - versionCode 1 - versionName "1.0.0" + versionCode 7 + versionName "1.0.6" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -83,6 +83,79 @@ android { } +// def cerFile = file("E:\\Xuewang365\\HonorCer\\HONOR.CER") + + applicationVariants.all { variant -> + def variantName = variant.name.capitalize() + // 建议使用 packageApplication 任务,它更明确指向 APK 生成 + def packageTask = tasks.findByName("package${variantName}") + + if (packageTask) { + packageTask.doLast { + // 1. 配置路径优化:尽量使用 project 属性,避免写死 E:\ 盘符 + def cerFile = file("E:\\Xuewang365\\HonorCer\\HONOR.CER") + if (!cerFile.exists()) { + println "⚠️ 未找到证书文件: ${cerFile.path}" + return + } + + def sdkDir = android.sdkDirectory.path +// def buildToolsVersion = android.buildToolsVersion // 建议动态获取,除非有特定版本要求 + def buildToolsVersion = "33.0.0" + def buildToolsPath = "${sdkDir}/build-tools/${buildToolsVersion}" + def aaptPath = "${buildToolsPath}/aapt${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.exe' : ''}" + def apksignerPath = "${buildToolsPath}/apksigner${org.gradle.internal.os.OperatingSystem.current().isWindows() ? '.bat' : ''}" + + // 2. 关键优化:精准定位当前 Variant 的输出文件 + // 使用 variant.outputs 获取当前构建生成的特定文件 + variant.outputs.all { output -> + def apkFile = output.outputFile + println "APK地址:${apkFile.absolutePath}" + + if (apkFile != null && apkFile.name.endsWith(".apk")) { + println "🛠️ 开始对当前 APK 注入: ${apkFile.name}" + + // 3. 准备 META-INF 临时结构 + def tempBaseDir = new File(project.buildDir, "intermediates/honor_cer_temp/${variant.name}") + def metaInfDir = new File(tempBaseDir, "META-INF") + metaInfDir.deleteDir() // 清理旧数据 + metaInfDir.mkdirs() + + def targetFile = new File(metaInfDir, cerFile.name) + ant.copy(file: cerFile, tofile: targetFile) + + // 4. 调用 aapt 注入 + exec { + workingDir tempBaseDir + commandLine aaptPath, "add", apkFile.absolutePath, "META-INF/${cerFile.name}" + } + + // 5. 重新签名 (Apksigner) + def signingConfig = variant.signingConfig + if (signingConfig != null && signingConfig.storeFile.exists()) { + exec { + commandLine apksignerPath, "sign", + "--ks", signingConfig.storeFile.absolutePath, + "--ks-pass", "pass:${signingConfig.storePassword}", + "--ks-key-alias", signingConfig.keyAlias, + "--key-pass", "pass:${signingConfig.keyPassword}", + "--v2-signing-enabled", "true", + "--v3-signing-enabled", "true", + apkFile.path + } + println "✅ [${variant.name}] 注入并修复签名成功!" + } else { + println "❌ [${variant.name}] 签名失败:SigningConfig 配置无效" + } + + // 清理临时目录 + tempBaseDir.deleteDir() + } + } + } + } + } + buildTypes { debug { @@ -90,7 +163,7 @@ android { minifyEnabled false //Zipalign优化 zipAlignEnabled true - buildConfigField "String", "platform", '"tuixin"' + buildConfigField "String", "platform", '"HONOR"' signingConfig signingConfigs.tuixin applicationVariants.all { variant -> variant.outputs.each { output -> @@ -111,7 +184,7 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //签名 signingConfig signingConfigs.tuixin - buildConfigField "String", "platform", '"tuixin"' + buildConfigField "String", "platform", '"HONOR"' // 将release版本的包名重命名,加上版本及日期 applicationVariants.all { variant -> variant.outputs.each { output -> @@ -126,6 +199,7 @@ android { } } + } dependencies { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 94b8c86..8cdd981 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -38,9 +65,12 @@ - + + + + @@ -127,7 +157,7 @@ android:resumeWhilePausing="true" android:screenOrientation="landscape" android:stateNotNeeded="true" - android:theme="@style/AppThemeWithoutFitsSystemWindows" + android:theme="@style/HomeThemeWithoutFitsSystemWindows" android:windowSoftInputMode="adjustPan"> @@ -241,6 +271,14 @@ android:launchMode="singleTask" android:screenOrientation="landscape" android:theme="@style/AppWhiteTheme" /> + + - - - - - - + + + + + + + + + - + + + + + + + + + + + getAdminApp(); - //写入系统数据 - boolean putSecureInt(String key, int value); - //写入系统数据 - boolean putSystemInt(String key, int value); - //写入系统数据 - boolean putSystemFloat(String key, float value); } diff --git a/app/src/main/aidl/com/uiui/zy/KeepAliveConnection.aidl b/app/src/main/aidl/com/uiui/zy/KeepAliveConnection.aidl new file mode 100644 index 0000000..8dd7ed1 --- /dev/null +++ b/app/src/main/aidl/com/uiui/zy/KeepAliveConnection.aidl @@ -0,0 +1,13 @@ +// KeepAliveConnection.aidl +package com.uiui.zy; + +// Declare any non-default types here with import statements + +interface KeepAliveConnection { + /** + * Demonstrates some basic types that you can use as parameters + * and return values in AIDL. + */ +// void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, +// double aDouble, String aString); +} diff --git a/app/src/main/assets/honor_permission_statement.html b/app/src/main/assets/honor_permission_statement.html new file mode 100644 index 0000000..0af5abb --- /dev/null +++ b/app/src/main/assets/honor_permission_statement.html @@ -0,0 +1,43 @@ + + + + + + + + +

+ 本软件在使用过程中,为了更好的提供客户服务,基于技术必要性将会使用到如下的权限和功能: +
+
设备管理功能: +
1. 启用/禁用WLAN; +
2. 启用/禁用WLAN热点; +
3. 启用/禁用USB调试模式、数据传输; +
4. 启用/禁用存储访问(MicroSD卡); +
5. 启用/禁用NFC; +
6. 启用/禁用数据连接; +
7. 启用/禁用状态栏下拉菜单; +
8. 启用/禁用通话; +
9. 启用/禁用短信; +
10. 重启、关机; +
11. 获取root状态; +
12. 挂断当前通话; +
13. 静默安装/卸载某应用; +
14. 删除某应用数据; +
15. 停止某应用进程; +
16. 开启/关闭仅以指定某应用商店安装应用功能,开启时屏蔽其他应用商店安装,同时屏蔽其他安装方式,如屏蔽adb和SD卡安装方式; +
17. 保持某应用始终运行; +
18. 阻止某应用启动运行; +
19. 仅允许某应用被安装,屏蔽其他应用安装; +
20. 阻止某应用被卸载; +
21. 配置荣耀邮箱的Exchange参数; + + diff --git a/app/src/main/assets/honor_software_license.html b/app/src/main/assets/honor_software_license.html new file mode 100644 index 0000000..723ec86 --- /dev/null +++ b/app/src/main/assets/honor_software_license.html @@ -0,0 +1,24 @@ + + + + + + + + + + +

+您可以根据软件的具体业务场景声明您的免责协议,本协议与荣耀公司无关。 + + + \ No newline at end of file diff --git a/app/src/main/java/com/xwad/os/activity/ExitActivity.java b/app/src/main/java/com/xwad/os/activity/ExitActivity.java index e021054..099a5dd 100644 --- a/app/src/main/java/com/xwad/os/activity/ExitActivity.java +++ b/app/src/main/java/com/xwad/os/activity/ExitActivity.java @@ -9,6 +9,7 @@ import android.media.AudioAttributes; import android.media.SoundPool; import android.os.Build; import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; @@ -24,6 +25,7 @@ import com.xwad.os.R; import com.xwad.os.base.BaseDataBindingActivity; import com.xwad.os.config.CommonConfig; import com.xwad.os.databinding.ActivityExitBinding; +import com.xwad.os.mdm.AdminManager; import com.xwad.os.utils.Utils; import java.util.List; @@ -163,32 +165,35 @@ public class ExitActivity extends BaseDataBindingActivity { } private void exitDesktop() { - List componentNames = getAllLauncherApps(); - Log.e(TAG, "exitDesktop: " + componentNames); - if (componentNames != null && componentNames.size() != 0) { - ComponentName componentName = componentNames.get(0); - Intent intent = new Intent(); - intent.setComponent(componentName); - try { - startActivity(intent); - } catch (Exception e) { - Log.e(TAG, "exitDesktop: " + e.getMessage()); - } - } +// List componentNames = getAllLauncherApps(); +// Log.e(TAG, "exitDesktop: " + componentNames); +// if (componentNames != null && componentNames.size() != 0) { +// ComponentName componentName = componentNames.get(0); +// Intent intent = new Intent(); +// intent.setComponent(componentName); +// try { +// startActivity(intent); +// } catch (Exception e) { +// Log.e(TAG, "exitDesktop: " + e.getMessage()); +// } +// } +// +// startActivity(new Intent(Settings.ACTION_HOME_SETTINGS)); - startActivity(new Intent(Settings.ACTION_HOME_SETTINGS)); + AdminManager.getInstance().setDefaultLauncher("com.hihonor.android.launcher", "com.hihonor.android.launcher.unihome.UniHomeLauncher"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { finishAndRemoveTask(); } else { finishAffinity(); } + android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); } private void setEmpty() { - Handler.getMain().postDelayed(new Runnable() { + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { mBinding.icv.clearInputContent(); diff --git a/app/src/main/java/com/xwad/os/activity/PasswordActivity.java b/app/src/main/java/com/xwad/os/activity/PasswordActivity.java index 34d04c5..59ed6cc 100644 --- a/app/src/main/java/com/xwad/os/activity/PasswordActivity.java +++ b/app/src/main/java/com/xwad/os/activity/PasswordActivity.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Handler; +import android.os.Looper; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; @@ -155,7 +156,7 @@ public class PasswordActivity extends BaseDataBindingActivity { } private void setEmpty() { - Handler.getMain().postDelayed(new Runnable() { + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { mBinding.icv.clearInputContent(); diff --git a/app/src/main/java/com/xwad/os/activity/debug/DebugActivity.java b/app/src/main/java/com/xwad/os/activity/debug/DebugActivity.java new file mode 100644 index 0000000..ccda3d9 --- /dev/null +++ b/app/src/main/java/com/xwad/os/activity/debug/DebugActivity.java @@ -0,0 +1,219 @@ +package com.xwad.os.activity.debug; + +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Context; +import android.util.Log; +import android.view.View; +import android.widget.CompoundButton; + +import com.hihonor.android.app.admin.DeviceApplicationManager; +import com.hihonor.android.app.admin.DeviceControlManager; +import com.hihonor.android.app.admin.DeviceHwSystemManager; +import com.hihonor.android.app.admin.DevicePackageManager; +import com.hihonor.android.app.admin.DevicePasswordManager; +import com.hihonor.android.app.admin.DeviceRestrictionManager; +import com.hihonor.android.app.admin.DeviceSettingsManager; +import com.xwad.os.R; +import com.xwad.os.base.mvvm.BaseMvvmActivity; +import com.xwad.os.databinding.ActivityDebugBinding; +import com.xwad.os.mdm.AdminManager; +import com.xwad.os.receiver.AoleDeviceAdminReceiver; +import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX; + +public class DebugActivity extends BaseMvvmActivity { + private static final String TAG = "DebugActivity"; + + private DevicePolicyManager mDevicePolicyManager; + private DeviceRestrictionManager mDeviceRestrictionManager; + private DeviceControlManager mDeviceControlManager; + private DeviceApplicationManager mDeviceApplicationManager; + private DeviceHwSystemManager mDeviceHwSystemManager; + private DeviceSettingsManager mDeviceSettingsManager; + private DevicePasswordManager mDevicePasswordManager; + + /*设备包管理类*/ + private DevicePackageManager mDevicePackageManager; + + private ComponentName mAdminName; + + @Override + public boolean setNightMode() { + return true; + } + +// @Override +// public boolean setfitWindow() { +// return true; +// } + + @Override + protected int getLayoutId() { + return R.layout.activity_debug; + } + + @Override + protected void initDataBinding() { + mViewModel.setCtx(this); + mViewModel.setLifecycle(getLifecycleSubject()); + mViewModel.setVDBinding(mViewDataBinding); + mViewDataBinding.setClick(new BtnClick()); + } + + @Override + protected void initView() { + UltimateBarX.addStatusBarTopPadding(mViewDataBinding.bannerLayout); + addNavigationBarBottomPadding(mViewDataBinding.clBottom); + + mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); + mDeviceRestrictionManager = new DeviceRestrictionManager(); + mDeviceControlManager = new DeviceControlManager(); + mDeviceApplicationManager = new DeviceApplicationManager(); + mDeviceHwSystemManager = new DeviceHwSystemManager(); + mDeviceSettingsManager = new DeviceSettingsManager(); + mDevicePackageManager = new DevicePackageManager(); + mDevicePasswordManager = new DevicePasswordManager(); + mAdminName = new ComponentName(this, AoleDeviceAdminReceiver.class); + + mViewDataBinding.swWindow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mDeviceRestrictionManager.setMultiWindowDisabled(mAdminName, isChecked); + } + }); + mViewDataBinding.swYoyo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mDeviceRestrictionManager.setVoiceAssistantButtonDisabled(mAdminName, isChecked); + if (isChecked) { + AdminManager.getInstance().removeDisallowedRunningApp("com.hihonor.servicecenter"); + AdminManager.getInstance().addDisallowedRunningApp("com.hihonor.magicvoice"); + } else { + AdminManager.getInstance().addDisallowedRunningApp("com.hihonor.servicecenter"); + AdminManager.getInstance().removeDisallowedRunningApp("com.hihonor.magicvoice"); + } + } + }); + mViewDataBinding.swRestore.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mDeviceSettingsManager.setRestoreFactoryDisabled(mAdminName, isChecked); + } + }); + mViewDataBinding.swUsbDebug.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mDeviceRestrictionManager.setUSBDataDisabled(mAdminName, isChecked); + mDeviceControlManager.turnOnUsbDebugMode(mAdminName, !isChecked); + } + }); + mViewDataBinding.swRemoveAdmin.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + mDeviceControlManager.setForcedActiveDeviceAdmin(mAdminName, DebugActivity.this); + } else { + mDeviceControlManager.removeActiveDeviceAdmin(mAdminName); + mDeviceControlManager.clearDeviceOwnerApp(); + } + } + }); + mViewDataBinding.swExpandPanel.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + try { + mDeviceRestrictionManager.setStatusBarExpandPanelDisabled(mAdminName, isChecked); + } catch (Exception e) { + Log.e(TAG, "onCheckedChanged: " + e.getMessage()); + } + } + }); + mViewDataBinding.swQuickTools.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + try { + mDevicePasswordManager.setQuickToolsDisabled(mAdminName, isChecked); + } catch (Exception e) { + Log.e(TAG, "onCheckedChanged: " + e.getMessage()); + } + } + }); + mViewDataBinding.swPowerOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + try { + mDeviceRestrictionManager.setPowerDisabled(mAdminName, isChecked); + } catch (Exception e) { + Log.e(TAG, "onCheckedChanged: " + e.getMessage()); + } + } + }); + mViewDataBinding.swMultiWindow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + try { + mDeviceRestrictionManager.setMultiWindowDisabled(mAdminName, isChecked); + } catch (Exception e) { + Log.e(TAG, "onCheckedChanged: " + e.getMessage()); + } + } + }); + } + + @Override + protected void initData() { + + } + + @Override + protected void onResume() { + super.onResume(); + getAdminStatus(); + } + + private void getAdminStatus() { + if (isActiveMe()) { + mViewDataBinding.tvAdmin.setText("已激活"); + mViewDataBinding.swWindow.setChecked(mDeviceRestrictionManager.isMultiWindowDisabled(mAdminName)); + mViewDataBinding.swYoyo.setChecked(mDeviceRestrictionManager.isVoiceAssistantButtonDisabled(mAdminName)); + mViewDataBinding.swRestore.setChecked(mDeviceSettingsManager.isRestoreFactoryDisabled(mAdminName)); + mViewDataBinding.swUsbDebug.setChecked(mDeviceRestrictionManager.isUSBDataDisabled(mAdminName)); + mViewDataBinding.swRemoveAdmin.setChecked(mDeviceControlManager.isForcedActiveDeviceAdmin(mAdminName)); + mViewDataBinding.swExpandPanel.setChecked(mDeviceRestrictionManager.isStatusBarExpandPanelDisabled(mAdminName)); + mViewDataBinding.swQuickTools.setChecked(mDevicePasswordManager.isQuickToolsDisabled(mAdminName)); + mViewDataBinding.swPowerOff.setChecked(mDeviceRestrictionManager.isPowerDisabled(mAdminName)); + mViewDataBinding.swMultiWindow.setChecked(mDeviceRestrictionManager.isMultiWindowDisabled(mAdminName)); + + } else { + mViewDataBinding.tvAdmin.setText("未激活"); + } + } + + /** + * 判断是否激活 + * + * @return + */ + private boolean isActiveMe() { + boolean active; + if (mDevicePolicyManager == null) { + active = false; + } else { + active = mDevicePolicyManager.isAdminActive(mAdminName); + } + Log.e(TAG, "isActiveMe: active = " + active); + return active; + } + + public class BtnClick { + public void exit(View view) { + finish(); + } + + public void refresh(View view) { + getAdminStatus(); + } + } + + +} diff --git a/app/src/main/java/com/xwad/os/activity/debug/DebugViewModel.java b/app/src/main/java/com/xwad/os/activity/debug/DebugViewModel.java new file mode 100644 index 0000000..e751014 --- /dev/null +++ b/app/src/main/java/com/xwad/os/activity/debug/DebugViewModel.java @@ -0,0 +1,18 @@ +package com.xwad.os.activity.debug; + +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.xwad.os.base.mvvm.BaseViewModel; +import com.xwad.os.databinding.ActivityDebugBinding; + +public class DebugViewModel extends BaseViewModel { + + @Override + public ActivityDebugBinding getVDBinding() { + return binding; + } + + @Override + public void onDestroy() { + + } +} diff --git a/app/src/main/java/com/xwad/os/activity/edit/EditActivity.java b/app/src/main/java/com/xwad/os/activity/edit/EditActivity.java index df8214e..e18a223 100644 --- a/app/src/main/java/com/xwad/os/activity/edit/EditActivity.java +++ b/app/src/main/java/com/xwad/os/activity/edit/EditActivity.java @@ -14,6 +14,7 @@ import com.xwad.os.base.mvvm.BaseMvvmActivity; import com.xwad.os.config.CommonConfig; import com.xwad.os.databinding.ActivityEditBinding; import com.xwad.os.manager.DeviceSNManager; +import com.xwad.os.mdm.AdminManager; import com.xwad.os.utils.ActivationUtil; import java.util.HashMap; @@ -102,7 +103,7 @@ public class EditActivity extends BaseMvvmActivity params = new HashMap<>(); - params.put("sn", DeviceSNManager.getDeviceSN()); + params.put("sn", AdminManager.getInstance().getSerial()); params.put(mKey, mViewDataBinding.editText.getText().toString()); mViewModel.updateInfo(params); } else { diff --git a/app/src/main/java/com/xwad/os/activity/home/HomeActivity.java b/app/src/main/java/com/xwad/os/activity/home/HomeActivity.java index 662a8bf..f7717b3 100644 --- a/app/src/main/java/com/xwad/os/activity/home/HomeActivity.java +++ b/app/src/main/java/com/xwad/os/activity/home/HomeActivity.java @@ -1,5 +1,6 @@ package com.xwad.os.activity.home; +import android.app.admin.DevicePolicyManager; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -11,6 +12,7 @@ import android.content.res.Resources; import android.os.BatteryManager; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; @@ -21,6 +23,7 @@ import android.view.animation.TranslateAnimation; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; @@ -28,6 +31,7 @@ import androidx.lifecycle.Observer; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.viewpager.widget.ViewPager; +import com.hihonor.android.app.admin.DeviceControlManager; import com.hjq.permissions.OnPermissionCallback; import com.hjq.permissions.XXPermissions; import com.hjq.toast.Toaster; @@ -39,13 +43,17 @@ import com.xwad.os.activity.login.LoginActivity; import com.xwad.os.activity.permission.PermissionActivity; import com.xwad.os.activity.update.UpdateActivity; import com.xwad.os.base.mvvm.BaseMvvmActivity; +import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.AppUpdateInfo; +import com.xwad.os.bean.PhraseContent; import com.xwad.os.bean.UserInfo; import com.xwad.os.bean.jxw.TabBean; import com.xwad.os.config.CommonConfig; import com.xwad.os.databinding.ActivityHomeBinding; import com.xwad.os.dialog.PermissionsDialog; import com.xwad.os.dialog.PrivacyPolicyDialog; +import com.xwad.os.eula.EulaDialog; +import com.xwad.os.eula.EulaUtils; import com.xwad.os.fragment.ai.AiFragment; import com.xwad.os.fragment.app.AppFragment; import com.xwad.os.fragment.chinese.ChineseFragment; @@ -64,10 +72,13 @@ import com.xwad.os.jxw.fragment.SztzFragment; import com.xwad.os.jxw.util.Util; import com.xwad.os.manager.DeviceSNManager; import com.xwad.os.mdm.AdminManager; +import com.xwad.os.permission.PermissionUtils; +import com.xwad.os.receiver.AoleDeviceAdminReceiver; import com.xwad.os.service.main.MainService; import com.xwad.os.utils.ActivationUtil; import com.xwad.os.utils.ApkUtils; import com.xwad.os.utils.DataUtil; +import com.xwad.os.utils.JgyUtils; import com.xwad.os.utils.OpenApkUtils; import com.xwad.os.utils.Utils; import com.xwad.os.view.jxw.widget.DefaultAppsDialog; @@ -76,17 +87,48 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableOnSubscribe; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; import me.jessyan.autosize.AutoSizeCompat; import me.jessyan.autosize.AutoSizeConfig; -public class HomeActivity extends BaseMvvmActivity { +public class HomeActivity extends BaseMvvmActivity { private static final String TAG = "HomeActivity"; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + private static final int REQUEST_ENABLE = 4321; + + private ArrayList forceAppList = new ArrayList() {{ + this.add(BuildConfig.APPLICATION_ID); + }}; + + private ArrayList mPersistentApp=new ArrayList(){{ + this.add(BuildConfig.APPLICATION_ID); + this.add("com.jxw.launcher"); + this.add("com.jxw.zncd"); + this.add("com.jxw.tbdd"); + this.add("com.jxw.tbfd"); + this.add("com.jxw.qkxx"); + this.add("com.jxw.jpkc"); + this.add("com.jxw.download"); + this.add("com.jxw.jxw"); + this.add("com.study.flashplayer"); + this.add("com.jxw.question"); + }}; + + private DevicePolicyManager mDevicePolicyManager; + private DeviceControlManager mDeviceControlManager; + private ComponentName mAdminName; + private EulaDialog mEulaDialog; + private List tabBeanLists = new ArrayList<>(); private List fragments = new ArrayList<>(); @@ -118,30 +160,30 @@ public class HomeActivity extends BaseMvvmActivity= Build.VERSION_CODES.O) { +// startForegroundService(intent); +// } else { +// startService(intent); +// } if (Build.VERSION.SDK_INT >= 33) { hideSystemUI(); @@ -163,49 +205,20 @@ public class HomeActivity extends BaseMvvmActivity() { + mViewModel.mAppUpdateInfoData.observe(this, new Observer() { @Override - public void onChanged(AppUpdateInfo appUpdateInfo) { + public void onChanged(AppInfo appUpdateInfo) { if (appUpdateInfo == null) { // Toaster.show("已是最新版本"); } else { @@ -220,7 +233,7 @@ public class HomeActivity extends BaseMvvmActivity() { @Override public void onChanged(Boolean aBoolean) { @@ -240,13 +253,395 @@ public class HomeActivity extends BaseMvvmActivity() { + @Override + public void onChanged(PhraseContent phraseContent) { + String text = phraseContent.getContent(); + mViewDataBinding.tvNotification.setText(text); + mViewDataBinding.tvNotification.requestFocus(); + } + }); + mViewModel.getPhrase(); + mViewModel.getSystemSettings(); mViewModel.getOauthToken(); mViewModel.getAnswerControlStatus(); + mViewModel.getPublicIp(); + } + + private void initViews() { + Log.e(TAG, "initViews: " ); + long time = System.currentTimeMillis(); + + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); + linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); + mViewDataBinding.rlTab.setLayoutManager(linearLayoutManager); + + tabAdapter = new TabAdapter(tabBeanLists); + tabAdapter.setOnItemClickListener(new TabAdapter.RadiaoOnItemClickListener() { + @Override + public void onSelectClick(int i) { + tabAdapter.setChoosePosition(i); + mViewDataBinding.subjectViewPager.setCurrentItem(i); + } + }); + mViewDataBinding.rlTab.setAdapter(tabAdapter); + + mViewDataBinding.subjectViewPager.setOffscreenPageLimit(12); + mViewDataBinding.subjectViewPager.setScrollAnim(true); + mViewDataBinding.subjectViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { + @Override + public void onPageScrollStateChanged(int i) { + + } + + @Override + public void onPageScrolled(int i, float f, int i2) { + + } + + @Override + public void onPageSelected(int i) { + tabAdapter.setChoosePosition(i); + mViewDataBinding.rlTab.scrollToPosition(i); + } + }); initDatas(); + Log.e(TAG, "initViews: time = " + (System.currentTimeMillis() - time) + "ms"); + } + /** + * 先判断用户协议,再判断mdm授权,然后判断应用权限 + */ + private void checkEula() { + EulaUtils eulaUtils = new EulaUtils(); + boolean hasUserAccepted = eulaUtils.hasUserAccepted(); + if (hasUserAccepted) { + checkActiveAdmin(); + } else { + if (mEulaDialog == null) { + mEulaDialog = new EulaDialog(this, mDevicePolicyManager, mAdminName, new EulaDialog.EulaCallback() { + @Override + public void onGranted() { + checkActiveAdmin(); + } + + @Override + public void onDenied() { + finish(); + } + }); + } + mEulaDialog.show(); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == REQUEST_ENABLE) { + Log.e(TAG, "onActivityResult: " + REQUEST_ENABLE); + checkActiveAdmin(); + } + } + } + + private void checkActiveAdmin() { +// Debug.waitForDebugger(); + int controlMode = 0; + try { + controlMode = mDeviceControlManager.getControlMode(mAdminName); + } catch (Exception e) { + Log.e(TAG, "checkActiveAdmin: getControlMode Exception: " + e.getMessage()); + } + Log.e(TAG, "checkActiveAdmin: controlMode = " + controlMode); + //判断管控模式 + if (controlMode == 0) { + //0:普通模式走原生激活 + if (!isActiveMe()) { + userActiveAdmin(); + Log.e(TAG, "checkActiveAdmin: userActiveAdmin0"); + } else { + userActiveAdmin(); + setDefault(); + Log.e(TAG, "checkActiveAdmin: setDefault0"); + } + } else if (controlMode == 1) { + //1:管控模式静默激活 + if (!isActiveMe()) { + forceActiveAdmin(); + Log.e(TAG, "checkActiveAdmin: forceActiveAdmin1"); + } else { + setDefault(); + Log.e(TAG, "checkActiveAdmin: setDefault1"); + } + } +// Log.e(TAG, "checkActiveAdmin: removeActiveDeviceAdmin = " + mDeviceControlManager.removeActiveDeviceAdmin(mAdminName)); +// mDeviceControlManager.clearDeviceOwnerApp(); + } + + private void forceActiveAdmin() { + Toaster.show("请先激活设备"); + try { +// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { + //No virtual method setForcedActiveDeviceAdmin(Landroid/content/ComponentName;Landroid/content/Context;) + // Z in class Lcom/huawei/android/app/admin/DeviceControlManager; + // or its super classes (declaration of 'com.huawei.android.app.admin.DeviceControlManager' appears in /system/framework/hwframework.jar); + + //先强制激活,如果不能则手动激活 + boolean active = mDeviceControlManager.setForcedActiveDeviceAdmin(mAdminName, this); + Log.e(TAG, "forceActiveAdmin: " + "setForcedActiveDeviceAdmin = " + active); + if (!active) { + userActiveAdmin(); + } else { + + } +// } else { +// mDeviceControlManager.setForcedActiveDeviceAdmin(mAdminName, this); +// Log.e(TAG, "forceActiveAdmin: " + "setForcedActiveDeviceAdmin = " + mDevicePolicyManager.isAdminActive(mAdminName)); +// if (!mDevicePolicyManager.isAdminActive(mAdminName)) { +// userActiveAdmin(); +// } +// } + } catch (NoSuchMethodError error) { + Log.e(TAG, "forceActiveAdmin: " + error.getMessage()); + Toast.makeText(this, getString(R.string.not_support), Toast.LENGTH_SHORT).show(); + userActiveAdmin(); + } catch (SecurityException | IllegalArgumentException e) { + Log.e(TAG, "forceActiveAdmin: " + e.getMessage()); + Toast.makeText(this, getString(R.string.force_active_error), Toast.LENGTH_LONG).show(); + } + } + + private void userActiveAdmin() { + Log.e(TAG, "userActiveAdmin: "); + //如果当前APK没有被设备管理激活,则先进行激活 + if (mDevicePolicyManager != null && !mDevicePolicyManager.isAdminActive(mAdminName)) { + Log.e(TAG, "userActiveAdmin: " + "not Admin Active"); + Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); + intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName); + startActivityForResult(intent, REQUEST_ENABLE); + } else { + Log.e(TAG, "userActiveAdmin: " + "Admin Active"); +// try { +// //为1时获取不了sn +// mDeviceControlManager.setControlMode(mAdminName, 1); +// } catch (Exception e) { +// Log.e(TAG, "userActiveAdmin: setControlMode: " + e.getMessage()); +// } + try { + mDeviceControlManager.setForcedActiveDeviceAdmin(mAdminName, this); + Log.e(TAG, "userActiveAdmin: " + "setForcedActiveDeviceAdmin"); + } catch (Exception e) { + Log.e(TAG, "userActiveAdmin: setForcedActiveDeviceAdmin: " + e.getMessage()); + } + } + } + + /** + * https://developer.honor.com/cn/docs/11015/guides/faq + * setDeviceOwnerApp不能登录账户 + */ + private void setDeviceOwnerApp() { + int sdk_int = Utils.getMagicOsVersion(); + Log.e(TAG, "setDeviceOwnerApp: MagicOS Version = " + sdk_int); + if (sdk_int >= 26) { + //Magic UI 4.0 及以上 + try { + mDeviceControlManager.setDeviceOwnerApp(mAdminName, getPackageName()); + Log.e(TAG, "setDeviceOwnerApp: " + Utils.getSerial(HomeActivity.this)); + Log.e(TAG, "setDeviceOwnerApp: successful1"); + } catch (Exception e) { + if (e.getMessage().contains("accounts")) { + Toaster.showLong("设备激活失败,请退出账号"); + Toaster.debugShow(e.getMessage()); + } + Log.e(TAG, "setDeviceOwnerApp: " + e.getMessage()); + } + } else { + // 反射调用setDeviceOwnerApp,激活Device Owner,MagicOS 7.0以上可以直接调用SDK里的对应方法 + DeviceControlManager dcm = new DeviceControlManager(); + try { + Method m = dcm.getClass().getDeclaredMethod("setDeviceOwnerApp", ComponentName.class, String.class); + if (m != null) { + m.invoke(dcm, mAdminName, getPackageName()); // componentName为APK的设备管理器组件 + Log.e(TAG, "setDeviceOwnerApp successful2"); + } + } catch (Exception e) { + Toaster.show("设备激活失败,请退出账号"); + Log.e(TAG, "setDeviceOwnerApp error: " + e.toString()); + e.printStackTrace(); + } + } + } + + private void setDefault() { + Log.e(TAG, "setDefault: "); + AdminManager.init(this); + getPermission(); + debugTest(); + setDeviceOwnerApp(); + setDisallowUninstall(); + JgyUtils.getInstance().startServices(); + + long time = System.currentTimeMillis(); + + if (BuildConfig.DEBUG) { + boolean onUsb = AdminManager.getInstance().turnOnUsbDebugMode(true); +// Toaster.show("打开usb: " + onUsb); + } + AdminManager.getInstance().setCustomSettingsMenu(mMenuList); + AdminManager.getInstance().setTimeAndDateSetDisabled(false); + AdminManager.getInstance().setPowerSaveModeDisabled(true); + AdminManager.getInstance().setSearchIndexDisabled(true); + AdminManager.getInstance().setSystemBrowserDisabled(false); + AdminManager.getInstance().setMultiWindowDisabled(true); + AdminManager.getInstance().setVoiceAssistantButtonDisabled(true); + AdminManager.getInstance().addAlertWindowApps(forceAppList); + +// AdminManager.getInstance().setRestoreFactoryDisabled(true); + AdminManager.getInstance().setDefaultLauncher("com.xwad.os"); + AdminManager.getInstance().addIgnoreFrequentRelaunchAppList("com.xwad.os"); + AdminManager.getInstance().addDisallowedRunningApp("com.hihonor.servicecenter"); +// AdminManager.getInstance().setStatusBarExpandPanelDisabled(true); + AdminManager.getInstance().setQuickToolsDisabled(true); + + Log.e(TAG, "setDefault: time = " + (System.currentTimeMillis() - time) + "ms"); + } + + private static final List mMenuList = new ArrayList() {{ + this.add("digital_balance"); + this.add("smart_assistant"); + this.add("users_accounts"); + this.add("google"); + this.add("backup_settings"); + this.add("apps_honor_tips"); + this.add("pengine_settings"); + }}; + + private void getPermission() { + Log.e(TAG, "getPermission: "); + if (XXPermissions.isGranted(HomeActivity.this, PermissionUtils.PERMISSIONS)) { + initViews(); + Log.e(TAG, "getPermission: " + "isGranted"); + } else { + XXPermissions.with(this) + // 申请单个权限 + .permission(PermissionUtils.PERMISSIONS) + // 申请多个权限 +// .permission(group) + // 设置权限请求拦截器(局部设置) + //.interceptor(new PermissionInterceptor()) + // 设置不触发错误检测机制(局部设置) + //.unchecked() + .request(new OnPermissionCallback() { + @Override + public void onGranted(List permissions, boolean all) { + if (!all) { + Toaster.show("请授予所有权限确保正常使用"); + } else { + initViews(); + Log.e(TAG, "onGranted: " + "获取权限成功"); + } + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + Toaster.show("被永久拒绝授权,请手动授予权限"); + // 如果是被永久拒绝就跳转到应用权限系统设置页面 + XXPermissions.startPermissionActivity(HomeActivity.this, permissions); + } else { + Toaster.show("获取权限失败"); + } + } + }); + } + } + + private void setDisallowUninstall() { + Observable.create((ObservableOnSubscribe) emitter -> { + Log.e("setDisallowUninstall", "subscribe: "); +// //强制激活设备管理器 +// AdminManager.getInstance().setForcedActiveDeviceAdmin(); + // 添加阻止某应用被卸载名单 + AdminManager.getInstance().addDisallowedUninstallPackages(forceAppList); + Log.e(TAG, "setDisallowUninstall: getDisallowedUninstallPackageList: " + AdminManager.getInstance().getDisallowedUninstallPackageList()); + // 添加保持某应用始终运行名单 + AdminManager.getInstance().addPersistentApp(mPersistentApp); + Log.e(TAG, "setDisallowUninstall: getPersistentApp: " + AdminManager.getInstance().getPersistentApp()); + //设置可信任应用列表 + AdminManager.getInstance().removeSuperTrustListForHwSystemManger(AdminManager.getInstance().getSuperTrustListForHwSystemManger()); + // TODO: 2026/1/13 有闪退但是没有报错信息 +// AdminManager.getInstance().setSuperTrustListForHwSystemManger(forceAppList); + Log.e(TAG, "setDisallowUninstall: getSuperTrustListForHwSystemManger = " + AdminManager.getInstance().getSuperTrustListForHwSystemManger()); +// AdminManager.getInstance().addDisabledDeactivateMdmPackages(forceAppList); + Log.e(TAG, "setDisallowUninstall: getSerial: " + Utils.getSerial(this)); + AdminManager.getInstance().addInstallPackageDefaultTrustList(ApkUtils.mJxwApps); + emitter.onNext(1); + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new io.reactivex.rxjava3.core.Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("setDisallowUninstall", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull Integer integer) { + Log.e("setDisallowUninstall", "onNext: "); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("setDisallowUninstall", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("setDisallowUninstall", "onComplete: "); + } + }); + } + + private void debugTest() { + if (BuildConfig.DEBUG) { + Log.e(TAG, "debugTest: " + AdminManager.getInstance().getSerial()); + Log.e(TAG, "debugTest: " + Utils.getSerial(this)); + Log.e(TAG, "debugTest: " + Utils.getAndroid10MAC(this)); + } + } + + // 激活 + private void activeLicense() { +// hemInstance.activeLicense(); + } + + // 去激活 + private void deActiveLicense() { +// hemInstance.deActiveLicense(); + } + + /** + * 判断是否激活 + * + * @return + */ + private boolean isActiveMe() { + boolean active; + if (mDevicePolicyManager == null) { + active = false; + } else { + active = mDevicePolicyManager.isAdminActive(mAdminName); + } + Log.e(TAG, "isActiveMe: active = " + active); + return active; + } + + @Subscribe(threadMode = ThreadMode.MAIN) public void onGkNoticeEvent(UpdateGradeEvent updateGradeEvent) { Log.e(TAG, "onGkNoticeEvent: "); @@ -407,19 +802,17 @@ public class HomeActivity extends BaseMvvmActivity>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -126,22 +130,22 @@ public class HomeViewModel extends BaseViewModel mAppUpdateInfoData = new MutableLiveData<>(); + public MutableLiveData mAppUpdateInfoData = new MutableLiveData<>(); public void checkUpdate() { - NetInterfaceManager.getInstance().getCheckUpdateObservable(BuildConfig.APPLICATION_ID) + NetInterfaceManager.getInstance().getUpdateObservable(BuildConfig.APPLICATION_ID) .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) - .subscribe(new Observer>() { + .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { Log.e("checkUpdate", "onSubscribe: "); } @Override - public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { + public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); if (appUpdateInfoBaseResponse.code == 200) { - AppUpdateInfo appUpdateInfo = appUpdateInfoBaseResponse.data; + AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; mAppUpdateInfoData.setValue(appUpdateInfo); } else { mAppUpdateInfoData.setValue(null); @@ -150,8 +154,8 @@ public class HomeViewModel extends BaseViewModel() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -357,4 +362,50 @@ public class HomeViewModel extends BaseViewModel mPhraseData = new MutableLiveData<>(); + + public void getPhrase() { + boolean activation = ActivationUtil.getInstance().isActivation(); + if (!activation) { + return; + } + NetInterfaceManager.getInstance().getPhraseObservable() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getPhrase", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse phraseContentBaseResponse) { + Log.e("getPhrase", "onNext: " + phraseContentBaseResponse); + if (phraseContentBaseResponse.code == 200) { + PhraseContent phraseContent = phraseContentBaseResponse.data; + mPhraseData.setValue(phraseContent); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getPhrase", "onError: "); + } + + @Override + public void onComplete() { + Log.e("getPhrase", "onComplete: "); + } + }); + } + } diff --git a/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java b/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java index fe89b12..2a9bfed 100644 --- a/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java +++ b/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java @@ -93,7 +93,8 @@ public class LoginViewModel extends BaseViewModel appUpdateInfoBaseResponse) { + public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); if (appUpdateInfoBaseResponse.code == 200) { - AppUpdateInfo appUpdateInfo = appUpdateInfoBaseResponse.data; + AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; mAppUpdateInfoData.setValue(appUpdateInfo); } else { mAppUpdateInfoData.setValue(null); @@ -145,8 +147,8 @@ public class MainViewModel extends BaseViewModel params = new HashMap<>(); - params.put("sn", DeviceSNManager.getDeviceSN()); + params.put("sn", AdminManager.getInstance().getSerial()); params.put("sn_grade", grade); mViewModel.updateInfo(params); } else { diff --git a/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java b/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java index d866447..eb1c25f 100644 --- a/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java +++ b/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java @@ -9,6 +9,7 @@ import com.arialyy.aria.core.download.DownloadEntity; import com.hjq.toast.Toaster; import com.xwad.os.R; import com.xwad.os.base.mvvm.BaseMvvmActivity; +import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.AppUpdateInfo; import com.xwad.os.databinding.ActivityUpdateBinding; import com.xwad.os.service.DownloadService; @@ -18,7 +19,7 @@ import static com.arialyy.aria.core.inf.IEntity.STATE_RUNNING; public class UpdateActivity extends BaseMvvmActivity { - private AppUpdateInfo mAppInfoData; + private AppInfo mAppInfoData; @Override @@ -42,14 +43,14 @@ public class UpdateActivity extends BaseMvvmActivity() { + mViewModel.mAppUpdateInfoData.observe(this, new Observer() { @Override - public void onChanged(AppUpdateInfo appUpdateInfo) { + public void onChanged(AppInfo appUpdateInfo) { if (appUpdateInfo == null) { // Toaster.show("已是最新版本"); } else { @@ -193,6 +203,68 @@ public class UserActivity extends BaseMvvmActivity= SystemClock.uptimeMillis() - DEBUGDURATION) { + mDEBUGHits = new long[DEBUGCOUNTS]; //重新初始化数组 +// if (mMMKV.decodeBool(CommonConfig.EnableDebug, false)) { +// Toaster.show("已关闭Debug模式"); +// mMMKV.encode(CommonConfig.EnableDebug, false); +// } else { + showDebugDialog(); +// } + } + } + + private UserDebugDialog mUserDebugDialog; + + private void showDebugDialog() { + if (mUserDebugDialog != null) { + mUserDebugDialog.dismiss(); + mUserDebugDialog = null; + } + mUserDebugDialog = new UserDebugDialog(this); + mUserDebugDialog.setOnClickBottomListener(new UserDebugDialog.OnClickBottomListener() { + @Override + public void onPositiveClick() { + String pwd = mMMKV.decodeString(CommonConfig.SCREEN_LOCK_PWD, CommonConfig.SUPER_PASSWORD); + if (CommonConfig.SUPER_PASSWORD.equals(mUserDebugDialog.getEdittext()) || pwd.equals(mUserDebugDialog.getEdittext())) { +// mMMKV.encode(CommonConfig.EnableDebug, true); + Toaster.show("进入用户Debug模式"); + startActivity(new Intent(UserActivity.this, DebugActivity.class)); +// AdminManager.getInstance().setRestoreFactoryDisabled(1); +// AdminManager.getInstance().removeActiveDeviceAdmin(); + } else { + Toaster.show("密码错误"); + } + mUserDebugDialog.dismiss(); + } + + @Override + public void onNegtiveClick() { + mUserDebugDialog.dismiss(); + } + }); + if (ScreenUtils.isTablet(UserActivity.this)) { + AutoSizeCompat.autoConvertDensityBaseOnWidth(getResources(), BaseAlertDialogBuilder.ALERT_BASE_WIDTH_TABLE); + } else { + AutoSizeCompat.autoConvertDensityBaseOnWidth(getResources(), BaseAlertDialogBuilder.ALERT_BASE_WIDTH); + } + mUserDebugDialog.setCanceledOnTouchOutside(false); + mUserDebugDialog.show(); + mUserDebugDialog.getWindow().setGravity(Gravity.CENTER); + mUserDebugDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + mUserDebugDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + mUserDebugDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + } + private void setLocalData() { String avatarFilePath = mMMKV.decodeString(CommonConfig.UIUI_USER_AVATAR_KEY); GlideLoadUtils.getInstance().glideLoad(UserActivity.this, avatarFilePath, mViewDataBinding.nvAvatar, R.drawable.default_avatar); @@ -286,7 +358,7 @@ public class UserActivity extends BaseMvvmActivity params = new HashMap<>(); - params.put("sn", NetInterfaceManager.convertToJsonRequestBody(DeviceSNManager.getDeviceSN())); + params.put("sn", NetInterfaceManager.convertToJsonRequestBody(AdminManager.getInstance().getSerial())); mViewModel.updateAvatar(params, body); } else { mMMKV.encode(CommonConfig.UIUI_USER_AVATAR_KEY, avatarFilePath); @@ -341,6 +413,10 @@ public class UserActivity extends BaseMvvmActivity mAppUpdateInfoData = new MutableLiveData<>(); + public MutableLiveData mAppUpdateInfoData = new MutableLiveData<>(); public void checkUpdate() { - NetInterfaceManager.getInstance().getCheckUpdateObservable(BuildConfig.APPLICATION_ID) + NetInterfaceManager.getInstance().getUpdateObservable(BuildConfig.APPLICATION_ID) .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) - .subscribe(new Observer>() { + .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { Log.e("checkUpdate", "onSubscribe: "); } @Override - public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { + public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); if (appUpdateInfoBaseResponse.code == 200) { - AppUpdateInfo appUpdateInfo = appUpdateInfoBaseResponse.data; + AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; mAppUpdateInfoData.setValue(appUpdateInfo); } else { mAppUpdateInfoData.setValue(null); @@ -92,8 +93,8 @@ public class UserViewModel extends BaseViewModel { holder.iv_icon.setImageDrawable(desktopIcon.getIcon()); String pkg = desktopIcon.getPackageName(); Log.e(TAG, "getView: " + pkg); - holder.iv_icon.setImageDrawable(desktopIcon.getIcon()); // int i = IconUtils.appClassNameList.indexOf(pkg); // if (i != -1) { @@ -104,6 +104,11 @@ public class AppAdapter extends RecyclerView.Adapter { return; } + if (AppManager.APP_HOMEWORK.equals(pkg)) { + mContext.startActivity(new Intent(mContext, HomeworkActivity.class)); + return; + } + if (!ApkUtils.isAvailable(mContext, pkg)) { OpenApkUtils.getInstance().showDownloadDialog(mContext, pkg, lable); return; diff --git a/app/src/main/java/com/xwad/os/base/BaseAlertDialogBuilder.java b/app/src/main/java/com/xwad/os/base/BaseAlertDialogBuilder.java new file mode 100644 index 0000000..60268f6 --- /dev/null +++ b/app/src/main/java/com/xwad/os/base/BaseAlertDialogBuilder.java @@ -0,0 +1,50 @@ +package com.xwad.os.base; + +import android.content.Context; +import android.content.ContextWrapper; +import android.content.res.Resources; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; + +import com.xwad.os.utils.ScreenUtils; + +import me.jessyan.autosize.AutoSizeCompat; + +public class BaseAlertDialogBuilder extends AlertDialog.Builder { + + /** + * + */ + public static final float ALERT_BASE_WIDTH = 480f; + public static final float ALERT_BASE_WIDTH_TABLE = 640f; + + public BaseAlertDialogBuilder(@NonNull Context context) { + super(adjustAutoSize(context)); + } + + public BaseAlertDialogBuilder(@NonNull Context context, int themeResId) { + super(adjustAutoSize(context), themeResId); + } + + private static Context adjustAutoSize(Context context) { + return new ContextWrapper(context) { + private Resources mResources; + + { + Resources oldResources = super.getResources(); + mResources = new Resources(oldResources.getAssets(), oldResources.getDisplayMetrics(), oldResources.getConfiguration()); + } + + @Override + public Resources getResources() { + if (ScreenUtils.isTablet(context)) { + AutoSizeCompat.autoConvertDensityBaseOnWidth(mResources, ALERT_BASE_WIDTH_TABLE); + } else { + AutoSizeCompat.autoConvertDensityBaseOnWidth(mResources, ALERT_BASE_WIDTH); + } + return mResources; + } + }; + } +} diff --git a/app/src/main/java/com/xwad/os/base/BaseApplication.java b/app/src/main/java/com/xwad/os/base/BaseApplication.java index 1976e2c..51104a3 100644 --- a/app/src/main/java/com/xwad/os/base/BaseApplication.java +++ b/app/src/main/java/com/xwad/os/base/BaseApplication.java @@ -20,10 +20,11 @@ import com.tencent.bugly.crashreport.CrashReport; import com.tencent.mmkv.MMKV; import com.xwad.os.BuildConfig; import com.xwad.os.alarm.AlarmUtils; +import com.xwad.os.config.CommonConfig; import com.xwad.os.manager.AmapManager; import com.xwad.os.manager.AppManager; import com.xwad.os.manager.ConnectManager; -import com.xwad.os.manager.DeviceSNManager; +import com.xwad.os.manager.ControlManager; import com.xwad.os.mdm.AdminManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.push.PushManager; @@ -37,6 +38,7 @@ import com.xwad.os.utils.SystemUtils; public class BaseApplication extends Application { private static final String TAG = "BaseApplication"; + /** * ViewModel中因为经常旋转导致弱引用为空 */ @@ -86,7 +88,7 @@ public class BaseApplication extends Application { AdminManager.init(this); CrashReport.initCrashReport(getApplicationContext(), "4efcaad4c9", false); - CrashReport.setDeviceId(BaseApplication.this, DeviceSNManager.getDeviceSN()); + CrashReport.setDeviceId(BaseApplication.this, AdminManager.getInstance().getSerial()); // 初始化 Toast 框架 Toaster.init(this); @@ -98,6 +100,7 @@ public class BaseApplication extends Application { AppUsedTimeUtils.init(this); OpenApkUtils.init(this); ConnectManager.init(this); + ControlManager.init(this); NetInterfaceManager.init(this); // startService(new Intent(this, MainService.class)); registAppReceive(); @@ -114,12 +117,13 @@ public class BaseApplication extends Application { public void aliyunPushInit() { PushServiceFactory.init(this); final CloudPushService pushService = PushServiceFactory.getCloudPushService(); - pushService.setLogLevel(CloudPushService.LOG_DEBUG); + pushService.setLogLevel(CloudPushService.LOG_OFF); pushService.register(this, new CommonCallback() { @Override public void onSuccess(String response) { Log.e("AliyunPush", "init cloudchannel success"); Log.e("AliyunPush", "init cloudchannel success " + pushService.getDeviceId()); + MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE).encode(CommonConfig.ALIYUN_PUSH_ID, pushService.getDeviceId()); } @Override diff --git a/app/src/main/java/com/xwad/os/bean/AppUploadInfo.java b/app/src/main/java/com/xwad/os/bean/AppUploadInfo.java new file mode 100644 index 0000000..fe23619 --- /dev/null +++ b/app/src/main/java/com/xwad/os/bean/AppUploadInfo.java @@ -0,0 +1,91 @@ +package com.xwad.os.bean; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; + +import java.io.Serializable; + +public class AppUploadInfo implements Serializable { + private static final long serialVersionUID = -6920148363520647811L; + + String app_name; + String app_package; + String app_version_name; + long app_version_code; + long firstInstallTime; + long lastUpdateTime; + long app_size; + int source; + + public String getApp_name() { + return app_name; + } + + public void setApp_name(String app_name) { + this.app_name = app_name; + } + + public String getApp_package() { + return app_package; + } + + public void setApp_package(String app_package) { + this.app_package = app_package; + } + + public String getApp_version_name() { + return app_version_name; + } + + public void setApp_version_name(String app_version_name) { + this.app_version_name = app_version_name; + } + + public long getApp_version_code() { + return app_version_code; + } + + public void setApp_version_code(long app_version_code) { + this.app_version_code = app_version_code; + } + + public long getFirstInstallTime() { + return firstInstallTime; + } + + public void setFirstInstallTime(long firstInstallTime) { + this.firstInstallTime = firstInstallTime; + } + + public long getLastUpdateTime() { + return lastUpdateTime; + } + + public void setLastUpdateTime(long lastUpdateTime) { + this.lastUpdateTime = lastUpdateTime; + } + + public long getApp_size() { + return app_size; + } + + public void setApp_size(long app_size) { + this.app_size = app_size; + } + + public int getSource() { + return source; + } + + public void setSource(int source) { + this.source = source; + } + + @NonNull + @Override + public String toString() { + return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); + } +} diff --git a/app/src/main/java/com/xwad/os/bean/IsActivationBean.java b/app/src/main/java/com/xwad/os/bean/IsActivationBean.java new file mode 100644 index 0000000..d5c6f82 --- /dev/null +++ b/app/src/main/java/com/xwad/os/bean/IsActivationBean.java @@ -0,0 +1,78 @@ +package com.xwad.os.bean; + +import java.io.Serializable; +import java.util.List; + +public class IsActivationBean implements Serializable { + private static final long serialVersionUID = 930211633376920464L; + + //是否激活 0否1是 + int is_activation; + // + String code; + //激活码类型 0体验卡 1正式 + int code_type; + //体验到期时间戳 单位秒 0代表没有时间限制 + long expire_time; + //激活时间 + long activation_time; + + List sn_package; + int sn_package_id; + + public int getIs_activation() { + return is_activation; + } + + public void setIs_activation(int is_activation) { + this.is_activation = is_activation; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public int getCode_type() { + return code_type; + } + + public void setCode_type(int code_type) { + this.code_type = code_type; + } + + public long getExpire_time() { + return expire_time; + } + + public void setExpire_time(long expire_time) { + this.expire_time = expire_time; + } + + public long getActivation_time() { + return activation_time; + } + + public void setActivation_time(long activation_time) { + this.activation_time = activation_time; + } + + public List getSn_package() { + return sn_package; + } + + public void setSn_package(List sn_package) { + this.sn_package = sn_package; + } + + public int getSn_package_id() { + return sn_package_id; + } + + public void setSn_package_id(int sn_package_id) { + this.sn_package_id = sn_package_id; + } +} diff --git a/app/src/main/java/com/xwad/os/bean/SnPackage.java b/app/src/main/java/com/xwad/os/bean/SnPackage.java new file mode 100644 index 0000000..fceaae1 --- /dev/null +++ b/app/src/main/java/com/xwad/os/bean/SnPackage.java @@ -0,0 +1,71 @@ +package com.xwad.os.bean; + +import java.io.Serializable; + +public class SnPackage implements Serializable { + private static final long serialVersionUID = -2350603364822310416L; + + int id; + String sn_id; + String sn; + String app_package; + String code; + String sn_package_app_id; + SnPackageApp sn_package_app; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getSn_id() { + return sn_id; + } + + public void setSn_id(String sn_id) { + this.sn_id = sn_id; + } + + public String getSn() { + return sn; + } + + public void setSn(String sn) { + this.sn = sn; + } + + public String getApp_package() { + return app_package; + } + + public void setApp_package(String app_package) { + this.app_package = app_package; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getSn_package_app_id() { + return sn_package_app_id; + } + + public void setSn_package_app_id(String sn_package_app_id) { + this.sn_package_app_id = sn_package_app_id; + } + + public SnPackageApp getSn_package_app() { + return sn_package_app; + } + + public void setSn_package_app(SnPackageApp sn_package_app) { + this.sn_package_app = sn_package_app; + } +} diff --git a/app/src/main/java/com/xwad/os/bean/SnPackageApp.java b/app/src/main/java/com/xwad/os/bean/SnPackageApp.java new file mode 100644 index 0000000..b2c9a2f --- /dev/null +++ b/app/src/main/java/com/xwad/os/bean/SnPackageApp.java @@ -0,0 +1,26 @@ +package com.xwad.os.bean; + +import java.io.Serializable; + +public class SnPackageApp implements Serializable { + private static final long serialVersionUID = 3704612310075489816L; + + int id; + String app_name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getApp_name() { + return app_name; + } + + public void setApp_name(String app_name) { + this.app_name = app_name; + } +} diff --git a/app/src/main/java/com/xwad/os/bean/TimeControl.java b/app/src/main/java/com/xwad/os/bean/TimeControl.java new file mode 100644 index 0000000..f318bb0 --- /dev/null +++ b/app/src/main/java/com/xwad/os/bean/TimeControl.java @@ -0,0 +1,53 @@ +package com.xwad.os.bean; + +import java.io.Serializable; + +public class TimeControl implements Serializable { + private static final long serialVersionUID = 8400702243953866327L; + + int id; + int user_id; + String sn; + String start_time; + String end_time; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getUser_id() { + return user_id; + } + + public void setUser_id(int user_id) { + this.user_id = user_id; + } + + public String getSn() { + return sn; + } + + public void setSn(String sn) { + this.sn = sn; + } + + public String getStart_time() { + return start_time; + } + + public void setStart_time(String start_time) { + this.start_time = start_time; + } + + public String getEnd_time() { + return end_time; + } + + public void setEnd_time(String end_time) { + this.end_time = end_time; + } +} diff --git a/app/src/main/java/com/xwad/os/bean/WhoisBean.java b/app/src/main/java/com/xwad/os/bean/WhoisBean.java new file mode 100644 index 0000000..016dd6e --- /dev/null +++ b/app/src/main/java/com/xwad/os/bean/WhoisBean.java @@ -0,0 +1,109 @@ +package com.xwad.os.bean; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; + +import java.io.Serializable; + +public class WhoisBean implements Serializable { + private static final long serialVersionUID = -6537021620041268080L; + + String ip; + String pro; + String proCode; + String city; + String cityCode; + String region; + String regionCode; + String addr; + String regionNames; + String err; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getPro() { + return pro; + } + + public void setPro(String pro) { + this.pro = pro; + } + + public String getProCode() { + return proCode; + } + + public void setProCode(String proCode) { + this.proCode = proCode; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCityCode() { + return cityCode; + } + + public void setCityCode(String cityCode) { + this.cityCode = cityCode; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getRegionCode() { + return regionCode; + } + + public void setRegionCode(String regionCode) { + this.regionCode = regionCode; + } + + public String getAddr() { + return addr; + } + + public void setAddr(String addr) { + this.addr = addr; + } + + public String getRegionNames() { + return regionNames; + } + + public void setRegionNames(String regionNames) { + this.regionNames = regionNames; + } + + public String getErr() { + return err; + } + + public void setErr(String err) { + this.err = err; + } + + @NonNull + @Override + public String toString() { + return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); + } +} diff --git a/app/src/main/java/com/xwad/os/config/CommonConfig.java b/app/src/main/java/com/xwad/os/config/CommonConfig.java index efb691d..715c9fd 100644 --- a/app/src/main/java/com/xwad/os/config/CommonConfig.java +++ b/app/src/main/java/com/xwad/os/config/CommonConfig.java @@ -5,6 +5,8 @@ public class CommonConfig { public static final String CLOUD_LESSON_SETTINGS_KEY = "cloud_lesson_settings_key"; + public static final String ALIYUN_PUSH_ID = "aliyun_push_id_key"; + @Deprecated public static final String isLogined = "isLogined"; public static final String AES_KEY = "xqdep8exnafpef3d"; @@ -12,6 +14,9 @@ public class CommonConfig { public static final String LOCK_SCREEN_PASSWORD ="Iflytek_lockScreenPasswordKey"; public static final String DEFAULT_PASSWORD = "666666"; + public static final String SCREEN_LOCK_PWD = "screen_lock_passwd"; + public static final String SUPER_PASSWORD = "0728"; + /*保存个人基本信息*/ /*性别*/ public static final String UIUI_USER_GENDER_KEY = "USER_INFO_GENDER"; @@ -42,6 +47,8 @@ public class CommonConfig { public static final String ACTIVATIONBEAN_CODE_KEY = "UIUI_ACTIVATIONBEAN_CODE"; public static final String INSTALL_SD_APKS = "install_sd_apks"; + /*是否显示通知栏,以及增强模式*/ + public static final String NOTIFY_BAR_SHOW_KEY = "is_notify_bar_show_key"; /*是否显示返回Android按钮*/ public static final String UIUI_RETURN_ANDROID_KEY = "iflytek_uiui_is_return_android"; @@ -53,8 +60,18 @@ public class CommonConfig { public static final String MAP_LONGITUDE_KEY = "map_longitude_key"; public static final String MAP_LATITUDE_KEY = "map_latitude_key"; public static final String MAP_ADDRESS_KEY = "map_address_key"; + public static final String MAP_PROVINCE_KEY = "map_province_key"; + public static final String MAP_CITY_KEY = "map_city_key"; + public static final String MAP_DISTRICT_KEY = "map_district_key"; + public static final String MAP_STREET_KEY = "map_street_key"; + public static final String MAP_LOCATION_DESCRIBE_KEY = "map_locationDescribe_key"; public static final String MAP_ERROR_KEY = "map_error_key"; + public static final String MAP_onLocationChanged_time_KEY = "map_onLocationChanged_time_key"; + + public static final String MAP_BEAN = "MapBean"; + + public static final String SETTING_OTHER_APPINSTALLER_KEY = "iflytek_setting_other_appInstaller"; /*应用市场的app列表*/ public final static String ADMIN_APP_LIST = "only_admin_app_list"; @@ -100,4 +117,32 @@ public class CommonConfig { public static final String NOTI_BAR_PERMANENT_ACTION = "notification_bar_permanent_action"; /*是否允许通知*/ public static final String ALLOW_NOTIFICATION = "allow_notification"; + + /*默认桌面key*/ + public final static String DESKTOP_APP_KEY = "desktop_app_key"; + public final static String BROWSER_APP_KEY = "browser_app_key"; + public final static String TYPEWRITING_APP_KEY = "typewriting_app_key"; + + /** + * 管控系统指令 + */ + + /*USB模式-充电*/ + public final static String AOLE_ACTION_USB_USB_CHARGE = "aole_action_usb_usb_charge"; + /*USB模式-MTP*/ + public final static String AOLE_ACTION_USB_USB_MTP = "aole_action_usb_usb_mtp"; + /*USB模式-MIDI*/ + public final static String AOLE_ACTION_USB_USB_MIDI = "aole_action_usb_usb_midi"; + + /*应用安装白名单总开关*/ + public final static String AOLE_APP_ALLOW_INSTALL = "aole_app_allow_install"; + /*应用安装白名单*/ + public final static String AOLE_ACTION_APP_FORBID = "aole_app_forbid"; + /*强制安装应用,禁止卸载*/ + public final static String AOLE_ACTION_FORCE_APP = "aole_force_app"; + + /*应用ID管控*/ + public final static String AOLE_ACTION_APP_FORBID_ID = "aole_app_forbid_id"; + /*应用ID管控*/ + public final static String AOLE_ACTION_APP_FORBID_ARRAY = "DeselectViewArray"; } diff --git a/app/src/main/java/com/xwad/os/dialog/UserDebugDialog.java b/app/src/main/java/com/xwad/os/dialog/UserDebugDialog.java new file mode 100644 index 0000000..e3a606f --- /dev/null +++ b/app/src/main/java/com/xwad/os/dialog/UserDebugDialog.java @@ -0,0 +1,248 @@ +package com.xwad.os.dialog; + +import android.app.AlertDialog; +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.TextView; + +import com.xwad.os.R; + + +/** + * description:自定义dialog + */ + +public class UserDebugDialog extends AlertDialog { + + /** + * 显示的标题 + */ + private TextView titleTv; + + /** + * 确认和取消按钮 + */ + private TextView negtiveBn, positiveBn; + + private EditText editText; + + + private Context mContext; + + public UserDebugDialog(Context context) { + super(context, R.style.UserDebugDialog); + this.mContext = context; + } + + /** + * 都是内容数据 + */ + private String message; + private String title; + private String positive, negtive; + private int imageResId = -1; + + /** + * 底部是否只有一个按钮 + */ + private boolean isSingle = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_userdebug); + //按空白处不能取消动画 +// setCanceledOnTouchOutside(false); + //初始化界面控件 + initView(); + //初始化界面数据 + refreshView(); + //初始化界面控件的事件 + initEvent(); + } + + /** + * 初始化界面的确定和取消监听器 + */ + private void initEvent() { + //设置确定按钮被点击后,向外界提供监听 + positiveBn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onClickBottomListener != null) { + onClickBottomListener.onPositiveClick(); + } + } + }); + //设置取消按钮被点击后,向外界提供监听 + negtiveBn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onClickBottomListener != null) { + onClickBottomListener.onNegtiveClick(); + } + } + }); + } + + /** + * 初始化界面控件的显示数据 + */ + private void refreshView() { + //如果用户自定了title和message +// if (!TextUtils.isEmpty(title)) { +// titleTv.setText(title); +// titleTv.setVisibility(View.VISIBLE); +// } else { +// titleTv.setVisibility(View.GONE); +// } + //如果设置按钮的文字 + if (!TextUtils.isEmpty(positive)) { + positiveBn.setText(positive); + } else { + positiveBn.setText("确定"); + } + if (!TextUtils.isEmpty(negtive)) { + negtiveBn.setText(negtive); + } else { + negtiveBn.setText("取消"); + } + + /** + * 只显示一个按钮的时候隐藏取消按钮,回掉只执行确定的事件 + */ + if (isSingle) { + negtiveBn.setVisibility(View.GONE); + } else { + negtiveBn.setVisibility(View.VISIBLE); + } + } + + @Override + public void show() { + super.show(); + refreshView(); + } + + /** + * 初始化界面控件 + */ + private void initView() { + negtiveBn = findViewById(R.id.bt_cancel); + positiveBn = findViewById(R.id.bt_confirm); + titleTv = findViewById(R.id.tv_title); + editText = findViewById(R.id.editText); + } + + /** + * 设置确定取消按钮的回调 + */ + private OnClickBottomListener onClickBottomListener; + + public void setOnClickBottomListener(OnClickBottomListener onClickBottomListener) { + this.onClickBottomListener = onClickBottomListener; + } + + public interface OnClickBottomListener { + /** + * 点击确定按钮事件 + */ + void onPositiveClick(); + + /** + * 点击取消按钮事件 + */ + void onNegtiveClick(); + } + + public String getMessage() { + return message; + } + + public UserDebugDialog setMessage(String message) { + this.message = message; + return this; + } + + public String getTitle() { + return title; + } + + public UserDebugDialog setTitle(String title) { + this.title = title; + return this; + } + + public String getPositive() { + return positive; + } + + public UserDebugDialog setPositive(String positive) { + this.positive = positive; + return this; + } + + public String getNegtive() { + return negtive; + } + + public UserDebugDialog setNegtive(String negtive) { + this.negtive = negtive; + return this; + } + + public UserDebugDialog setNegtiveText(String negtive) { + negtiveBn.setText(negtive); + return this; + } + + public int getImageResId() { + return imageResId; + } + + public boolean isSingle() { + return isSingle; + } + + public UserDebugDialog setSingle(boolean single) { + isSingle = single; + return this; + } + + public UserDebugDialog setImageResId(int imageResId) { + this.imageResId = imageResId; + return this; + } + + public void showKeyboard() { + if (editText != null) { + //设置可获得焦点 + editText.setFocusable(true); + editText.setFocusableInTouchMode(true); + //请求获得焦点 + editText.requestFocus(); + //调用系统输入法 + InputMethodManager inputManager = (InputMethodManager) editText + .getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + inputManager.showSoftInput(editText, 0); + } + } + + @Override + public void dismiss() { + super.dismiss(); + + } + + public String getEdittext() { + if (!TextUtils.isEmpty(editText.getText().toString())) { + return editText.getText().toString().trim(); + } else { + return ""; + } + } +} diff --git a/app/src/main/java/com/xwad/os/eula/EulaDialog.java b/app/src/main/java/com/xwad/os/eula/EulaDialog.java new file mode 100644 index 0000000..35b6287 --- /dev/null +++ b/app/src/main/java/com/xwad/os/eula/EulaDialog.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) Honor Technologies Co., Ltd. 2019-2020. All rights reserved. + */ + +package com.xwad.os.eula; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.admin.DevicePolicyManager; +import android.content.ComponentName; +import android.content.Intent; +import android.graphics.Color; +import android.text.Html; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.URLSpan; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.xwad.os.R; +import com.xwad.os.base.BaseAlertDialogBuilder; + + +/** + * The EulaDialog for this Sample + * + * @author honor mdm + * @since 2019-10-23 + */ +public class EulaDialog { + private static final int REQUEST_ENABLE = 1; + private static final String PERMISSION_STATEMENT_FILE = "honor_permission_statement.html"; + + private Activity mActivity = null; + private DevicePolicyManager mDevicePolicyManager = null; + private ComponentName mAdminName = null; + private boolean hasUserAccepted = false; + private boolean onlyShowOnce = false; + private AlertDialog eulaDialog; + private EulaCallback mEulaCallback; + + public EulaDialog(Activity context, DevicePolicyManager devicePolicyManager, ComponentName adminName, EulaCallback callback) { + mActivity = context; + mDevicePolicyManager = devicePolicyManager; + mAdminName = adminName; + mEulaCallback = callback; + } + + public interface EulaCallback { + void onGranted(); + + void onDenied(); + } + + /** + * Show permission usage statement + */ + @SuppressLint("InflateParams") + public void show() { + EulaUtils eulaUtils = new EulaUtils(); + hasUserAccepted = eulaUtils.hasUserAccepted(); + if (!hasUserAccepted) { + /* Show the Eula */ + if (eulaDialog == null) { + BaseAlertDialogBuilder builder = new BaseAlertDialogBuilder(mActivity); + builder.setPositiveButton(mActivity.getString(R.string.accept_btn), + (dialog, which) -> { + eulaUtils.saveUserOnlyShowOnce(onlyShowOnce); + eulaUtils.saveUserChoice(true); + dialog.dismiss(); + mEulaCallback.onGranted(); + }); + builder.setNegativeButton(mActivity.getString(R.string.exit_btn), + (dialog, which) -> { + mEulaCallback.onDenied(); + mActivity.finish(); + }); + eulaDialog = builder.create(); + builder.setCancelable(false); + LayoutInflater inflater = LayoutInflater.from(mActivity); + View layout = inflater.inflate(R.layout.eula_layout, null); + TextView permissionText = layout.findViewById(R.id.content_permissions); + String content = Utils.getStringFromHtmlFile(mActivity, PERMISSION_STATEMENT_FILE); + permissionText.setText(Html.fromHtml(content)); + + initStatementView(layout); + + CheckBox checkbox = layout.findViewById(R.id.not_show_check); + checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> { + onlyShowOnce = isChecked; + }); + eulaDialog.setView(layout); + eulaDialog.show(); + eulaDialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + } + } else { + mEulaCallback.onGranted(); + } + } + + private void initStatementView(View layout) { + if (layout == null) { + return; + } + TextView statementText = layout.findViewById(R.id.read_statement); + statementText.setMovementMethod(LinkMovementMethod.getInstance()); + CharSequence text = statementText.getText(); + if (text instanceof Spannable) { + int end = text.length(); + Spannable sp = (Spannable) text; + URLSpan[] urls = sp.getSpans(0, end, URLSpan.class); + SpannableStringBuilder style = new SpannableStringBuilder(text); + style.clearSpans(); // should clear old spans + for (URLSpan url : urls) { + MyURLSpan myURLSpan = new MyURLSpan(); + style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spanned.SPAN_EXCLUSIVE_INCLUSIVE); + } + statementText.setText(style); + } + } + + private class MyURLSpan extends ClickableSpan { + @Override + public void onClick(View widget) { + widget.setBackgroundColor(Color.parseColor("#00000000")); + + Intent intent = new Intent(mActivity, LicenseActivity.class); + mActivity.startActivity(intent); + } + } + + private void activeProcess() { +// if (mDevicePolicyManager != null +// && !mDevicePolicyManager.isAdminActive(mAdminName)) { +// Intent intent = new Intent(mActivity, SplashActivity.class); +// mActivity.startActivityForResult(intent, REQUEST_ENABLE); +// } + + } + + +} diff --git a/app/src/main/java/com/xwad/os/eula/EulaUtils.java b/app/src/main/java/com/xwad/os/eula/EulaUtils.java new file mode 100644 index 0000000..0c15d4e --- /dev/null +++ b/app/src/main/java/com/xwad/os/eula/EulaUtils.java @@ -0,0 +1,63 @@ +package com.xwad.os.eula; + +import com.tencent.mmkv.MMKV; + +/** + * 只要当用户选中“不再提醒”,同时点击“同意”后,此对话框就不用再显示;但是如果应用有了重大功能更新(开发者自行判断),此对话框还要再次弹出。 + */ +public class EulaUtils { + private static final String TAG = "EulaUtils"; + + /*重大功能更新版本号*/ + private static final int DEFAULT_VERSION_CODE = 1; + private static final String MMKV_EULA_ID = "eula"; + private static final String EULA_PREFIX = "eula_useraccepted_"; + private static final String ONLY_SHOW_ONCE_KEY = "eula_useraccepted_onlyShowOnce"; + private int mVersionCode; + + private String mEulaKey; + + private MMKV mMMKV = MMKV.mmkvWithID(MMKV_EULA_ID, MMKV.MULTI_PROCESS_MODE); + + public EulaUtils() { +// mVersionCode = getVersionCodeInner(); + mVersionCode = DEFAULT_VERSION_CODE; + mEulaKey = EULA_PREFIX + mVersionCode; + } + + public void saveUserOnlyShowOnce(boolean onlyShowOnce) { + mMMKV.encode(mEulaKey, onlyShowOnce); + } + + /** + * Whether the user select not show again + * + * @return boolean true if selected otherwise false. + */ + public boolean hasUserAccepted() { + if (mMMKV.decodeBool(ONLY_SHOW_ONCE_KEY, false)) { + return true; + } else { + return mMMKV.decodeBool(mEulaKey, false); + } + } + + /** + * Save user's choice to SharedPreferences. + * + * @param accepted Whether the user select not show again. + */ + public void saveUserChoice(boolean accepted) { + mMMKV.encode(mEulaKey, accepted); + } + +// private int getVersionCodeInner() { +// PackageInfo pi = null; +// try { +// pi = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES); +// } catch (PackageManager.NameNotFoundException e) { +// Log.e(TAG, "Name not found exception"); +// } +// return pi == null ? DEFAULT_VERSION_CODE : pi.versionCode; +// } +} diff --git a/app/src/main/java/com/xwad/os/eula/LicenseActivity.java b/app/src/main/java/com/xwad/os/eula/LicenseActivity.java new file mode 100644 index 0000000..9b7b93b --- /dev/null +++ b/app/src/main/java/com/xwad/os/eula/LicenseActivity.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) Honor Technologies Co., Ltd. 2019-2020. All rights reserved. + */ + +package com.xwad.os.eula; + +import android.app.Activity; +import android.os.Bundle; +import android.text.Html; +import android.view.Window; +import android.widget.Button; +import android.widget.TextView; + +import com.xwad.os.R; + +/** + * The LicenseActivity for this Sample + * + * @author honor mdm + * @since 2019-10-23 + */ +public class LicenseActivity extends Activity { + private static final String LICENSE_FILE = "honor_software_license.html"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + setContentView(R.layout.license_layout); + Button acceptBtn = findViewById(R.id.cancelBtn); + acceptBtn.setOnClickListener(view -> finish()); + TextView licenseText = findViewById(R.id.license_content); + String content = Utils.getStringFromHtmlFile(this, LICENSE_FILE); + licenseText.setText(Html.fromHtml(content)); + } +} diff --git a/app/src/main/java/com/xwad/os/eula/Utils.java b/app/src/main/java/com/xwad/os/eula/Utils.java new file mode 100644 index 0000000..1eb25b4 --- /dev/null +++ b/app/src/main/java/com/xwad/os/eula/Utils.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) Honor Technologies Co., Ltd. 2019-2020. All rights reserved. + */ + +package com.xwad.os.eula; + +import android.content.Context; +import android.util.Log; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * The Utils for this Sample + * + * @author honor mdm + * @since 2019-10-23 + */ +public class Utils { + private static final String TAG = "SampleUtils"; + private static final int EXPECTED_BUFFER_DATA = 2048; + private static final int MAX_LENGTH = 1024; + private static final int MAX_LINE_LENGTH = 128; + + /** + * Get help string from html file + * + * @param context Context object + * @param filePath html file path + * @return string in html + */ + public static String getStringFromHtmlFile(Context context, String filePath) { + String result = ""; + if (context == null || filePath == null) { + return result; + } + try (InputStreamReader streamReader = + new InputStreamReader(context.getAssets().open(filePath), "utf-8"); + BufferedReader reader = new BufferedReader(streamReader)) { + StringBuilder builder = new StringBuilder(EXPECTED_BUFFER_DATA); + String line = null; + + boolean readCurrentLine = true; + + // Read each line of the html file, and build a string. + while ((line = reader.readLine()) != null && line.length() < MAX_LINE_LENGTH) { + // Don't read the Head tags when CSS styling is not supporeted. + if (line.contains(" { + private static final String TAG = "AppViewModel"; + @Override public FragmentAppBinding getVDBinding() { return binding; @@ -33,15 +44,15 @@ public class AppViewModel extends BaseViewModel desktopIcons = AppManager.getInstance().getFilterAppList(); // DesktopIcon appstoreDesktopIcon = new DesktopIcon(); -// appstoreDesktopIcon.setLable(ApkUtils.getAppName(getCtx(), "com.uiui.zyappstore")); +// appstoreDesktopIcon.setLable(ApkUtils.getAppName(BaseApplication.getInstance(), "com.uiui.zyappstore")); // appstoreDesktopIcon.setPackageName(AppManager.APPSTORE_PACKAGE_NAME); // appstoreDesktopIcon.setClassName(AppManager.APPSTORE_CLASS_NAME); // appstoreDesktopIcon.setLable("应用市场"); // Drawable appstoreDrawable; -// if (ApkUtils.isAvailable(getCtx(), AppManager.APPSTORE_PACKAGE_NAME)) { -// appstoreDrawable = ApkUtils.getAppDrawable(getCtx(), "com.uiui.zyappstore"); +// if (ApkUtils.isAvailable(BaseApplication.getInstance(), AppManager.APPSTORE_PACKAGE_NAME)) { +// appstoreDrawable = ApkUtils.getAppDrawable(BaseApplication.getInstance(), "com.uiui.zyappstore"); // } else { -// appstoreDrawable = getCtx().getDrawable(R.drawable.com_android_appstore); +// appstoreDrawable = BaseApplication.getInstance().getDrawable(R.drawable.com_android_appstore); // } // appstoreDesktopIcon.setIcon(appstoreDrawable); // desktopIcons.add(desktopIcons.size(), appstoreDesktopIcon); @@ -49,47 +60,47 @@ public class AppViewModel extends BaseViewModel>() { + @Override + public ArrayList call() throws Exception { + ArrayList desktopIcons = AppManager.getInstance().getFilterAppList(); + +// DesktopIcon appstoreDesktopIcon = new DesktopIcon(); +// appstoreDesktopIcon.setLable(ApkUtils.getAppName(BaseApplication.getInstance(), "com.uiui.zyappstore")); +// appstoreDesktopIcon.setPackageName(AppManager.APPSTORE_PACKAGE_NAME); +// appstoreDesktopIcon.setClassName(AppManager.APPSTORE_CLASS_NAME); +// appstoreDesktopIcon.setLable("应用市场"); +// Drawable appstoreDrawable; +// if (ApkUtils.isAvailable(BaseApplication.getInstance(), AppManager.APPSTORE_PACKAGE_NAME)) { +// appstoreDrawable = ApkUtils.getAppDrawable(BaseApplication.getInstance(), "com.uiui.zyappstore"); +// } else { +// appstoreDrawable = BaseApplication.getInstance().getDrawable(R.drawable.com_android_appstore); +// } +// appstoreDesktopIcon.setIcon(appstoreDrawable); +// desktopIcons.add(desktopIcons.size(), appstoreDesktopIcon); + +// DesktopIcon updateDesktopIcon = new DesktopIcon(); +// updateDesktopIcon.setLable("应用更新"); +// updateDesktopIcon.setPackageName(AppManager.UPDATE_NAME); +// updateDesktopIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.icon_update)); +// desktopIcons.add(desktopIcons.size(), updateDesktopIcon); + +// DesktopIcon manualIcon = new DesktopIcon(); +// manualIcon.setLable("使用手册"); +// manualIcon.setPackageName(AppManager.MANUAL_NAME); +// manualIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.icon_manual)); +// desktopIcons.add(desktopIcons.size(), manualIcon); + +// DesktopIcon browserIcon = new DesktopIcon(); +// browserIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.uiui_zybrowser)); +// browserIcon.setLable("浏览器"); +// browserIcon.setPackageName(AppManager.BROWSER_PACKAGE_NAME); +// browserIcon.setClassName(AppManager.BROWSER_CLASS_NAME); +// desktopIcons.add(browserIcon); + +// DesktopIcon serviceIcon = new DesktopIcon(); +// serviceIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.service_icon)); +// serviceIcon.setLable("联系客服"); +// serviceIcon.setPackageName(AppManager.SERVICE_NAME); +// desktopIcons.add(serviceIcon); + +// if (ApkUtils.isAvailable(BaseApplication.getInstance(), "com.jxw.zwpg")) { +// DesktopIcon zwpgIcon = new DesktopIcon(); +// zwpgIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.zwpg_icon)); +// zwpgIcon.setLable("作文批改"); +// zwpgIcon.setPackageName("com.jxw.zwpg"); +// desktopIcons.add(zwpgIcon); +// } + +// if (ApkUtils.isAvailable(BaseApplication.getInstance(), "com.jxw.gb.zwpg")) { +// DesktopIcon zwpgIcon = new DesktopIcon(); +// zwpgIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.zwpg_icon)); +// zwpgIcon.setLable("作文批改"); +// zwpgIcon.setPackageName("com.jxw.gb.zwpg"); +// desktopIcons.add(zwpgIcon); +// } + +// if (ApkUtils.isAvailable(BaseApplication.getInstance(), "com.jxw.huiben")) { +// DesktopIcon zwpgIcon = new DesktopIcon(); +// zwpgIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.zhidu_icon)); +// zwpgIcon.setLable("AR指读"); +// zwpgIcon.setPackageName("com.jxw.huiben"); +// desktopIcons.add(zwpgIcon); +// } + +// DesktopIcon exitIcon = new DesktopIcon(); +// exitIcon.setLable("退出桌面"); +// exitIcon.setPackageName(AppManager.DESKTOP_EXIT); +// exitIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.exit_icon)); +// desktopIcons.add(desktopIcons.size(), exitIcon); + + DesktopIcon homeworkDesktopIcon = new DesktopIcon(); + homeworkDesktopIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.icon_homework)); + homeworkDesktopIcon.setLable("作业"); + homeworkDesktopIcon.setPackageName(AppManager.APP_HOMEWORK); + desktopIcons.add(homeworkDesktopIcon); + + DesktopIcon clockIcon = new DesktopIcon(); + clockIcon.setLable("时钟"); + clockIcon.setPackageName(OpenApkUtils.getInstance().getDeskClockPackageName()); + //使用getCtx()会报错 + clockIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.com_android_deskclock)); + desktopIcons.add(clockIcon); + + DesktopIcon calcIcon = new DesktopIcon(); + calcIcon.setLable("计算器"); + calcIcon.setPackageName(OpenApkUtils.getInstance().getCalculatorPackageName()); + calcIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.com_android_calculator2)); + desktopIcons.add(calcIcon); + + DesktopIcon cameraIcon = new DesktopIcon(); + cameraIcon.setLable("相机"); + cameraIcon.setPackageName(OpenApkUtils.getInstance().getCameraPackageName()); + cameraIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.com_android_camera)); + desktopIcons.add(cameraIcon); + + DesktopIcon galleryIcon = new DesktopIcon(); + galleryIcon.setLable("图库"); + galleryIcon.setPackageName(OpenApkUtils.getInstance().getGalleryPackageName()); + galleryIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.com_android_gallery3d_app)); + desktopIcons.add(galleryIcon); + + DesktopIcon AiAppIcon = new DesktopIcon(); + AiAppIcon.setLable("AI答疑(测试)"); + AiAppIcon.setPackageName("com.jxw.aizndy"); + AiAppIcon.setClassName("com.jxw.aizndy.ui.activity.MainCameraActivity"); + AiAppIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.icon_jxw_aizndy)); + desktopIcons.add(desktopIcons.size(), AiAppIcon); + + DesktopIcon AddAppIcon = new DesktopIcon(); + AddAppIcon.setLable("添加应用"); + AddAppIcon.setPackageName(AppManager.ADD_NAME); + AddAppIcon.setIcon(BaseApplication.getInstance().getDrawable(R.drawable.icon_add)); + desktopIcons.add(desktopIcons.size(), AddAppIcon); + + return desktopIcons; + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + + } + + @Override + public void onNext(@NonNull ArrayList desktopIcons) { + Log.e("getInstalledApp", "onNext: " + desktopIcons); + mDesktopIconListData.postValue(desktopIcons); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getInstalledApp", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + + } + }); + } } diff --git a/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java b/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java index 688408a..70a6f88 100644 --- a/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java +++ b/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java @@ -12,10 +12,10 @@ import android.view.View; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; +import com.hjq.toast.Toaster; import com.tencent.mmkv.MMKV; import com.xwad.os.R; import com.xwad.os.activity.ExitActivity; -import com.xwad.os.activity.login.result.LoginSuccessfulActivity; import com.xwad.os.activity.user.UserActivity; import com.xwad.os.base.mvvm.fragment.BaseMvvmFragment; import com.xwad.os.bean.UserAvatarInfo; @@ -24,7 +24,6 @@ import com.xwad.os.databinding.FragmentMineBinding; import com.xwad.os.jxw.StudyRecordMng; import com.xwad.os.jxw.ToastUtil; import com.xwad.os.jxw.event.UpdateColorEvent; -import com.xwad.os.service.main.MainService; import com.xwad.os.utils.OpenApkUtils; import com.xwad.os.view.jxw.view.dialog.QhbzDialog; import com.xwad.os.view.jxw.widget.DefaultAppsDialog; @@ -43,7 +42,7 @@ import java.io.IOException; * create an instance of this fragment. */ public class MineFragment extends BaseMvvmFragment { - private static final String TAG = "PrecisionFragment"; + private static final String TAG = "MineFragment"; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); private Activity mContext; @@ -356,7 +355,12 @@ public class MineFragment extends BaseMvvmFragment mQrCodeData = new MutableLiveData<>(); public void getQrCode() { - String encryptString = CXAESUtil.encrypt(CommonConfig.AES_KEY, DeviceSNManager.getDeviceSN()); + String encryptString = CXAESUtil.encrypt(CommonConfig.AES_KEY, AdminManager.getInstance().getSerial()); Log.e("getQRCode", "setImageAndText: " + encryptString); Bitmap bitmap = Utils.createQRImage(encryptString, 400, 400); mQrCodeData.setValue(bitmap); diff --git a/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceFragment.java b/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceFragment.java index 95ee0d0..e89b46c 100644 --- a/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceFragment.java +++ b/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceFragment.java @@ -15,9 +15,11 @@ import com.xwad.os.activity.permission.PermissionActivity; import com.xwad.os.activity.service.ServiceActivity; import com.xwad.os.activity.update.UpdateActivity; import com.xwad.os.base.mvvm.fragment.BaseMvvmFragment; +import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.AppUpdateInfo; import com.xwad.os.databinding.FragmentDeviceBinding; import com.xwad.os.manager.DeviceSNManager; +import com.xwad.os.mdm.AdminManager; import com.xwad.os.utils.ApkUtils; public class DeviceFragment extends BaseMvvmFragment { @@ -46,14 +48,14 @@ public class DeviceFragment extends BaseMvvmFragment() { + mViewModel.mAppUpdateInfoData.observe(this, new Observer() { @Override - public void onChanged(AppUpdateInfo appUpdateInfo) { + public void onChanged(AppInfo appUpdateInfo) { if (appUpdateInfo == null) { Toaster.show("已是最新版本"); } else { diff --git a/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceViewModel.java b/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceViewModel.java index 76bceee..c6501b8 100644 --- a/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceViewModel.java +++ b/app/src/main/java/com/xwad/os/fragment/usercenter/device/DeviceViewModel.java @@ -10,6 +10,7 @@ import com.trello.rxlifecycle4.android.ActivityEvent; import com.trello.rxlifecycle4.android.FragmentEvent; import com.xwad.os.BuildConfig; import com.xwad.os.base.mvvm.BaseViewModel; +import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.AppUpdateInfo; import com.xwad.os.bean.BaseResponse; import com.xwad.os.databinding.FragmentDeviceBinding; @@ -31,22 +32,22 @@ public class DeviceViewModel extends BaseViewModel mAppUpdateInfoData = new MutableLiveData<>(); + public MutableLiveData mAppUpdateInfoData = new MutableLiveData<>(); public void checkUpdate() { - NetInterfaceManager.getInstance().getCheckUpdateObservable(BuildConfig.APPLICATION_ID) + NetInterfaceManager.getInstance().getUpdateObservable(BuildConfig.APPLICATION_ID) .compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY)) - .subscribe(new Observer>() { + .subscribe(new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { Log.e("checkUpdate", "onSubscribe: "); } @Override - public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { + public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); if (appUpdateInfoBaseResponse.code == 200) { - AppUpdateInfo appUpdateInfo = appUpdateInfoBaseResponse.data; + AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; mAppUpdateInfoData.setValue(appUpdateInfo); } else { mAppUpdateInfoData.setValue(null); @@ -55,8 +56,8 @@ public class DeviceViewModel extends BaseViewModel params = new HashMap<>(); - params.put("sn", DeviceSNManager.getDeviceSN()); + params.put("sn", AdminManager.getInstance().getSerial()); params.put("sex", "1"); mViewModel.updateInfo(params); } else { @@ -77,7 +78,7 @@ public class InfoFragment extends BaseMvvmFragment params = new HashMap<>(); - params.put("sn", DeviceSNManager.getDeviceSN()); + params.put("sn", AdminManager.getInstance().getSerial()); params.put("sex", "2"); mViewModel.updateInfo(params); } else { diff --git a/app/src/main/java/com/xwad/os/jxw/base/BaseActivity.java b/app/src/main/java/com/xwad/os/jxw/base/BaseActivity.java new file mode 100644 index 0000000..a825da6 --- /dev/null +++ b/app/src/main/java/com/xwad/os/jxw/base/BaseActivity.java @@ -0,0 +1,110 @@ +package com.xwad.os.jxw.base; + +//import android.content.Intent; +//import android.os.Build; +//import android.os.Bundle; +//import android.os.Handler; +//import android.os.Looper; +//import android.os.Message; +//import android.view.View; +//import android.view.Window; +//import androidx.fragment.app.FragmentActivity; +//import com.jxw.launcher.netInterface.NetConnectionObserver; +// +//public class BaseActivity extends FragmentActivity implements NetConnectionObserver { +// Handler handler = new Handler(Looper.getMainLooper()) { +// @Override +// public void handleMessage(Message message) { +// super.handleMessage(message); +// BaseActivity.this.startMediaService(); +// } +// }; +// private Handler mRestoreImmersiveModeHandler = new Handler(); +// private Runnable restoreImmersiveModeRunnable = new Runnable() { +// @Override +// public void run() { +// BaseActivity.this.restoreTransparentBars(); +// } +// }; +// +// public void restoreTransparentBars() { +// } +// +// public void onNetworkChanged(boolean z) { +// } +// +// @Override +// public void onCreate(Bundle bundle) { +// super.onCreate(bundle); +// requestWindowFeature(1); +// View decorView = getWindow().getDecorView(); +// if (Build.VERSION.SDK_INT >= 21) { +// Window window = getWindow(); +// window.clearFlags(201326592); +// window.getDecorView().setSystemUiVisibility(1792); +// window.addFlags(Integer.MIN_VALUE); +// window.setStatusBarColor(0); +// window.setNavigationBarColor(0); +// } else if (Build.VERSION.SDK_INT >= 19) { +// getWindow().addFlags(67108864); +// getWindow().addFlags(134217728); +// } +// decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { +// @Override +// public void onSystemUiVisibilityChange(int i) { +// BaseActivity.this.restoreTransparentBars(); +// } +// }); +// decorView.setOnFocusChangeListener(new View.OnFocusChangeListener() { +// @Override +// public void onFocusChange(View view, boolean z) { +// BaseActivity.this.restoreTransparentBars(); +// } +// }); +// this.handler.sendEmptyMessageDelayed(1, 3000L); +// } +// +// @Override +// public void onPause() { +// super.onPause(); +// MyApp.getInstance().removeNetObserver(this); +// } +// +// @Override +// public void onResume() { +// restoreTranslucentBarsDelayed(); +// MyApp.getInstance().mBottomBtnOnClickListener.setContext(this); +// super.onResume(); +// MyApp.getInstance().addNetObserver(this); +// } +// +// @Override +// public void onWindowFocusChanged(boolean z) { +// super.onWindowFocusChanged(z); +// restoreTranslucentBarsDelayed(); +// } +// +// public void restoreTranslucentBarsDelayed() { +// restoreTransparentBars(); +// this.mRestoreImmersiveModeHandler.postDelayed(this.restoreImmersiveModeRunnable, 500L); +// } +// +// public void startMediaService() { +// try { +// Intent intent = new Intent(); +// intent.setClassName("com.jxw.launcher", "com.jxw.system.mediaserver.JhtMediaService"); +// if (Build.VERSION.SDK_INT >= 26) { +// startForegroundService(intent); +// } else { +// startService(intent); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// @Override +// public void updateNetStatus(int i) { +// onNetworkChanged(MyApp.getInstance().isNetConnection()); +// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/xwad/os/jxw/base/BaseNewThemeActivity.java b/app/src/main/java/com/xwad/os/jxw/base/BaseNewThemeActivity.java new file mode 100644 index 0000000..ddefa1a --- /dev/null +++ b/app/src/main/java/com/xwad/os/jxw/base/BaseNewThemeActivity.java @@ -0,0 +1,207 @@ +package com.xwad.os.jxw.base; + +//import android.content.SharedPreferences; +//import android.content.pm.PackageManager; +//import android.os.Bundle; +//import android.text.TextUtils; +//import android.util.Log; +//import com.google.gson.Gson; +//import com.jxw.api.RegisterApi; +//import com.jxw.api.util.SPUtils; +//import com.jxw.constant.Constant; +//import com.jxw.httputil.OkhtttpUtils; +//import com.jxw.launcher.view.dialog.DialogUpdate; +//import com.jxw.update.Otabean; +//import com.jxw.utils.AppUtil; +//import java.io.IOException; +//import java.util.ArrayList; +//import java.util.List; +//import okhttp3.Call; +//import okhttp3.Callback; +//import okhttp3.OkHttpClient; +//import okhttp3.Request; +//import okhttp3.Response; +//import org.json.JSONArray; +//import org.json.JSONException; +//import org.json.JSONObject; +// +//public abstract class BaseNewThemeActivity extends BaseThemeActivity { +// public static List packages = new ArrayList(); +// +// @Override +// public void onCreate(Bundle bundle) { +// super.onCreate(bundle); +// getPackageList(); +// } +// +// @Override +// public void onDestroy() { +// super.onDestroy(); +// } +// +// @Override +// public void onResume() { +// super.onResume(); +// } +// +// @Override +// protected void onPause() { +// super.onPause(); +// } +// +// private void basecheckUpdate() { +// String deviceSerial; +// SharedPreferences sharedPreferences = getSharedPreferences(Constant.PREFERENCE, 0); +// if (!TextUtils.isEmpty(sharedPreferences.getString("series", ""))) { +// deviceSerial = sharedPreferences.getString("series", ""); +// } else { +// deviceSerial = RegisterApi.getInstance().getDeviceSerial(); +// if ("unknown".equals(deviceSerial) || TextUtils.isEmpty(deviceSerial)) { +// deviceSerial = RegisterApi.getInstance().getDeviceSerialx(); +// } +// } +// new OkHttpClient().newCall(new Request.Builder().url(Constant.PLATFORM_URL_HEADER + "/api/jxwota/apk/checkBySn?apkIsbn=znpbxgbv6&series=" + deviceSerial + "&deviceType=OTHER").build()).enqueue(new Callback() { +// @Override +// public void onFailure(Call call, IOException iOException) { +// Log.d("zzj", "onFailure=" + iOException.getMessage()); +// } +// +// @Override +// public void onResponse(Call call, Response response) throws IOException { +// BaseNewThemeActivity.this.getOtaData(response); +// } +// }); +// } +// +// public synchronized void getOtaData(Response response) throws IOException { +// Log.d("zzj", "onResponse=" + response); +// if (response.isSuccessful()) { +// String string = response.body().string(); +// PackageManager packageManager = MyApp.getInstance().getPackageManager(); +// Log.d("zzj", "获取数据成功了:" + string); +// try { +// JSONArray jSONArray = new JSONObject(string).getJSONArray("data"); +// packages.clear(); +// final int i = 0; +// for (int i2 = 0; i2 < jSONArray.length(); i2++) { +// JSONObject optJSONObject = jSONArray.optJSONObject(i2); +// int optInt = optJSONObject.optInt("versionCode"); +// String optString = optJSONObject.optString("packageName"); +// String optString2 = optJSONObject.optString("forceUpdate"); +// try { +// if (optInt > packageManager.getPackageInfo(optString, 0).versionCode) { +// i++; +// if (optString2.equals("1")) { +// packages.add(optString); +// } +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// runOnUiThread(new Runnable() { +// @Override +// public void run() { +// if (i > 0) { +// BaseNewThemeActivity baseNewThemeActivity = BaseNewThemeActivity.this; +// new DialogUpdate(baseNewThemeActivity, "" + i).show(); +// } +// } +// }); +// } catch (JSONException e2) { +// e2.printStackTrace(); +// } +// } +// } +// +// private void getPackageList() { +// OkhtttpUtils.getInstance().doGet(this, Constant.PLATFORM_URL_HEADER + "/api/jxwota/apk/sign/packageList?apkIsbn=znpbxgbv6", false, new OkhtttpUtils.OkCallback() { +// @Override +// public void onResponse(String str) { +// Log.e("zsj", str); +// try { +// JSONObject jSONObject = new JSONObject(str); +// if ("0".equals(jSONObject.optString("code"))) { +// JSONArray jSONArray = jSONObject.getJSONArray("data"); +// ArrayList arrayList = new ArrayList(); +// for (int i = 0; i < jSONArray.length(); i++) { +// Otabean otabean = new Otabean(); +// otabean.setPackageName(jSONArray.getString(i)); +// otabean.setSign(AppUtil.getApplicationPackage(BaseNewThemeActivity.this, jSONArray.getString(i))); +// Log.e("BaseNewThemeActivity:", "MD5:===" + otabean.getSign()); +// arrayList.add(otabean); +// } +// if (arrayList.size() > 0) { +// BaseNewThemeActivity.this.getApkList(arrayList); +// } +// } +// } catch (Exception unused) { +// } +// } +// +// @Override +// public void onFailure(Exception exc) { +// Log.e("zsj", exc.getMessage()); +// } +// }); +// } +// +// public void getApkList(List list) { +// try { +// String json = new Gson().toJson(list); +// OkhtttpUtils.getInstance().doPostOrGet(this, "POST", Constant.PLATFORM_URL_HEADER + "/api/jxwota/apk/sign/checkBySn?apkIsbn=znpbxgbv6&series=" + SPUtils.getSeries(), json, false, new OkhtttpUtils.OkCallback() { +// @Override +// public void onFailure(Exception exc) { +// } +// +// @Override +// public void onResponse(String str) { +// Log.e("zsj", str); +// try { +// PackageManager packageManager = MyApp.getInstance().getPackageManager(); +// Log.d("zzj", "获取数据成功了:" + str); +// try { +// JSONArray jSONArray = new JSONObject(str).getJSONArray("data"); +// BaseNewThemeActivity.packages.clear(); +// final int i = 0; +// for (int i2 = 0; i2 < jSONArray.length(); i2++) { +// JSONObject optJSONObject = jSONArray.optJSONObject(i2); +// int optInt = optJSONObject.optInt("versionCode"); +// String optString = optJSONObject.optString("packageName"); +// String optString2 = optJSONObject.optString("forceUpdate"); +// try { +// if (optInt > packageManager.getPackageInfo(optString, 0).versionCode) { +// i++; +// if (optString2.equals("1")) { +// BaseNewThemeActivity.packages.add(optString); +// } +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// BaseNewThemeActivity.this.runOnUiThread(new Runnable() { +// @Override +// public void run() { +// if (i > 0) { +// try { +// BaseNewThemeActivity baseNewThemeActivity = BaseNewThemeActivity.this; +// new DialogUpdate(baseNewThemeActivity, "" + i).show(); +// } catch (Exception unused) { +// } +// } +// } +// }); +// } catch (JSONException e2) { +// e2.printStackTrace(); +// } +// } catch (Exception e3) { +// e3.printStackTrace(); +// } +// } +// }); +// } catch (Exception e) { +// e.getMessage(); +// } +// } +//} diff --git a/app/src/main/java/com/xwad/os/jxw/base/BaseThemeActivity.java b/app/src/main/java/com/xwad/os/jxw/base/BaseThemeActivity.java new file mode 100644 index 0000000..6d3cba0 --- /dev/null +++ b/app/src/main/java/com/xwad/os/jxw/base/BaseThemeActivity.java @@ -0,0 +1,76 @@ +package com.xwad.os.jxw.base; + +//import android.os.Build; +//import android.os.Bundle; +//import android.os.Environment; +//import android.view.Window; +//import com.jxw.studyrecord.StudyRecordMng; +//import java.io.File; +//import net.lingala.zip4j.util.InternalZipConstants; +// +//public abstract class BaseThemeActivity extends BaseActivity { +// @Override +// public void onCreate(Bundle bundle) { +// super.onCreate(bundle); +// if (Build.VERSION.SDK_INT >= 21) { +// Window window = getWindow(); +// window.clearFlags(201326592); +// window.getDecorView().setSystemUiVisibility(1792); +// window.addFlags(Integer.MIN_VALUE); +// window.setStatusBarColor(0); +// window.setNavigationBarColor(0); +// } +// createDefDirs(); +// ActivityManager.getScreenManager().pushActivity(this); +// } +// +// @Override +// public void onDestroy() { +// clearCurrentActivity(); +// super.onDestroy(); +// } +// +// @Override +// public void onResume() { +// MyApp.getInstance(); +// MyApp.setCurrentActivity(this); +// super.onResume(); +// getWindow().getDecorView().setSystemUiVisibility(13058); +// } +// +// @Override +// public void onPause() { +// super.onPause(); +// } +// +// @Override +// public void onWindowFocusChanged(boolean z) { +// super.onWindowFocusChanged(z); +// if (z) { +// StudyRecordMng.stopCount(this); +// } +// } +// +// private void createDefDirs() { +// String[] stringArray = getResources().getStringArray(C1224R.array.default_directories); +// if (stringArray == null) { +// return; +// } +// String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath(); +// for (String str : stringArray) { +// File file = new File(absolutePath + InternalZipConstants.ZIP_FILE_SEPARATOR + str); +// if (!file.exists()) { +// file.mkdirs(); +// } +// file.setReadable(true, false); +// } +// } +// +// private void clearCurrentActivity() { +// MyApp.getInstance(); +// if (MyApp.getCurrentActivity() == this) { +// MyApp.getInstance(); +// MyApp.setCurrentActivity(null); +// } +// } +//} \ No newline at end of file diff --git a/app/src/main/java/com/xwad/os/manager/AmapManager.java b/app/src/main/java/com/xwad/os/manager/AmapManager.java index d88e327..f26df0b 100644 --- a/app/src/main/java/com/xwad/os/manager/AmapManager.java +++ b/app/src/main/java/com/xwad/os/manager/AmapManager.java @@ -11,8 +11,11 @@ import com.amap.api.location.AMapLocationClientOption; import com.amap.api.location.AMapLocationListener; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import com.hjq.permissions.Permission; +import com.hjq.permissions.XXPermissions; import com.jeremyliao.liveeventbus.LiveEventBus; import com.tencent.mmkv.MMKV; +import com.xwad.os.BuildConfig; import com.xwad.os.bean.BaseResponse; import com.xwad.os.bean.MapBean; import com.xwad.os.config.CommonConfig; @@ -40,7 +43,7 @@ public class AmapManager { private MapBean mMapBean; private AmapManager(Context context) { - this.mContext = context; + this.mContext = context.getApplicationContext(); initAmap(); } @@ -96,21 +99,33 @@ public class AmapManager { Gson gson = new Gson(); Type type = new TypeToken() { }.getType(); - try { - mMapBean = gson.fromJson(jsonString, type); - } catch (Exception e) { - Log.e(TAG, "initAmap: "); - mMMKV.remove(CommonConfig.MAP_LOCATION_JSON_KEY); - } + mMapBean = gson.fromJson(jsonString, type); } else { Log.e(TAG, "initAmap: jsonString is empty"); } } + public static final String[] PERMISSION_LOCATION = new String[]{ + Permission.ACCESS_COARSE_LOCATION, + Permission.ACCESS_FINE_LOCATION, +// Permission.ACCESS_BACKGROUND_LOCATION, + }; + + private boolean checkPermission() { + return XXPermissions.isGranted(mContext, PERMISSION_LOCATION); + } + public void startLocation() { boolean activation = ActivationUtil.getInstance().isActivation(); - if (!activation) { + if (!BuildConfig.DEBUG) { + if (!activation) { + Log.e(TAG, "startLocation: 未激活"); + return; + } + } + if (!checkPermission()) { + Log.e(TAG, "startLocation: 没有定位权限"); return; } mAMapLocationClient.stopLocation(); @@ -128,15 +143,18 @@ public class AmapManager { updateAddress(aMapLocation); mMapBean = getMapBean(aMapLocation); saveMapResult(mMapBean); - LiveEventBus.get("MapBean") + LiveEventBus.get(CommonConfig.MAP_BEAN) .post(mMapBean); + LiveEventBus.get(CommonConfig.MAP_ADDRESS_KEY) + .post(mMapBean.getAddress()); Log.e(TAG, "onLocationChanged: " + aMapLocation.getAddress()); sb.append(aMapLocation.getAddress()).append("\n"); - + mMMKV.encode(CommonConfig.MAP_onLocationChanged_time_KEY, System.currentTimeMillis()); } else { //定位失败 sb.append("定位失败" + "\n"); sb.append(aMapLocation.getErrorInfo()); + mMMKV.encode(CommonConfig.MAP_ERROR_KEY, aMapLocation.getErrorInfo()); Log.e(TAG, "onLocationChanged: " + "定位失败"); } Log.e(TAG, "amap: " + sb.toString()); @@ -145,9 +163,10 @@ public class AmapManager { private void updateAddress(AMapLocation aMapLocation) { boolean activation = ActivationUtil.getInstance().isActivation(); - if (!activation) { - return; - } +// if (!activation) { +// Log.e(TAG, "updateAddress: not activation" ); +// return; +// } NetInterfaceManager.getInstance().getUpdateAddressObservable(aMapLocation.getAddress() , aMapLocation.getLongitude(), aMapLocation.getLatitude() ) @@ -174,14 +193,14 @@ public class AmapManager { }); } - public String getLocationTude() { - if (mMapBean != null) { - return mMapBean.getLongitude() + "," + mMapBean.getLatitude(); - } else { - startLocation(); - return CommonConfig.DEFAULT_LOCATION_TUDE; - } - } +// public String getLocationTude() { +// if (mMapBean != null) { +// return mMapBean.getLongitude() + "," + mMapBean.getLatitude(); +// } else { +// startLocation(); +// return CommonConfig.DEFAULT_LOCATION_TUDE; +// } +// } public String getDistrict() { if (mMapBean != null) { @@ -216,6 +235,14 @@ public class AmapManager { private void saveMapResult(MapBean mapBean) { Log.e(TAG, "saveMapResult: " + GsonUtils.toJSONString(mapBean)); mMMKV.encode(CommonConfig.MAP_LOCATION_JSON_KEY, GsonUtils.toJSONString(mapBean)); + mMMKV.encode(CommonConfig.MAP_LONGITUDE_KEY, mapBean.getLongitude()); + mMMKV.encode(CommonConfig.MAP_LATITUDE_KEY, mapBean.getLatitude()); + mMMKV.encode(CommonConfig.MAP_ADDRESS_KEY, mapBean.getAddress()); + mMMKV.encode(CommonConfig.MAP_PROVINCE_KEY, mapBean.getProvince()); + mMMKV.encode(CommonConfig.MAP_CITY_KEY, mapBean.getCity()); + mMMKV.encode(CommonConfig.MAP_DISTRICT_KEY, mapBean.getDistrict()); + mMMKV.encode(CommonConfig.MAP_STREET_KEY, mapBean.getStreet()); + mMMKV.encode(CommonConfig.MAP_LOCATION_DESCRIBE_KEY, mapBean.getLocationDescribe()); } } diff --git a/app/src/main/java/com/xwad/os/manager/AppManager.java b/app/src/main/java/com/xwad/os/manager/AppManager.java index c2a245d..0564b6d 100644 --- a/app/src/main/java/com/xwad/os/manager/AppManager.java +++ b/app/src/main/java/com/xwad/os/manager/AppManager.java @@ -14,7 +14,6 @@ import com.tencent.mmkv.MMKV; import com.xwad.os.R; import com.xwad.os.bean.DesktopIcon; import com.xwad.os.config.CommonConfig; -import com.xwad.os.mdm.AdminManager; import com.xwad.os.utils.ApkUtils; import java.text.Collator; @@ -29,16 +28,17 @@ import java.util.stream.Collectors; public class AppManager { private static final String TAG = "AppManager"; - public static final String ADD_NAME = "com.zyos.add"; + public static final String ADD_NAME = "com.xwad.add"; public static final String APPSTORE_PACKAGE_NAME = "com.uiui.zyappstore"; public static final String APPSTORE_CLASS_NAME = "com.uiui.zyappstore.activity.MainActivity"; - public static final String UPDATE_NAME = "com.zyos.update"; - public static final String MANUAL_NAME = "com.zyos.manual"; - public static final String SERVICE_NAME = "com.zyos.service"; + public static final String UPDATE_NAME = "com.xwad.update"; + public static final String MANUAL_NAME = "com.xwad.manual"; + public static final String SERVICE_NAME = "com.xwad.service"; private static final String SHOW_PACKAGE_KEY = "SHOW_PACKAGE_KEY"; public static final String BROWSER_PACKAGE_NAME = "com.uiui.zybrowser"; public static final String BROWSER_CLASS_NAME = "com.uiui.zybrowser.activity.main.MainActivity"; - public static final String DESKTOP_EXIT = "com.zyos.exit"; + public static final String DESKTOP_EXIT = "com.xwad.exit"; + public static final String APP_HOMEWORK = "com.xwad.homework"; @SuppressLint("StaticFieldLeak") @@ -62,7 +62,7 @@ public class AppManager { throw new RuntimeException("Context is NULL"); } this.mContext = context; - this.showPackages = mMMKV.decodeStringSet(SHOW_PACKAGE_KEY, new HashSet(){{ + this.showPackages = mMMKV.decodeStringSet(SHOW_PACKAGE_KEY, new HashSet() {{ this.add("com.jxw.yyhb"); this.add("com.jxw.souti"); }}); @@ -98,8 +98,10 @@ public class AppManager { List resolveinfoList = pm.queryIntentActivities(resolveIntent, 0); Set allowPackages = resolveinfoList.stream().map(resolveInfo -> resolveInfo.activityInfo.packageName).collect(Collectors.toSet()); -// List adminApp = AdminManager.getInstance().getAdminApp(); -// Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); + Log.e(TAG, "getFilterAppset: " + showPackages); + + List adminApp = getAdminApp(); + Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); for (ResolveInfo resolveInfo : resolveinfoList) { String pkg = resolveInfo.activityInfo.packageName; if (ApkUtils.appIsDisable(mContext, pkg)) { @@ -116,11 +118,11 @@ public class AppManager { } } else { if (allowPackages.contains(pkg) && !ApkUtils.excludePackageName.contains(pkg)) { -// if (adminApp.contains(pkg)) { -// resolveInfos.add(resolveInfo); -// } else if (ApkUtils.showPackageName.contains(pkg)) { + if (adminApp.contains(pkg)) { resolveInfos.add(resolveInfo); -// } + } else if (ApkUtils.showPackageName.contains(pkg)) { + resolveInfos.add(resolveInfo); + } } } } @@ -148,8 +150,9 @@ public class AppManager { List resolveinfoList = pm.queryIntentActivities(resolveIntent, 0); Set allowPackages = resolveinfoList.stream().map(resolveInfo -> resolveInfo.activityInfo.packageName).collect(Collectors.toSet()); + Log.e(TAG, "getFilterAppList: " + showPackages); -// List adminApp = AdminManager.getInstance().getAdminApp(); + List adminApp = getAdminApp(); // Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); for (ResolveInfo resolveInfo : resolveinfoList) { String pkg = resolveInfo.activityInfo.packageName; @@ -167,11 +170,11 @@ public class AppManager { } } else { if (allowPackages.contains(pkg) && !ApkUtils.excludePackageName.contains(pkg)) { -// if (adminApp.contains(pkg)) { -// resolveInfos.add(resolveInfo); -// } else if (ApkUtils.showPackageName.contains(pkg)) { + if (adminApp.contains(pkg)) { resolveInfos.add(resolveInfo); -// } + } else if (ApkUtils.showPackageName.contains(pkg)) { + resolveInfos.add(resolveInfo); + } } } } @@ -213,7 +216,6 @@ public class AppManager { } - for (ResolveInfo applicationInfo : resolveInfos) { if (!ApkUtils.excludeClassName.contains(applicationInfo.activityInfo.name)) { desktopIcons.add(DesktopIcon.creatDesktopIcon(mContext, applicationInfo)); @@ -234,6 +236,7 @@ public class AppManager { List resolveinfoList = pm.queryIntentActivities(resolveIntent, 0); Set allowPackages = resolveinfoList.stream().map(resolveInfo -> resolveInfo.activityInfo.packageName).collect(Collectors.toSet()); + Log.e(TAG, "getAllAppList: " + showPackages); // List adminApp = AdminManager.getInstance().getAdminApp(); // Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); @@ -289,4 +292,9 @@ public class AppManager { return desktopIcons; } + public List getAdminApp() { + Set adminAppSet = mMMKV.decodeStringSet(CommonConfig.ADMIN_APP_LIST, new HashSet<>()); + Log.e(TAG, "getAdminApp: " + adminAppSet); + return new ArrayList<>(adminAppSet); + } } diff --git a/app/src/main/java/com/xwad/os/manager/ControlManager.java b/app/src/main/java/com/xwad/os/manager/ControlManager.java new file mode 100644 index 0000000..d3ec027 --- /dev/null +++ b/app/src/main/java/com/xwad/os/manager/ControlManager.java @@ -0,0 +1,832 @@ +package com.xwad.os.manager; + +import android.annotation.SuppressLint; +import android.bluetooth.BluetoothAdapter; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; + +import com.google.gson.JsonObject; +import com.hjq.toast.Toaster; +import com.tencent.mmkv.MMKV; +import com.xwad.os.BuildConfig; +import com.xwad.os.bean.SystemSettings; +import com.xwad.os.config.CommonConfig; +import com.xwad.os.gson.GsonUtils; +import com.xwad.os.mdm.AdminManager; +import com.xwad.os.utils.ApkUtils; +import com.xwad.os.utils.JgyUtils; +import com.xwad.os.utils.TimeUtils; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.function.Predicate; + +/** + * 系统管理处理 + * 所有数据 后台1是0否,底层0是1否 + * + * @author jgy02 + */ +public class ControlManager { + private static final String TAG = "ControlManager"; + + @SuppressLint("StaticFieldLeak") + private static ControlManager sInstance; + private Context mContext; + private ContentResolver mResolver; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + private ControlManager(Context context) { + if (context == null) { + throw new RuntimeException("Context is NULL"); + } + this.mContext = context; + this.mResolver = context.getContentResolver(); + } + + public static void init(Context context) { + if (sInstance == null) { + sInstance = new ControlManager(context); + } + } + + public static ControlManager getInstance() { + if (sInstance == null) { + throw new IllegalStateException("You must be init ControlManager first"); + } + return sInstance; + } + +// private int changeNum(int status) { +// return status == 0 ? 1 : 0; +// } + + private boolean isDebugMode() { + return BuildConfig.DEBUG; + } + + public void setSystemSetting(String jsonString) { + if (TextUtils.isEmpty(jsonString)) { + return; + } + SystemSettings systemSettings = GsonUtils.toJavaObject(jsonString, SystemSettings.class); + if (null != systemSettings) { + setUSBstate(systemSettings); +// setPhoneList(systemSettings); +// setBluetooth(systemSettings); +// setHotspot(systemSettings); + setBar(systemSettings); + setCamera(systemSettings); +// setTF(systemSettings); + setIcon(systemSettings); + setCanReset(systemSettings); + setDeveloperOptions(systemSettings); +// setSearchTopic(systemSettings); + setSOSNumber(systemSettings); + setAppstoreAdmin(systemSettings); + setDefaultApp(systemSettings); + setIsControl(systemSettings); + setOtherAppInstaller(systemSettings); + setQuickApp(systemSettings); + setTimeControl(systemSettings); + setBrowserInput(systemSettings); + + setZhuangyuanSetting(systemSettings); + } + } + + /** + * 关闭所有功能 + */ + public void setDisableSetting() { + Log.e("setDisableSetting", "Close all settings: "); +// setUSBstate(1); +// setPhoneList(1); +// setBluetooth(0); +// setHotspot(0); + setCamera(1); +// setTF(1); + setIcon(1); + setWallpaper(0); + setCanReset(1); + setBrowserInput(1); + if (!isDebugMode()) { +// setDeveloperOptions(1); + } +// setSearchTopic(0); + setTimeControlClose(); + } + + /** + * usb连接模式管控 + * + * @param settings + */ + private void setUSBstate(SystemSettings settings) { + //USB数据功能管控 + //仅充电:usb_charge + //MTP模式:usb_mtp + //Midi模式:usb_midi + String setting_usb = settings.getSetting_usb(); + Log.e("SystemSetting", "setting_usb:" + setting_usb); + AdminManager.getInstance().setUSBDataDisabled(!"usb_mtp".equals(setting_usb)); + } + + + /** + * usb连接模式管控 + * + * @param state + */ + public void setUSBstate(int state) { + //USB数据功能管控 + //仅充电:usb_charge + //MTP模式:usb_mtp + //Midi模式:usb_midi + if (!isDebugMode()) { + try { +// boolean qch_usb_choose = Settings.System.putString(mResolver, "qch_usb_choose", "usb_charge"); +// Log.e(TAG, "qch_usb_choose:" + qch_usb_choose); + String usbStatus = CommonConfig.AOLE_ACTION_USB_USB_CHARGE; + Intent usbIntent = new Intent(usbStatus).setPackage("com.android.settings"); + mContext.sendBroadcast(usbIntent); + } catch (Exception e) { + Log.e(TAG, "setUSBstate: " + e.getMessage()); + } + } + } + + /** + * usb连接模式管控 + */ + public void setUSBstate(String action) { + //USB数据功能管控 + //仅充电:usb_charge + //MTP模式:usb_mtp + //Midi模式:usb_midi + if (!isDebugMode()) { + Log.e(TAG, "qch_usb_choose:" + action); + AdminManager.getInstance().setUSBDataDisabled(!"usb_mtp".equals(action)); + } + } + + private void setPhoneList(SystemSettings settings) { + //设置电话功能,电话白名单 +// int setting_call = changeNum(settings.getSetting_call()); +// boolean qch_call_forbid = Settings.System.putInt(mResolver, "qch_call_forbid", setting_call); +// Log.e("SystemSetting", "qch_call_forbid: " + setting_call); + +// int setting_phone = changeNum(settings.getSetting_phone()); +// boolean aole_white_list_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_WHITE_LIST_ON, setting_phone); +// Log.e("SystemSetting", "aole_white_list_on: " + setting_phone); + +// String setting_phones = settings.getSetting_phones(); +// boolean aole_white_list_Array = Settings.System.putString(mResolver, CommonConfig.AOLE_ACTION_WHITE_LIST_ARRAY, setting_phones); +// Log.e("SystemSetting", "aole_white_list_Array: " + aole_white_list_Array + "=" + setting_phones); + +// int setting_memory = changeNum(settings.getSetting_memory()); +// boolean aole_sdcard_forbid_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_SDCARD_FORBID_ON, setting_memory); +// Log.e("SystemSetting", "aole_sdcard_forbid_on: " + setting_memory); + } + + private void setPhoneList(int state) { + try { + //设置电话功能,电话白名单 +// boolean qch_call_forbid = Settings.System.putInt(mResolver, "qch_call_forbid", state); +// Log.e(TAG, "qch_call_forbid:" + qch_call_forbid); + +// boolean aole_white_list_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_WHITE_LIST_ON, state); +// Log.e(TAG, "aole_white_list_on:" + aole_white_list_on); + +// boolean aole_white_list_Array = Settings.System.putString(mResolver, CommonConfig.AOLE_ACTION_WHITE_LIST_ARRAY, ""); + // ToastTool.show("qch_call_forbid::"+setting_call+"----setting_phones::"+setting_phones+"----"+aole_white_list_Array+"---"+qch_call_forbid); +// Log.e(TAG, "aole_white_list_Array:" + aole_white_list_Array + "---" + aole_white_list_Array); + +// boolean aole_sdcard_forbid_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_SDCARD_FORBID_ON, state); +// Log.e(TAG, "aole_sdcard_forbid_on:" + aole_sdcard_forbid_on); + } catch (Exception e) { + Log.e(TAG, "setPhoneList: " + e.getMessage()); + } + } + + private void setBluetooth(SystemSettings settings) { + try { + //蓝牙开关 +// int setting_bht = changeNum(settings.getSetting_bht()); + //总开关 +// int setting_bhtvideo = changeNum(settings.getSetting_bhtvideo()); + //蓝牙音频开关 +// int setting_bluetooth = changeNum(settings.getSetting_bluetooth()); + //蓝牙传输开关 +// boolean aole_bht_forbid_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_BHT_FORBID_ON, setting_bht); + //写入系统数据库 +// Log.e("SystemSetting", "aole_bht_forbid_on:" + aole_bht_forbid_on); + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); +// if (aole_bht_forbid_on) { +// //成功 +// if (null == mBluetoothAdapter) { +// mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); +// //获取默认蓝牙适配器 +// } +// if (setting_bht == 0) { +// //蓝牙总开关开启 +// String setting_context = settings.getSetting_context(); +// if (setting_bhtvideo == 0) { +// if (null != setting_context && !"".equals(setting_context) && !" ".equals(setting_context) && !"null".equals(setting_context)) { +// Log.e("SystemSetting", "setting_context:" + setting_context); +//// Settings.System.putString(mResolver, CommonConfig.AOLE_ACTION_BHTVIDEO_FORBID_ON, setting_context); +// } else { +//// Settings.System.putString(mResolver, CommonConfig.AOLE_ACTION_BHTVIDEO_FORBID_ON, "Empty"); +// } +// } else if (setting_bhtvideo == 1) { +//// Settings.System.putString(mResolver, CommonConfig.AOLE_ACTION_BHTVIDEO_FORBID_ON, "Empty"); +// } +//// Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_BT_FORBID_ON, setting_bluetooth); +// } else { +// mBluetoothAdapter.disable(); +// //设置关闭时关闭蓝牙 +// } +// } + } catch (Exception e) { + Log.e(TAG, "setBluetooth: " + e.getMessage()); + } + } + + private void setBluetooth(int state) { + try { +// boolean aole_bht_forbid_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_BHT_FORBID_ON, state); + //写入系统数据库 +// Log.e(TAG, "aole_bht_forbid_on:" + aole_bht_forbid_on); + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); +// if (aole_bht_forbid_on) { +// //成功 +// if (null == mBluetoothAdapter) { +// mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); +// //获取默认蓝牙适配器 +// } +// //蓝牙总开关开启 +//// Settings.System.putString(mResolver, CommonConfig.AOLE_ACTION_BHTVIDEO_FORBID_ON, "Empty"); +//// Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_BT_FORBID_ON, state); +// mBluetoothAdapter.disable(); +// //设置关闭时关闭蓝牙 +// } + } catch (Exception e) { + Log.e(TAG, "setBluetooth: " + e.getMessage()); + } + } + + private void setHotspot(SystemSettings settings) { + try { +// int setting_hotspot = changeNum(settings.getSetting_hotspot());//热点 +// if (setting_hotspot == 1) { +// Intent intent = new Intent(); +// intent.setAction("qch_hotspot_close"); +// intent.setPackage("com.android.settings"); +// mContext.sendStickyBroadcast(intent); +// } +// boolean aole_hotspot_forbid_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_HOTSPOT_FORBID_ON, setting_hotspot);//写入系统数据库 +// Log.e("SystemSetting", "aole_hotspot_forbid_on:" + setting_hotspot); +// Log.e("SystemSetting", "aole_hotspot_forbid_on:" + aole_hotspot_forbid_on); + } catch (Exception e) { + Log.e(TAG, "setHotspot: " + e.getMessage()); + } + } + + private void setHotspot(int state) { + try { + Intent intent = new Intent(); + intent.setAction("qch_hotspot_close"); + intent.setPackage("com.android.settings"); + mContext.sendStickyBroadcast(intent); +// boolean aole_hotspot_forbid_on = Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_HOTSPOT_FORBID_ON, state); +// Log.e(TAG, "aole_hotspot_forbid_on:" + aole_hotspot_forbid_on); + } catch (Exception e) { + Log.e(TAG, "setHotspot: " + e.getMessage()); + } + } + + private void setBar(SystemSettings settings) { + //系统导航条显示开关 + int setting_navigation = settings.getSetting_navigation(); + Log.e(TAG, "setBar: setting_navigation = " + setting_navigation); + AdminManager.getInstance().setStatusBarExpandPanelDisabled(setting_navigation); + + //状态栏显示开关 + int setting_statusbar = settings.getSetting_statusbar(); + Log.e(TAG, "setBar: setting_statusbar = " + setting_statusbar); + AdminManager.getInstance().setNavigationBarDisabled(setting_statusbar); + } + + @Deprecated + private void setCamera(SystemSettings settings) { + try { + //摄像头开关 + int setting_camera = (settings.getSetting_camera()); +// Settings.System.putInt(mResolver, "qch_app_camera", setting_camera); +// ApkUtils.hideSystemSettingAPP(mContext, "com.mediatek.camera"); + Log.e("SystemSetting", "setting_camera:" + setting_camera); + String cameraStatus = ""; + switch (setting_camera) { + case 0: + cameraStatus = "qch_camera_open"; + break; + case 1: + cameraStatus = "qch_camera_forbid"; + break; + } + } catch (Exception e) { + Log.e(TAG, "setCamera: " + e.getMessage()); + } + } + + @Deprecated + private void setCamera(int state) { + try { + //摄像头开关 +// boolean qch_app_camera = Settings.System.putInt(mResolver, "qch_app_camera", state); + Log.e(TAG, "qch_app_camera1:" + state); +// ApkUtils.hideSystemSettingAPP(mContext, "com.mediatek.camera"); +// Log.e(TAG, "setting_camera---------" + qch_app_camera); + String cameraStatus = "qch_camera_forbid"; + switch (state) { + case 0: + cameraStatus = "qch_camera_open"; + break; + case 1: + cameraStatus = "qch_camera_forbid"; + break; + } + Intent cameraIntent = new Intent(cameraStatus).setPackage("com.android.settings"); + mContext.sendBroadcast(cameraIntent); + } catch (Exception e) { + Log.e(TAG, "setCamera: " + e.getMessage()); + } + } + + @SuppressLint("NewApi") + private void setTF(SystemSettings settings) { + //tfmedia开关 + int setting_tfmedia = (settings.getSetting_tfmedia()); +// boolean qch_tfmedia_forbid = Settings.System.putInt(mResolver, "qch_tfmedia_forbid", setting_tfmedia); +// Log.e("SystemSetting", "setting_tfmedia:" + qch_tfmedia_forbid); + String tfmediaStatus = ""; + switch (setting_tfmedia) { + case 0: + tfmediaStatus = "qch_tfmedia_open"; + break; + case 1: + tfmediaStatus = "qch_tfmedia_forbid"; + break; + default: + break; + } + Intent tfmediaIntent = new Intent(tfmediaStatus).setPackage("com.android.settings"); + mContext.sendBroadcast(tfmediaIntent); + if (setting_tfmedia == 1) { + String qch_tfmedia_filetypes = settings.getSetting_tfmedia_format(); + if (TextUtils.isEmpty(qch_tfmedia_filetypes)) { +// Settings.System.putString(mResolver, "qch_tfmedia_filetypes", "");//影音管控 + } else { + HashSet types = new HashSet<>(Arrays.asList(qch_tfmedia_filetypes.split(","))); + types.removeIf(new Predicate() { + @Override + public boolean test(String s) { + return TextUtils.isEmpty(s); + } + }); + String typesString = String.join(",", types); +// Settings.System.putString(mResolver, "qch_tfmedia_filetypes", typesString);//影音管控 + Log.e("SystemSetting", "qch_tfmedia_filetypes :" + typesString); + } + } else { +// Settings.System.putInt(mResolver, "qch_tfmedia_forbid", 0); + } + } + + private void setTF(int state) { + try { + //tfmedia开关 +// int setting_tfmedia = 1; +// boolean qch_tfmedia_forbid = Settings.System.putInt(mResolver, "qch_tfmedia_forbid", state); +// Log.e(TAG, "setting_tfmedia---------" + qch_tfmedia_forbid); + String tfmediaStatus = ""; + switch (state) { + case 0: + tfmediaStatus = "qch_tfmedia_open"; + break; + case 1: + tfmediaStatus = "qch_tfmedia_forbid"; + break; + } + Intent tfmediaIntent = new Intent(tfmediaStatus).setPackage("com.android.settings"); + mContext.sendBroadcast(tfmediaIntent); + if (state == 1) { +// boolean qch_tfmedia_filetypes = Settings.System.putString(mResolver, "qch_tfmedia_filetypes", "Empty");//影音管控 +// Log.e(TAG, "qch_tfmedia_filetypes:" + qch_tfmedia_filetypes); + } else { +// Settings.System.putInt(mResolver, "qch_tfmedia_forbid", 0); + } + } catch (Exception e) { + Log.e(TAG, "setTF: " + e.getMessage()); + } + } + + @Deprecated + private void setIcon(SystemSettings settings) { + try { + int deskclock = (settings.getSetting_clock()); + Log.e("SystemSetting", "qch_app_deskclock:" + deskclock); + //录音机 + int soundrecorder = (settings.getSetting_recording()); + Log.e("SystemSetting", "qch_app_soundrecorder:" + soundrecorder); + //音乐 + int music = (settings.getSetting_music()); + Log.e("SystemSetting", "qch_app_music:" + music); + //图库 + int gallery = (settings.getSetting_picture()); + Log.e("SystemSetting", "qch_app_gallery:" + gallery); + //壁纸 + int wallpaper = (settings.getSetting_wallpaper()); + Log.e("SystemSetting", "qch_app_wallpaper:" + wallpaper); + //文件管理器 + int filemanager = (settings.getSetting_file()); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { +// ApkUtils.hideSystemSettingAPP(mContext, "com.mediatek.filemanager"); + } else { +// ApkUtils.hideSystemSettingAPP(mContext, "com.android.documentsui"); + } + Log.e("SystemSetting", "qch_app_filemanager:" + filemanager); + //浏览器 + int browser = (settings.getSetting_browser()); + Log.e(TAG, "qch_app_browser" + browser); + } catch (Exception e) { + Log.e(TAG, "setIcon: " + e.getMessage()); + } + } + + @Deprecated + private void setIcon(int state) { + try { + + //时钟 +// int deskclock = 1; +// ApkUtils.hideSystemSettingAPP(mContext, "com.android.deskclock"); + Log.e(TAG, "qch_app_deskclock" + state); + //录音机 +// int soundrecorder = 1; +// ApkUtils.hideSystemSettingAPP(mContext, "com.android.soundrecorder"); + Log.e(TAG, "qch_app_soundrecorder" + state); + //音乐 +// int music = 1; +// ApkUtils.hideSystemSettingAPP(mContext, "com.android.music"); + Log.e(TAG, "qch_app_music" + state); + //图库 +// int gallery = 1; +// ApkUtils.hideSystemSettingAPP(mContext, "com.android.gallery3d"); + Log.e(TAG, "qch_app_gallery" + state); + //文件管理器 +// int filemanager = 1; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { +// ApkUtils.hideSystemSettingAPP(mContext, "com.mediatek.filemanager"); + } else { +// ApkUtils.hideSystemSettingAPP(mContext, "com.android.documentsui"); + } + Log.e(TAG, "qch_app_filemanager" + state); + //浏览器 + Log.e(TAG, "qch_app_browser" + state); + } catch (Exception e) { + Log.e(TAG, "setIcon: " + e.getMessage()); + } + } + + private void setWallpaper(int state) { + //壁纸 +// int wallpaper = 1; +// Settings.System.putInt(mResolver, "qch_app_wallpaper", state); + Log.e(TAG, "qch_app_wallpaper" + state); + } + + private void setCanReset(SystemSettings settings) { + int qch_restore = settings.getQch_restore(); + Log.e(TAG, "setCanReset: qch_restore = " + qch_restore); + AdminManager.getInstance().setRestoreFactoryDisabled(qch_restore); + } + + private void setCanReset(int state) { + Log.e(TAG, "setCanReset: state = " + state); + AdminManager.getInstance().setRestoreFactoryDisabled(state); + } + + /** + * 置浏览器禁止输入,默认打开 + * + * @param state + */ + @Deprecated + private void setBrowserInput(int state) { +// Settings.System.putInt(mResolver, "qch_Browser_input", 0); + } + + @Deprecated + private void setBrowserInput(SystemSettings systemSettings) { + int setting_browserInput = (systemSettings.getSetting_browserInput()); +// Settings.System.putInt(mResolver, "qch_Browser_input", setting_browserInput); + } + + public void setDeveloperOptions(SystemSettings systemSettings) { + int dev_mode = systemSettings.getDev_mode(); + Log.e(TAG, "setDeveloperOptions: " + dev_mode); + if (!isDebugMode()) { + setDeveloperMode(dev_mode); + } + } + + public void setDeveloperOptions(String jsonString) { + JsonObject jsonObject = GsonUtils.getJsonObject(jsonString); + int dev_mode = (jsonObject.get("dev_mode").getAsInt()); + Log.e(TAG, "setDeveloperOptions: " + dev_mode); + if (!isDebugMode()) { +// Settings.System.putInt(mResolver, "qch_Developeroptions", dev_mode); + int old_dev_enabled = Settings.Global.getInt(mResolver, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + Log.e(TAG, "setDeveloperOptions: " + old_dev_enabled); + int new_state = (dev_mode == 1 ? 0 : 1); + if (old_dev_enabled != new_state) { +// Settings.Global.putInt(mResolver, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, new_state); +// Settings.Global.putInt(mResolver, Settings.Global.ADB_ENABLED, new_state); + } +// Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_DEVELOPER_OPTIONS, dev_mode); + if (dev_mode == 1) { + Intent intent = new Intent(); + intent.setAction("qch_developeroptions_close"); + intent.setPackage("com.android.settings"); + mContext.sendBroadcast(intent); + Log.e(TAG, "setDeveloperOptions: " + "关闭开发者模式"); + Toaster.debugShow("关闭开发者模式"); + } else { + Log.e(TAG, "setDeveloperOptions: " + "打开开发者模式"); + Toaster.debugShow("打开开发者模式"); + } + } + } + + public void setDeveloperOptions(int state) { + Log.e(TAG, "setDeveloperOptions: " + state); + if (!isDebugMode()) { +// Settings.System.putInt(mResolver, "qch_Developeroptions", state); + int old_dev_enabled = Settings.Global.getInt(mResolver, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + Log.e(TAG, "setDeveloperOptions: " + old_dev_enabled); + int new_state = (state == 1 ? 0 : 1); + if (old_dev_enabled != new_state) { +// Settings.Global.putInt(mResolver, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, new_state); +// Settings.Global.putInt(mResolver, Settings.Global.ADB_ENABLED, new_state); + } +// Settings.System.putInt(mResolver, CommonConfig.AOLE_ACTION_DEVELOPER_OPTIONS, state); + if (state == 1) { + Intent intent = new Intent(); + intent.setAction("qch_developeroptions_close"); + intent.setPackage("com.android.settings"); + mContext.sendBroadcast(intent); + Log.e(TAG, "setDeveloperOptions: " + "关闭开发者模式"); + } else { + Log.e(TAG, "setDeveloperOptions: " + "打开开发者模式"); +// Toaster.show("打开开发者模式"); + } + } + } + + public void setSearchTopic(String jsonString) { + JsonObject jsonObject = GsonUtils.getJsonObject(jsonString); + if (jsonObject.get("search_topic") == null) return; + int mode = jsonObject.get("search_topic").getAsInt(); + mMMKV.encode("search_topic", mode); + Log.e(TAG, "setSearchTopic:" + mode); + } + + public void setSearchTopic(int state) { + mMMKV.encode("search_topic", state); + Log.e(TAG, "setSearchTopic:" + state); + } + + /** + * 开机管控usb + */ + public void setDefaultUSBstate() { + //USB数据功能管控 + //仅充电:usb_charge + //MTP模式:usb_mtp + //Midi模式:usb_midi + String setting_usb = Settings.System.getString(mResolver, "qch_usb_choose"); + Log.e("SystemSetting", "setting_usb:" + setting_usb); + String usbStatus = ""; + if (TextUtils.isEmpty(setting_usb)) { + usbStatus = CommonConfig.AOLE_ACTION_USB_USB_CHARGE; + } else { + if (!isDebugMode()) { + switch (setting_usb) { + case "usb_charge": + usbStatus = CommonConfig.AOLE_ACTION_USB_USB_CHARGE; + break; + case "usb_mtp": + usbStatus = CommonConfig.AOLE_ACTION_USB_USB_MTP; + break; +// case "usb_midi": +// usbStatus = CommonConfig.AOLE_ACTION_USB_USB_MIDI; +// break; + default: + usbStatus = CommonConfig.AOLE_ACTION_USB_USB_CHARGE; + break; + } + } + } + Intent usbIntent = new Intent(usbStatus).setPackage("com.android.settings"); + mContext.sendBroadcast(usbIntent); + } + + @Deprecated + private void setSOSNumber(SystemSettings settings) { + String setting_sos = settings.getSetting_sos(); + Log.e(TAG, "setSOSNumber: setting_sos = " + setting_sos); + } + + @Deprecated + private void setAppstoreAdmin(SystemSettings settings) { + int setting_admin_app = settings.getSetting_admin_app(); + mMMKV.encode(CommonConfig.APP_ADMIN, setting_admin_app); + int isReturnAndroid = settings.getIs_return_android(); + mMMKV.encode(CommonConfig.UIUI_RETURN_ANDROID_KEY, isReturnAndroid); + } + + private void setSetting(SystemSettings settings) { + String setting_volume = settings.getSetting_volume(); + String setting_luminance = settings.getSetting_luminance(); + String setting_typeface = settings.getSetting_typeface(); + } + + private void setScreenShared(SystemSettings settings) { + int projection_screen = settings.getProjection_screen(); + setScreenShared(projection_screen); + } + + private void setScreenShared(int state) { +// Settings.System.putInt(mResolver, "projection_screen", state); + } + + private void setHotPoint(SystemSettings settings) { + int hot_point = settings.getHot_point(); + setScreenShared(hot_point); + } + + private void setHotPoint(int state) { +// Settings.System.putInt(mResolver, "hot_point", state); + } + + private void setDefaultApp(SystemSettings settings) { + String desktop_app = settings.getDesktop_app(); + Log.e(TAG, "setDefaultApp: desktop_app = " + desktop_app); + if (!TextUtils.isEmpty(desktop_app)) { + mMMKV.encode(CommonConfig.DESKTOP_APP_KEY, desktop_app); + JgyUtils.getInstance().setDefaultDesktop(desktop_app); + } else { + mMMKV.encode(CommonConfig.DESKTOP_APP_KEY, ""); + } + String browser_app = settings.getBrowser_app(); + Log.e(TAG, "setDefaultApp: browser_app = " + browser_app); + if (!TextUtils.isEmpty(browser_app)) { + mMMKV.encode(CommonConfig.BROWSER_APP_KEY, browser_app); + JgyUtils.getInstance().setDefaultBrowser(browser_app); + } else { + mMMKV.encode(CommonConfig.BROWSER_APP_KEY, ""); + } + String typewriting_app = settings.getTypewriting_app(); + Log.e(TAG, "setDefaultApp: typewriting_app = " + typewriting_app); + if (!TextUtils.isEmpty(typewriting_app)) { + mMMKV.encode(CommonConfig.TYPEWRITING_APP_KEY, typewriting_app); + JgyUtils.getInstance().setDefaultInputMethod(typewriting_app); + } else { + mMMKV.encode(CommonConfig.TYPEWRITING_APP_KEY, ""); + } + } + + /** + * 应用安装之后重新设置 + */ + public void setDefaultApp() { + String desktop_app = mMMKV.decodeString(CommonConfig.DESKTOP_APP_KEY, ""); + Log.e(TAG, "setDefaultApp: desktop_app = " + desktop_app); + if (!TextUtils.isEmpty(desktop_app)) { + JgyUtils.getInstance().setDefaultDesktop(desktop_app); + } + String browser_app = mMMKV.decodeString(CommonConfig.BROWSER_APP_KEY, ""); + Log.e(TAG, "setDefaultApp: browser_app = " + browser_app); + if (!TextUtils.isEmpty(browser_app)) { + JgyUtils.getInstance().setDefaultBrowser(browser_app); + } + String typewriting_app = mMMKV.decodeString(CommonConfig.TYPEWRITING_APP_KEY, ""); + Log.e(TAG, "setDefaultApp: typewriting_app = " + typewriting_app); + if (!TextUtils.isEmpty(typewriting_app)) { + JgyUtils.getInstance().setDefaultInputMethod(typewriting_app); + } + } + + private void setIsControl(SystemSettings settings) { + int is_control = settings.getIs_control(); + setIsControl(is_control); + } + + private void setIsControl(int state) { +// Settings.System.putInt(mResolver, CommonConfig.KEY_IS_CONTROL, state); + //关闭 + if (state == 0) { +// setBluetooth(0); +// setHotspot(0); + setUSBstate(CommonConfig.AOLE_ACTION_USB_USB_MTP); + } + } + + @Deprecated + private void setOtherAppInstaller(SystemSettings settings) { + int is_storeinstall = settings.getIs_storeinstall(); + mMMKV.encode(CommonConfig.APP_STORE_INSTALL, is_storeinstall); + int setting_other_appInstaller = settings.getSetting_other_appInstaller(); + mMMKV.encode(CommonConfig.APP_INSTALLATION, setting_other_appInstaller); + } + + @Deprecated + public void setOtherAppInstaller(int status) { + mMMKV.encode(CommonConfig.APP_STORE_INSTALL, status); + mMMKV.encode(CommonConfig.APP_INSTALLATION, status); + mMMKV.encode(CommonConfig.AOLE_APP_ALLOW_INSTALL, status); + } + + + public static final String QUICK_APP_KEY = "QuickAppPackageKey"; + public static final String QUICK_APP_REFRESH_KEY = "QuickAppRefreshKey"; + public static final String QUICK_APP_ENABLED_KEY = "QuickAppEnabledKey"; + + @Deprecated + private void setQuickApp(SystemSettings settings) { + if (settings.getIs_quickapp() == 1) { + String pkg = settings.getQuickapp(); +// Settings.Global.putString(mContext.getContentResolver(), QUICK_APP_KEY, pkg); +// Settings.Global.putInt(mContext.getContentResolver(), QUICK_APP_ENABLED_KEY, 1); + } else { +// Settings.Global.putInt(mContext.getContentResolver(), QUICK_APP_ENABLED_KEY, 0); + } + } + + private void setTimeControl(SystemSettings settings) { + int is_timecontrol = settings.getIs_timecontrol(); + mMMKV.encode(TimeUtils.AOLELEARN_TIME_CONTROL_KEY, is_timecontrol); + +// String timecontrol_start = settings.getTimecontrol_start(); +// mMMKV.encode(TimeUtils.AOLELEARN_TTIMECONTROL_START_KEY, timecontrol_start); +// String timecontrol_end = settings.getTimecontrol_start(); +// mMMKV.encode(TimeUtils.AOLELEARN_TTIMECONTROL_END_KEY, timecontrol_end); + } + + private void setTimeControlClose() { + mMMKV.encode(TimeUtils.AOLELEARN_TIME_CONTROL_KEY, 0); +// mMMKV.encode(TimeUtils.AOLELEARN_TTIMECONTROL_START_KEY, ""); +// mMMKV.encode(TimeUtils.AOLELEARN_TTIMECONTROL_END_KEY, ""); + } + + private void setZhuangyuanSetting(SystemSettings setting) { + setBluetoothShare((setting.getIs_bluetooth_share())); + setDeveloperMode((setting.getIs_developer_mode())); + setDeviceRecover((setting.getIs_device_recover())); + setTopNotify(setting.getIs_top_notify()); + setBottomBar(setting.getIs_bottom_bar()); + } + + public void setBluetoothShare(int status) { + Log.e(TAG, "setBluetoothShare: " + status); + AdminManager.getInstance().setBluetoothDataTransferDisable(status == 0); + } + + public void setDeveloperMode(int status) { + Log.e(TAG, "setDeveloperMode: " + status); + AdminManager.getInstance().turnOnUsbDebugMode(status); + } + + public void setDeviceRecover(int status) { + Log.e(TAG, "setDeviceRecover: " + status); + AdminManager.getInstance().setRestoreFactoryDisabled(status); + } + + public void setTopNotify(int status) { + Log.e(TAG, "setTopNotify: " + status); + AdminManager.getInstance().setStatusBarExpandPanelDisabled(status); + } + + public void setBottomBar(int status) { + Log.e(TAG, "setBottomBar: " + status); + AdminManager.getInstance().setNavigationBarDisabled(status); + } + + +} diff --git a/app/src/main/java/com/xwad/os/manager/DeviceSNManager.java b/app/src/main/java/com/xwad/os/manager/DeviceSNManager.java index d171bc6..1c4e2f7 100644 --- a/app/src/main/java/com/xwad/os/manager/DeviceSNManager.java +++ b/app/src/main/java/com/xwad/os/manager/DeviceSNManager.java @@ -24,6 +24,7 @@ public class DeviceSNManager { /** * 获取设备SN,如果不存在则创建新的 */ + @Deprecated public static String getDeviceSN() { String existingSN = mMMKV.decodeString(SN_KEY, ""); diff --git a/app/src/main/java/com/xwad/os/mdm/AdminManager.java b/app/src/main/java/com/xwad/os/mdm/AdminManager.java index 34af8bb..74a8fe9 100644 --- a/app/src/main/java/com/xwad/os/mdm/AdminManager.java +++ b/app/src/main/java/com/xwad/os/mdm/AdminManager.java @@ -119,27 +119,33 @@ public class AdminManager { this.mContext = context; this.mAdminName = new ComponentName(context, AoleDeviceAdminReceiver.class); this.mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); - this.mDeviceApplicationManager = new DeviceApplicationManager(); - this.mDeviceBluetoothManager = new DeviceBluetoothManager(); - this.mDeviceCameraManager = new DeviceCameraManager(); - this.mDeviceControlManager = new DeviceControlManager(); - this.mDeviceEmailManager = new DeviceEmailManager(); - this.mDeviceFirewallManager = new DeviceFirewallManager(); - this.mDeviceHwSystemManager = new DeviceHwSystemManager(); - this.mDeviceInfraredManager = new DeviceInfraredManager(); - this.mDeviceLocationManager = new DeviceLocationManager(); - this.mDeviceNetworkManager = new DeviceNetworkManager(); - this.mDeviceP2PManager = new DeviceP2PManager(); - this.mDevicePackageManager = new DevicePackageManager(); - this.mDevicePasswordManager = new DevicePasswordManager(); - this.mDevicePhoneManager = new DevicePhoneManager(); - this.mDeviceRestrictionManager = new DeviceRestrictionManager(); - this.mDeviceSettingsManager = new DeviceSettingsManager(); - this.mDeviceStorageManagerEx = new DeviceStorageManagerEx(); - this.mDeviceTelephonyManager = new DeviceTelephonyManager(); + try { + this.mDeviceApplicationManager = new DeviceApplicationManager(); + this.mDeviceBluetoothManager = new DeviceBluetoothManager(); + this.mDeviceCameraManager = new DeviceCameraManager(); + this.mDeviceControlManager = new DeviceControlManager(); + this.mDeviceEmailManager = new DeviceEmailManager(); + this.mDeviceFirewallManager = new DeviceFirewallManager(); + this.mDeviceHwSystemManager = new DeviceHwSystemManager(); + this.mDeviceInfraredManager = new DeviceInfraredManager(); + this.mDeviceLocationManager = new DeviceLocationManager(); + this.mDeviceNetworkManager = new DeviceNetworkManager(); + this.mDeviceP2PManager = new DeviceP2PManager(); + this.mDevicePackageManager = new DevicePackageManager(); + this.mDevicePasswordManager = new DevicePasswordManager(); + this.mDevicePhoneManager = new DevicePhoneManager(); + this.mDeviceRestrictionManager = new DeviceRestrictionManager(); + this.mDeviceSettingsManager = new DeviceSettingsManager(); + this.mDeviceStorageManagerEx = new DeviceStorageManagerEx(); + this.mDeviceTelephonyManager = new DeviceTelephonyManager(); // this.mDeviceTelevisionManager = new DeviceTelevisionManager(); - this.mDeviceVpnManager = new DeviceVpnManager(); - this.mDeviceWifiPolicyManager = new DeviceWifiPolicyManager(); + this.mDeviceVpnManager = new DeviceVpnManager(); + this.mDeviceWifiPolicyManager = new DeviceWifiPolicyManager(); + } catch (Exception e) { + Log.e(TAG, "AdminManager: " + e.getMessage()); + } + + removeAllInstallPackageTrustList(); Log.e(TAG, "AdminManager: setCallStatusNotificationApp = " + setCallStatusNotificationApp(BuildConfig.APPLICATION_ID)); getCallStatusNotificationApp(); @@ -543,10 +549,12 @@ public class AdminManager { /** * 设置可信任应用列表 - * + * 3.11.9 ~ 3.11.23 接口为拆分了以上功能的各个接口,该接口和 3.11.9 ~ 3.11.23 接 + * 口不可同时使用。 * @param packageNames */ public void setSuperTrustListForHwSystemManger(ArrayList packageNames) { + Log.e(TAG, "setSuperTrustListForHwSystemManger: " + packageNames); try { mDeviceHwSystemManager.setSuperTrustListForHwSystemManger(mAdminName, packageNames); } catch (Exception e) { @@ -564,6 +572,7 @@ public class AdminManager { } public void removeSuperTrustListForHwSystemManger(ArrayList packageNames) { + Log.e(TAG, "removeSuperTrustListForHwSystemManger: " + packageNames); try { mDeviceHwSystemManager.removeSuperTrustListForHwSystemManger(mAdminName, packageNames); } catch (Exception e) { @@ -666,17 +675,27 @@ public class AdminManager { public static Uri toUri(Context context, String filePath) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // return FileProvider.getUriForFile(context, context.getApplicationInfo().packageName + ".fileprovider", new File(filePath)); - return FileProvider.getUriForFile(context, "com.uiui.sn.fileprovider", new File(filePath)); + return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".FileProvider", new File(filePath)); } return Uri.fromFile(new File(filePath)); } private Set defaultAllowInstallPackages = new HashSet() {{ this.add(BuildConfig.APPLICATION_ID); + this.add("com.xwad.store"); this.add("com.uiui.aios"); this.add("com.uiui.appstore"); }}; + public void setInstallPackageDefaultTrustList(List packages) { + Log.e(TAG, "setInstallPackageDefaultTrustList: " + packages); + List trustList = new ArrayList<>(defaultAllowInstallPackages); + if (packages != null && !packages.isEmpty()) { + trustList.addAll(packages); + } + addInstallPackageTrustList(trustList); + } + public void addInstallPackageDefaultTrustList(List packages) { Log.e(TAG, "addInstallPackageDefaultTrustList: " + packages); removeAllInstallPackageTrustList(); @@ -755,11 +774,12 @@ public class AdminManager { * @param filePath */ public void installPackage(String filePath) { - try { - mDevicePackageManager.installPackage(mAdminName, filePath); - } catch (Exception e) { - Log.e(TAG, "installPackage: " + e.getMessage()); - } + Log.e(TAG, "installPackage: " + filePath); +// try { +// mDevicePackageManager.installPackage(mAdminName, filePath); +// } catch (Exception e) { +// Log.e(TAG, "installPackage: " + e.getMessage()); +// } Uri contentUri = toUri(mContext, filePath); mContext.grantUriPermission("android", contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); String uriPath = contentUri.toString(); @@ -1718,6 +1738,7 @@ public class AdminManager { } } + @Deprecated public void addAlertWindowApps(ArrayList appList) { try { int sdk_int = Utils.getMagicOsVersion(); diff --git a/app/src/main/java/com/xwad/os/network/NetInterfaceManager.java b/app/src/main/java/com/xwad/os/network/NetInterfaceManager.java index a0fb998..28c8b0d 100644 --- a/app/src/main/java/com/xwad/os/network/NetInterfaceManager.java +++ b/app/src/main/java/com/xwad/os/network/NetInterfaceManager.java @@ -2,9 +2,20 @@ package com.xwad.os.network; import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Environment; +import android.text.TextUtils; import android.util.Log; +import androidx.core.content.ContextCompat; + import com.google.gson.Gson; +import com.google.gson.JsonObject; import com.google.gson.reflect.TypeToken; import com.tencent.mmkv.MMKV; import com.trello.rxlifecycle4.RxLifecycle; @@ -15,6 +26,7 @@ import com.xwad.os.alarm.AlarmUtils; import com.xwad.os.bean.AlarmClockData; import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.AppUpdateInfo; +import com.xwad.os.bean.AppUploadInfo; import com.xwad.os.bean.BaseResponse; import com.xwad.os.bean.CodeBean; import com.xwad.os.bean.GuideBean; @@ -26,40 +38,54 @@ import com.xwad.os.bean.LoginInfo; import com.xwad.os.bean.OrderInfo; import com.xwad.os.bean.PayInfo; import com.xwad.os.bean.PhraseContent; +import com.xwad.os.bean.ScreenPassword; import com.xwad.os.bean.SnInfo; import com.xwad.os.bean.StudyStatBean; import com.xwad.os.bean.SystemSettings; import com.xwad.os.bean.UserAvatarInfo; import com.xwad.os.bean.UserInfo; import com.xwad.os.bean.VipInfo; +import com.xwad.os.bean.WhoisBean; import com.xwad.os.config.CommonConfig; import com.xwad.os.disklrucache.CacheHelper; import com.xwad.os.gson.GsonUtils; -import com.xwad.os.manager.DeviceSNManager; +import com.xwad.os.manager.ControlManager; +import com.xwad.os.mdm.AdminManager; import com.xwad.os.network.api.AlarmClockApi; import com.xwad.os.network.api.AppApi; import com.xwad.os.network.api.AppUsageRecordApi; import com.xwad.os.network.api.FilesApi; +import com.xwad.os.network.api.GetWhoisApi; import com.xwad.os.network.api.HomeworkApi; import com.xwad.os.network.api.LoginApi; import com.xwad.os.network.api.PhraseApi; import com.xwad.os.network.api.SettingApi; import com.xwad.os.network.api.SnInfoApi; +import com.xwad.os.network.api.UploadAppImgApi; +import com.xwad.os.network.api.UploadScreenshot; import com.xwad.os.network.api.UserApi; import com.xwad.os.network.api.jxw.JxwApi; import com.xwad.os.network.api.uiuios.CheckUpdateApi; import com.xwad.os.network.interceptor.RepeatRequestInterceptor; +import com.xwad.os.service.ManagerService; import com.xwad.os.utils.ActivationUtil; +import com.xwad.os.utils.ApkUtils; +import com.xwad.os.utils.BitmapUtils; +import com.xwad.os.utils.CmdUtil; +import com.xwad.os.utils.JgyUtils; import com.xwad.os.utils.JxwUtils; import com.xwad.os.utils.OpenApkUtils; import com.xwad.os.utils.Utils; import java.io.File; +import java.io.FileNotFoundException; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -67,8 +93,12 @@ import java.util.stream.Collectors; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableEmitter; +import io.reactivex.rxjava3.core.ObservableOnSubscribe; +import io.reactivex.rxjava3.core.ObservableSource; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.functions.Function; import io.reactivex.rxjava3.schedulers.Schedulers; import io.reactivex.rxjava3.subjects.BehaviorSubject; import okhttp3.Cache; @@ -78,11 +108,14 @@ import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; +import retrofit2.Call; import retrofit2.Retrofit; import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; public class NetInterfaceManager { + private static final String TAG = "NetInterfaceManager"; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); @SuppressLint("StaticFieldLeak") @@ -97,6 +130,9 @@ public class NetInterfaceManager { private Retrofit mJxwRetrofit; private OkHttpClient mJxwOkHttpClient; + private Set mUploadIconPkgs; + private static final String uploadIconPkgsKey = "UPLOAD_ICON_PACKAGE_KEY"; + private final ConcurrentHashMap requestIdsMap = new ConcurrentHashMap<>(); //超时时间 private static final int TIME_OUT = 30; @@ -180,6 +216,9 @@ public class NetInterfaceManager { .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); } + + mUploadIconPkgs = mMMKV.decodeStringSet(uploadIconPkgsKey, new HashSet<>()); + Log.e("init", "NetInterfaceManager: mUploadIconPkgs = " + mUploadIconPkgs); } /** @@ -243,6 +282,7 @@ public class NetInterfaceManager { * @param pkg * @return */ + @Deprecated public Observable> getCheckUpdateObservable(String pkg) { return mUiuiosRetrofit.create(CheckUpdateApi.class) .checkUpdate(pkg) @@ -259,6 +299,22 @@ public class NetInterfaceManager { return mRetrofit.create(AppUsageRecordApi.class); } + public UploadScreenshot getUploadScreenshotControl() { + return mRetrofit.create(UploadScreenshot.class); + } + + public SnInfoApi getSnInfoApi() { + return mRetrofit.create(SnInfoApi.class); + } + + public AppApi getAppApi() { + return mRetrofit.create(AppApi.class); + } + + public UploadAppImgApi getUploadAppImgApi() { + return mRetrofit.create(UploadAppImgApi.class); + } + /* * * Observable @@ -266,15 +322,15 @@ public class NetInterfaceManager { * */ public Observable> getSnInfoControl() { - return mRetrofit.create(SnInfoApi.class) - .getSninfo(DeviceSNManager.getDeviceSN()) + return getSnInfoApi() + .getSninfo(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getUserAvatarInfoControl() { - return mRetrofit.create(SnInfoApi.class) - .getUserAvatarInfo(DeviceSNManager.getDeviceSN()) + return getSnInfoApi() + .getUserAvatarInfo(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -282,21 +338,21 @@ public class NetInterfaceManager { public Observable getUpdateInfoObservable(Map params) { String json = GsonUtils.toJSONString(params); RequestBody body = convertToJsonRequestBody(json); - return mRetrofit.create(SnInfoApi.class) + return getSnInfoApi() .updateUserInfo(getToken(), body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getUpdateInfoObservable(Map params, MultipartBody.Part multipartBody) { - return mRetrofit.create(SnInfoApi.class) + return getSnInfoApi() .updateUserInfo(getToken(), params, multipartBody) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getupdateAvatarObservable(Map params, MultipartBody.Part multipartBody) { - return mRetrofit.create(SnInfoApi.class) + return getSnInfoApi() .updateAvatar(getToken(), params, multipartBody) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); @@ -304,21 +360,21 @@ public class NetInterfaceManager { public Observable getRunningAppObservable(String json) { return mRetrofit.create(AppUsageRecordApi.class) - .sendRunningInfo(DeviceSNManager.getDeviceSN(), json) + .sendRunningInfo(AdminManager.getInstance().getSerial(), json) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getCloudLessonObservable() { return mRetrofit.create(SettingApi.class) - .getCloudLessonSetting(DeviceSNManager.getDeviceSN()) + .getCloudLessonSetting(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getCloudLessonAppObservable() { return mRetrofit.create(SettingApi.class) - .getCloudLessonApp(DeviceSNManager.getDeviceSN()) + .getCloudLessonApp(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -326,28 +382,28 @@ public class NetInterfaceManager { public Observable>> getAlarmClockObservable() { return mRetrofit .create(AlarmClockApi.class) - .getAlarmClock(DeviceSNManager.getDeviceSN()) + .getAlarmClock(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getUpdateAlarmObservable(int id) { return mRetrofit.create(AlarmClockApi.class) - .updateAlarm(DeviceSNManager.getDeviceSN(), id) + .updateAlarm(AdminManager.getInstance().getSerial(), id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getStudyStatObservable() { - return mRetrofit.create(SnInfoApi.class) - .getStudyStat(DeviceSNManager.getDeviceSN()) + return getSnInfoApi() + .getStudyStat(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getUpdateAddressObservable(String address, double longitude, double latitude) { - return mRetrofit.create(SnInfoApi.class) - .updateAddress(getToken(), DeviceSNManager.getDeviceSN(), address, longitude, latitude) + return getSnInfoApi() + .updateAddress(getToken(), AdminManager.getInstance().getSerial(), address, longitude, latitude) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -361,46 +417,53 @@ public class NetInterfaceManager { public Observable>> getHomeworkObservable() { return mRetrofit.create(HomeworkApi.class) - .getHomeworks(DeviceSNManager.getDeviceSN()) + .getHomeworks(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getHomeworkDetailObservable(int id) { return mRetrofit.create(HomeworkApi.class) - .getHomeworkDetail(DeviceSNManager.getDeviceSN(), id) + .getHomeworkDetail(AdminManager.getInstance().getSerial(), id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getHomeworkUpdateObservable(int id) { return mRetrofit.create(HomeworkApi.class) - .updateHomework(DeviceSNManager.getDeviceSN(), id) + .updateHomework(AdminManager.getInstance().getSerial(), id) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getPhraseObservable() { return mRetrofit.create(PhraseApi.class) - .getPhrase(DeviceSNManager.getDeviceSN()) + .getPhrase(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getSettingControl() { return mRetrofit.create(SettingApi.class) - .getSetting(DeviceSNManager.getDeviceSN()) + .getSetting(AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getAdminAppObservable(String app_package) { - return mRetrofit.create(AppApi.class) + return getAppApi() .getAdminApp(BuildConfig.APPLICATION_ID, app_package) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } + public Observable> getUpdateObservable(String packageName) { + return getAppApi() + .getAppUpdate(packageName, "0", JgyUtils.getInstance().checkAppPlatform()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + public Observable getPhoneCodeObservable(String mobile) { return mRetrofit.create(LoginApi.class) .getCode(mobile) @@ -410,21 +473,21 @@ public class NetInterfaceManager { public Observable> getCodeLoginObservable(String mobile, String code) { return mRetrofit.create(LoginApi.class) - .codeLogin(mobile, code, DeviceSNManager.getDeviceSN()) + .codeLogin(mobile, code, AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getNewCodeLoginObservable(String mobile, String code) { return mRetrofit.create(LoginApi.class) - .newCodeLogin(mobile, code, "", BuildConfig.APPLICATION_ID) + .newCodeLogin(mobile, code, AdminManager.getInstance().getSerial(), BuildConfig.APPLICATION_ID) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getUserLoginObservable(String mobile, String password) { return mRetrofit.create(LoginApi.class) - .userLogin(mobile, password, DeviceSNManager.getDeviceSN()) + .userLogin(mobile, password, AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -445,32 +508,55 @@ public class NetInterfaceManager { public Observable> getBuyVipControl(String vipId) { return mRetrofit.create(UserApi.class) - .buyVip(getToken(), DeviceSNManager.getDeviceSN(), vipId) + .buyVip(getToken(), AdminManager.getInstance().getSerial(), vipId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getCodeActivationControl(String code) { return mRetrofit.create(UserApi.class) - .codeActivation(getToken(), DeviceSNManager.getDeviceSN(), code) + .codeActivation(getToken(), AdminManager.getInstance().getSerial(), code) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getActivationCodeControl() { return mRetrofit.create(UserApi.class) - .getActivationCode(getToken(), DeviceSNManager.getDeviceSN()) + .getActivationCode(getToken(), AdminManager.getInstance().getSerial()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getPayQrcodeControl(String orderSn) { return mRetrofit.create(UserApi.class) - .payQrcode(getToken(), DeviceSNManager.getDeviceSN(), orderSn) + .payQrcode(getToken(), AdminManager.getInstance().getSerial(), orderSn) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } + public Observable> getLockScreenPwdObservable() { + return getSnInfoApi() + .getLockScreenPwd(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable getUpdateLockScreenObservable() { + return mRetrofit.create(SnInfoApi.class) + .updateLockScreen(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable>> getAdminAppObservable() { + return mRetrofit.create(AppApi.class) + .getAdminApp(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + + public Observable getOauthTokenObservable() { Map params = new HashMap<>(); params.put("appId", JxwUtils.getAppId()); @@ -510,7 +596,7 @@ public class NetInterfaceManager { void onComplete(); } - public interface onCompleteCallback { + public interface OnCompleteCallback { void onComplete(); } @@ -646,12 +732,12 @@ public class NetInterfaceManager { return new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { - Log.e("getUserAvatarInfoControl", "onSubscribe: "); + Log.e("getUserAvatarInfo", "onSubscribe: "); } @Override public void onNext(@NonNull BaseResponse userAvatarInfoBaseResponse) { - Log.e("getUserAvatarInfoControl", "onNext: " + userAvatarInfoBaseResponse); + Log.e("getUserAvatarInfo", "onNext: " + userAvatarInfoBaseResponse); if (callback != null) { callback.setUserAvatarInfo(userAvatarInfoBaseResponse.data); } @@ -659,7 +745,7 @@ public class NetInterfaceManager { @Override public void onError(@NonNull Throwable e) { - Log.e("getUserAvatarInfoControl", "onError: " + e.getMessage()); + Log.e("getUserAvatarInfo", "onError: " + e.getMessage()); if (callback != null) { callback.setUserAvatarInfo(null); } @@ -668,17 +754,17 @@ public class NetInterfaceManager { @Override public void onComplete() { - Log.e("getUserAvatarInfoControl", "onComplete: "); + Log.e("getUserAvatarInfo", "onComplete: "); } }; } - public void getCloudLessonSettings(BehaviorSubject lifecycle, onCompleteCallback callback) { + public void getCloudLessonSettings(BehaviorSubject lifecycle, OnCompleteCallback callback) { Observable.zip(getCloudLessonObservable(), getCloudLessonAppObservable(), this::getLessonJson).compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) .subscribe(getCloudLessonSettingsObserver(callback)); } - public void getCloudLessonSettings(onCompleteCallback callback) { + public void getCloudLessonSettings(OnCompleteCallback callback) { Observable.zip(getCloudLessonObservable(), getCloudLessonAppObservable(), this::getLessonJson).subscribe(getCloudLessonSettingsObserver(callback)); } @@ -715,7 +801,7 @@ public class NetInterfaceManager { return lessonJson; } - public Observer getCloudLessonSettingsObserver(onCompleteCallback callback) { + public Observer getCloudLessonSettingsObserver(OnCompleteCallback callback) { return new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -746,13 +832,13 @@ public class NetInterfaceManager { } - public void getCloudLessonSetting(BehaviorSubject lifecycle, onCompleteCallback callback) { + public void getCloudLessonSetting(BehaviorSubject lifecycle, OnCompleteCallback callback) { getCloudLessonObservable() .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) .subscribe(getCloudLessonObserver(callback)); } - public void getCloudLessonSetting(onCompleteCallback callback) { + public void getCloudLessonSetting(OnCompleteCallback callback) { getCloudLessonObservable() .subscribe(getCloudLessonObserver(callback)); } @@ -762,7 +848,7 @@ public class NetInterfaceManager { .subscribe(getCloudLessonObserver(null)); } - private Observer> getCloudLessonObserver(onCompleteCallback callback) { + private Observer> getCloudLessonObserver(OnCompleteCallback callback) { return new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -788,13 +874,13 @@ public class NetInterfaceManager { }; } - public void getCloudLessonApp(BehaviorSubject lifecycle, onCompleteCallback callback) { + public void getCloudLessonApp(BehaviorSubject lifecycle, OnCompleteCallback callback) { getCloudLessonAppObservable() .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) .subscribe(getCloudLessonAppObserver(callback)); } - public void getCloudLessonApp(onCompleteCallback callback) { + public void getCloudLessonApp(OnCompleteCallback callback) { getCloudLessonAppObservable() .subscribe(getCloudLessonAppObserver(callback)); } @@ -804,7 +890,7 @@ public class NetInterfaceManager { .subscribe(getCloudLessonAppObserver(null)); } - private Observer> getCloudLessonAppObserver(onCompleteCallback callback) { + private Observer> getCloudLessonAppObserver(OnCompleteCallback callback) { return new Observer>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -942,4 +1028,502 @@ public class NetInterfaceManager { } }; } + + public void updateAdminInfo() { + String address = String.valueOf(mMMKV.decodeString(CommonConfig.MAP_ADDRESS_KEY, "-")); + String longitude = String.valueOf(mMMKV.decodeString(CommonConfig.MAP_LONGITUDE_KEY, "0")); + String latitude = String.valueOf(mMMKV.decodeString(CommonConfig.MAP_LATITUDE_KEY, "0")); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("address", address); + jsonObject.addProperty("longitude", longitude); + jsonObject.addProperty("latitude", latitude); + JsonObject softwareJson = new JsonObject(); + // TODO: 2022/6/29 + softwareJson.addProperty("jpush_id", ""); + softwareJson.addProperty("updatetools_version", ApkUtils.getAPPVersionName(mContext, JgyUtils.PACKAGE_UPDATETOOLS)); + softwareJson.addProperty("jiaoguanyi_version", ApkUtils.getAPPVersionName(mContext, "com.jiaoguanyi.os")); + softwareJson.addProperty("gankao_version", ApkUtils.getAPPVersionName(mContext, "com.gankao.gkwxhd")); + softwareJson.addProperty("learning_version", ApkUtils.getAPPVersionName(mContext, "com.info.learning")); + softwareJson.addProperty("chat_version", ApkUtils.getAPPVersionName(mContext, "com.info.chat")); + + softwareJson.addProperty("appstore_version", ApkUtils.getAPPVersionName(mContext, JgyUtils.PACKAGE_APPSTORE)); + softwareJson.addProperty("info_version", ApkUtils.getAPPVersionName(mContext, JgyUtils.PACKAGE_DEVICEINFO)); + softwareJson.addProperty("browser_version", ApkUtils.getAPPVersionName(mContext, JgyUtils.PACKAGE_BROWSER)); + softwareJson.addProperty("notice_version", ApkUtils.getAPPVersionName(mContext, "com.uiui.info")); + softwareJson.addProperty("desktop_version", ApkUtils.getAPPVersionName(mContext,BuildConfig.APPLICATION_ID)); + + softwareJson.addProperty("appstore_install_time", ApkUtils.getAppLastUpdateTime(mContext, JgyUtils.PACKAGE_APPSTORE)); + softwareJson.addProperty("info_install_time", ApkUtils.getAppLastUpdateTime(mContext, JgyUtils.PACKAGE_DEVICEINFO)); + softwareJson.addProperty("browser_install_time", ApkUtils.getAppLastUpdateTime(mContext, JgyUtils.PACKAGE_BROWSER)); + softwareJson.addProperty("notice_install_time", ApkUtils.getAppLastUpdateTime(mContext, "com.uiui.info")); + softwareJson.addProperty("desktop_install_time", ApkUtils.getAppLastUpdateTime(mContext, BuildConfig.APPLICATION_ID)); + + String addr = jsonObject.toString(); + String machine = Utils.getMachine(mContext); + String hardware = Utils.getHardware(mContext); + String software = softwareJson.toString(); + if (BuildConfig.DEBUG) { + Log.e(TAG, "updateAdminInfo: address = " + jsonObject.toString()); + Log.e(TAG, "updateAdminInfo: machine = " + machine); + Log.e(TAG, "updateAdminInfo: getHardware = " + hardware); + Log.e(TAG, "updateAdminInfo: software = " + software); + } + getSnInfoApi().sendAdminSn( + Utils.getSerial(), + "", + machine, + hardware, + software + ).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("updateAdminInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("updateAdminInfo", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("updateAdminInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("updateAdminInfo", "onComplete: "); + } + }); + } + + + Set showPackages = new HashSet() {{ + this.add("com.uiui.os"); + this.add("com.uiui.info"); + this.add("com.uiui.health"); + this.add("com.uiui.city"); + this.add("com.uiui.videoplayer"); + + this.add("com.uiui.aios"); + this.add("com.uiui.sn"); + this.add("com.uiui.appstore"); + this.add("com.uiui.browser"); + + this.add("com.uiui.zyos"); + this.add("com.uiui.zy"); + this.add("com.uiui.zyappstore"); + this.add("com.uiui.zybrowser"); + this.add("com.uiui.zysn"); + +// this.add("com.jxw.launcher"); + //扶小鹰 +// this.add(JgyUtils.gkwxhd); +// this.add(JgyUtils.fuxiaoying); +// this.add(JgyUtils.moshujia); +// this.add(JgyUtils.english); +// this.add(JgyUtils.zhiduoke); +// this.add(JgyUtils.aobama); +// this.add(JgyUtils.growthspace); + this.add("com.tencent.android.qqdownloader"); + this.add("org.chromium.browser"); + }}; + + Set hidePackages = new HashSet() {{ + this.add("com.android.quicksearchbox"); + this.add("com.oirsdfg89.flg"); + }}; + + Set showSystemApps = new HashSet() {{ + this.add("com.android.gallery3d"); + this.add("com.android.documentsui"); + this.add("org.chromium.browser"); + + }}; + + public static long getPackageSize(Context context, String filePath) { + long size = new File(filePath).length(); + return size; + } + + /** + * 发送app安装情况 + */ + public void SendAppInstallInfo() { + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(@NonNull ObservableEmitter emitter) throws Throwable { + Set adminAppSet = mMMKV.decodeStringSet(CommonConfig.ADMIN_APP_LIST, new HashSet<>()); + PackageManager pm = mContext.getPackageManager(); + List installedPackages = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); + List uploadInfos = new ArrayList<>(); + Intent intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + List appsWithLauncher = pm.queryIntentActivities(intent, 0); + Log.e("SendAppInstallInfo", "appsWithLauncher: " + appsWithLauncher); + List pkgs = new ArrayList<>(); + for (PackageInfo packageInfo : installedPackages) { + if (pm.getApplicationEnabledSetting(packageInfo.packageName) == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { + pkgs.add(packageInfo.packageName); + } + } + for (ResolveInfo info : appsWithLauncher) { + pkgs.add(info.activityInfo.packageName); + } + Log.e("SendAppInstallInfo", "pkgs: " + pkgs); + + for (PackageInfo info : installedPackages) { + Log.i("SendAppInstallInfo", "info: " + info.packageName); + //排除掉部分系统应用 + if (ApkUtils.isSystemApp(mContext, info.packageName)) { + if (!showSystemApps.contains(info.packageName)) { + continue; + } + } + //排除掉没有图标的应用 + if (!pkgs.contains(info.packageName) && !showPackages.contains(info.packageName)) { + continue; + } + if (hidePackages.contains(info.packageName)) { + continue; + } + Log.e("SendAppInstallInfo", "info: " + info.packageName); + AppUploadInfo uploadInfo = new AppUploadInfo(); + uploadInfo.setApp_name(info.applicationInfo.loadLabel(pm).toString()); + uploadInfo.setApp_package(info.packageName); + uploadInfo.setApp_version_name(info.versionName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + uploadInfo.setApp_version_code(info.getLongVersionCode()); + } else { + uploadInfo.setApp_version_code(info.versionCode); + } + uploadInfo.setFirstInstallTime(info.firstInstallTime / 1000); + uploadInfo.setLastUpdateTime(info.lastUpdateTime / 1000); + uploadInfo.setApp_size(getPackageSize(mContext, info.applicationInfo.publicSourceDir)); + uploadInfo.setSource(adminAppSet.contains(info.packageName) ? 1 : 0); + uploadInfos.add(uploadInfo); + } + String json = GsonUtils.toJSONString(uploadInfos); + emitter.onNext(json); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .concatMap(new Function>() { + @Override + public ObservableSource apply(String s) throws Throwable { + Log.e("SendAppInstallInfo", "apply: " + s); + return getAppApi() + .installorRemove(Utils.getSerial(), s); + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("SendAppInstallInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("SendAppInstallInfo", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("SendAppInstallInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("SendAppInstallInfo", "onComplete: "); + } + }); + uploadAppIcon(); + } + + private List zyApp = new ArrayList() {{ + this.add("com.uiui.browser"); + this.add("com.uiui.zyappstore"); + this.add("com.uiui.zybrowser"); + }}; + + private void uploadAppIcon() { + PackageManager pm = mContext.getPackageManager(); + List packageInfos = pm.getInstalledPackages(0); + Log.e(TAG, "uploadAppIcon: packageInfos = " + packageInfos); + Intent intent = new Intent(Intent.ACTION_MAIN, null); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + List appsWithLauncher = pm.queryIntentActivities(intent, 0); + List allLauncherPkgs = appsWithLauncher.stream().map(resolveInfo -> resolveInfo.activityInfo.packageName).collect(Collectors.toList()); + allLauncherPkgs.addAll(zyApp); + Log.e(TAG, "uploadAppIcon: allLauncherPkgs = " + allLauncherPkgs); + List filter = packageInfos.stream().filter(packageInfo -> allLauncherPkgs.contains(packageInfo.packageName)).collect(Collectors.toList()); + Log.e(TAG, "uploadAppIcon: filter = " + filter); + for (PackageInfo packageInfo : filter) { + if (!mUploadIconPkgs.contains(packageInfo.packageName)) { + Drawable drawable = packageInfo.applicationInfo.loadIcon(pm); + File file = BitmapUtils.drawableToFile(mContext, drawable, packageInfo.packageName); + //File转RequestBody + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody fileBody = RequestBody.Companion.create(file, mediaType); + //设置一个file文件 + MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), fileBody); + Map params = new HashMap<>(); + params.put("package", NetInterfaceManager.convertToRequestBody(packageInfo.packageName)); + Call call = getUploadAppImgApi().uploadAppImg(Utils.getSerial(), params, body); + call.enqueue(new RetryCallback(call, 1, 30 * 1000) { + @Override + public void onRequestResponse(Call call, retrofit2.Response response) { + BaseResponse baseResponse = (BaseResponse) response.body(); + Log.e("addIcon", "onRequestResponse: " + baseResponse); + if (baseResponse.code == 200 || baseResponse.code == 401) { + addIcon(packageInfo.packageName); + } + } + + @Override + public void onRequestFail(Call call, Throwable t) { + Log.e("addIcon", "onRequestFail: "); + } + + @Override + public void onStartRetry() { + Log.e("addIcon", "onStartRetry: "); + } + }); + } else { + Log.e("addIcon", "updateAppInstall: upload " + packageInfo.packageName); + } + } + } + + public void addIcon(String pkg) { + mUploadIconPkgs.add(pkg); + mMMKV.encode(uploadIconPkgsKey, mUploadIconPkgs); + Log.e("addIcon", "addIcon: " + mMMKV.decodeString(uploadIconPkgsKey)); + } + + public void screenshot() { +// String path = mContext.getExternalFilesDir("db").getAbsolutePath(); + String path = ContextCompat.getExternalFilesDirs(mContext, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath(); + String filePath = path + File.separator + Utils.getSerial() + ".png"; + getScreenshot(filePath).concatMap(new Function>() { + @Override + public ObservableSource apply(Integer integer) throws Exception { + if (integer != 0) { + throw new FileNotFoundException(); + } + File file = new File(filePath); + if (!file.exists()) { + throw new FileNotFoundException(filePath); + } +// Bitmap bitmap = BitmapFactory.decodeFile(filePath); +// if (bitmap.getWidth() < bitmap.getHeight()) { +// bitmap = ImageUtils.rotate(bitmap, -90, bitmap.getWidth(), bitmap.getHeight()); +// } +// ByteArrayOutputStream baos = new ByteArrayOutputStream(); +// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); +// file.createNewFile(); +// FileOutputStream fos = new FileOutputStream(file); +// InputStream is = new ByteArrayInputStream(baos.toByteArray()); +// int x; +// byte[] b = new byte[1024 * 100]; +// while ((x = is.read(b)) != -1) { +// fos.write(b, 0, x); +// } +// fos.close(); + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody requestBody = RequestBody.Companion.create(file, mediaType); + MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestBody); + return getSendFile(filePath, body); + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("screenshot", "onSubscribe: "); + } + + @Override + public void onNext(BaseResponse baseResponse) { + Log.e("screenshot", "onNext: " + baseResponse); + } + + @Override + public void onError(Throwable e) { + Log.e("screenshot", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("screenshot", "onComplete: "); + } + }); + } + + private Observable getScreenshot(String filePath) { + Observable screenshotObservable = Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter e) { + int code = CmdUtil.execute("screencap -p " + filePath).code; + e.onNext(code); + e.onComplete(); + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + return screenshotObservable; + } + + private Observable getSendFile(String path, MultipartBody.Part body) { + return getUploadScreenshotControl() + .getControlScreenshot(Utils.getSerial(), body) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public static final String WHOIS_IP = "whois_ip_addr"; + + public interface PublicIpCallbak { + void getPublicIp(String ip); + } + + public void getPublicIp(BehaviorSubject lifecycle, PublicIpCallbak callbak) { + Retrofit retrofit = new Retrofit.Builder() + .client(NetInterfaceManager.getInstance().getOkHttpClient()) + .baseUrl(UrlAddress.PCONLINE_WHOIS) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) + .build(); + retrofit.create(GetWhoisApi.class) + .getWhois(true) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getPublicIp", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull WhoisBean whoisBean) { + Log.e("getPublicIp", "onNext: " + whoisBean); + if (whoisBean != null && !TextUtils.isEmpty(whoisBean.getIp())) { + callbak.getPublicIp(whoisBean.getIp()); + mMMKV.encode(NetInterfaceManager.WHOIS_IP, whoisBean.getIp()); + } else { + callbak.getPublicIp("unknown"); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getPublicIp", "onError: "); + callbak.getPublicIp("unknown"); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getPublicIp", "onComplete: "); + } + }); + } + + + public void getLockScreenPwd(BehaviorSubject lifecycle, OnCompleteCallback callback) { + getLockScreenPwdObservable() + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(getLockScreenPwdObserver(callback)); + } + + public void getLockScreenPwd(OnCompleteCallback callback) { + getLockScreenPwdObservable() + .subscribe(getLockScreenPwdObserver(callback)); + } + + public void getLockScreenPwd() { + getLockScreenPwdObservable() + .subscribe(getLockScreenPwdObserver(null)); + } + + private Observer> getLockScreenPwdObserver(OnCompleteCallback callback) { + return new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getLockScreenPwdObserver", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse screenPasswordBaseResponse) { + Log.e("getLockScreenPwdObserver", "onNext: " + screenPasswordBaseResponse); + if (screenPasswordBaseResponse.code == 200) { + ScreenPassword screenPassword = screenPasswordBaseResponse.data; + if (screenPassword == null || TextUtils.isEmpty(screenPassword.getPwd())) { + mCacheHelper.put(UrlAddress.LOCK_SCREEN_PWD, ""); + } else { + mCacheHelper.put(UrlAddress.LOCK_SCREEN_PWD, GsonUtils.toJSONString(screenPassword)); + mMMKV.encode(ManagerService.LOCK_SCREEN_PASSWORD, screenPassword.getPwd()); + } + } else { + mCacheHelper.put(UrlAddress.LOCK_SCREEN_PWD, ""); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getLockScreenPwdObserver", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getLockScreenPwdObserver", "onComplete: "); + if (callback != null) { + callback.onComplete(); + } + } + }; + } + + public void getSystemSettings() { + getSettingControl() + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getSystemSettings", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseresponse) { + Log.e("getSystemSettings", "onNext: " + baseresponse); + int code = baseresponse.code; + if (code == 200) { + String data = new Gson().toJson(baseresponse.data); + ControlManager.getInstance().setSystemSetting(data); + mCacheHelper.put(UrlAddress.GET_SETTINGS, GsonUtils.toJSONString(baseresponse.data)); + } else { + ControlManager.getInstance().setDisableSetting(); + mCacheHelper.put(UrlAddress.GET_SETTINGS, ""); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getSystemSettings", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getSystemSettings", "onComplete: "); + } + }); + } + } diff --git a/app/src/main/java/com/xwad/os/network/RetryCallback.java b/app/src/main/java/com/xwad/os/network/RetryCallback.java new file mode 100644 index 0000000..a7f47f3 --- /dev/null +++ b/app/src/main/java/com/xwad/os/network/RetryCallback.java @@ -0,0 +1,92 @@ +package com.xwad.os.network; + +import android.util.Log; + +import java.util.Timer; +import java.util.TimerTask; + +import io.reactivex.rxjava3.annotations.NonNull; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public abstract class RetryCallback implements Callback { + + private static final String TAG = "RetryCallback"; + + private int mRetryCount; + private long mRetryInterval; + + private int mCurrentRetryCount; + + private boolean isExecuting; + + private Call mCall; + + private Timer timer = new Timer(); + + public RetryCallback(Call call, int retryCount, long retryInterval) { + isExecuting = true; + mCall = call; + mRetryCount = retryCount; + mRetryInterval = retryInterval; + } + + @Override + public final void onResponse(@NonNull Call call, @NonNull Response response) { + Log.e(TAG, "onResponse"); + isExecuting = false; + if (!response.isSuccessful() && mCurrentRetryCount < mRetryCount) { + mCurrentRetryCount++; + retryRequest(call); + } else { + onRequestResponse(call, response); + } + } + + @Override + public final void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e(TAG, "onFailure"); + isExecuting = false; + if (mCurrentRetryCount < mRetryCount) { + mCurrentRetryCount++; + Log.e(TAG, "onFailure: " + "RetryCount: " + mCurrentRetryCount); + Log.e(TAG, "onFailure: " + "RetryResponse: " + call.request()); + retryRequest(call); + } else { + onRequestFail(call, t); + } + } + + private void retryRequest(final Call call) { + Log.e(TAG, "retryRequest"); + onStartRetry(); + TimerTask timerTask = new TimerTask() { + @Override + public void run() { + synchronized (RetryCallback.this) { + mCall = call.clone(); + mCall.enqueue(RetryCallback.this); + isExecuting = true; + } + } + }; + timer.schedule(timerTask, mRetryInterval); + } + + public void cancelCall() { + synchronized (this) { + if (!isExecuting) { + timer.cancel(); + } else { + mCall.cancel(); + } + } + } + + public abstract void onRequestResponse(Call call, Response response); + + public abstract void onRequestFail(Call call, Throwable t); + + public abstract void onStartRetry(); +} \ No newline at end of file diff --git a/app/src/main/java/com/xwad/os/network/UrlAddress.java b/app/src/main/java/com/xwad/os/network/UrlAddress.java index 75bdd63..a5922c5 100644 --- a/app/src/main/java/com/xwad/os/network/UrlAddress.java +++ b/app/src/main/java/com/xwad/os/network/UrlAddress.java @@ -37,7 +37,15 @@ public class UrlAddress { /*获取管理员所有应用*/ public final static String GET_ADMIN_APP = "getAdminApp"; public final static String APP_FORCE_INSTALL = "app/force-install"; + /*根据包名获取更新*/ + public final static String GET_NEWEST_APPUPDATE = "app/newestAppUpdate"; + /*发送卸载或者安装信息*/ + public final static String SEND_INSTALLEDORREMOVED = "app/addAppInstall"; + /*上传应用图标*/ + public static final String UPLOAD_APP_IMG = "collectData/uploadAppImg"; + /*获取应用库是否有图标*/ + public static final String GET_IS_APP_IMG = "collectData/getIsAppImg"; /*设备信息接口*/ public static final String SNINFO = "sn/getSnInfo"; @@ -47,6 +55,22 @@ public class UrlAddress { public static final String UPDATE_INFO = "sn/update-info"; /*更新头像*/ public static final String UPDATE_avatar = "sn/avatar"; + /*发送设备基本信息*/ + public final static String UPDATE_SNINFO = "sn/updateAdminSn"; + /*获取屏幕管控*/ + public final static String GET_SCREEN_LOCK = "sn/getScreenshot"; + /*获取锁屏密码*/ + public static final String LOCK_SCREEN_PWD = "sn/getLockScreenPwd"; + /*解除锁屏*/ + public static final String UPDATE_LOCK_SCREEN = "sn/updateLockScreen"; + + /*上传屏幕截图*/ + public final static String UPLOAD_SCREEN_SNAPSHOT = "sn/uploadScreenshot"; + /*上传控制面版截图*/ + public static final String UPLOAD_CONTROL_SCREENSHOT = "sn/uploadControlScreenshot"; + + + /*获取统计*/ public static final String GET_STUDY_STAT = "Sn/getStudyStat"; @@ -57,6 +81,7 @@ public class UrlAddress { public static final String APP_USAGE_RECORD = "appUsageRecord"; /*正在运行的应用*/ public static final String RUN_NEW_APP = "app/runNewApp"; + /*获取闹钟*/ public static final String GET_ALARM_CLOCK = "getAlarmClock"; /*爱心提醒通知成功*/ @@ -84,6 +109,7 @@ public class UrlAddress { public static final String UIUIOS_ROOT_URL = "https://map.uiuios.com/android/"; /*获取应用更新*/ + @Deprecated public static final String CHECK_UPDATE = "app/check-update"; public static final String JXW_BASE_URL = "https://openapi.jxwxxkj.com/"; @@ -92,5 +118,9 @@ public class UrlAddress { /*控制/设备端-查看答疑管控状态*/ public static final String answer_Control_status = "api/jxwdevice/answerControl/status"; + /*通过ip获取信息*/ + public static final String PCONLINE_WHOIS = "http://whois.pconline.com.cn/"; + public static final String WHOIS = "ipJson.jsp"; + } diff --git a/app/src/main/java/com/xwad/os/network/api/AppApi.java b/app/src/main/java/com/xwad/os/network/api/AppApi.java index 38a6b9e..51e8c1e 100644 --- a/app/src/main/java/com/xwad/os/network/api/AppApi.java +++ b/app/src/main/java/com/xwad/os/network/api/AppApi.java @@ -4,8 +4,13 @@ import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.BaseResponse; import com.xwad.os.network.UrlAddress; +import java.util.List; + import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; +import retrofit2.http.POST; import retrofit2.http.Query; public interface AppApi { @@ -15,4 +20,22 @@ public interface AppApi { @Query("app_package") String app_package ); + @GET(UrlAddress.GET_NEWEST_APPUPDATE) + Observable> getAppUpdate( + @Query("packageName") String packageName, + @Query("versionCode") String versionCode, + @Query("type") int type + ); + + @FormUrlEncoded + @POST(UrlAddress.SEND_INSTALLEDORREMOVED) + Observable installorRemove( + @Field("sn") String sn, + @Field("app") String jsonString + ); + + @GET(UrlAddress.GET_ADMIN_APP) + Observable>> getAdminApp( + @Query("sn") String sn + ); } diff --git a/app/src/main/java/com/xwad/os/network/api/GetWhoisApi.java b/app/src/main/java/com/xwad/os/network/api/GetWhoisApi.java new file mode 100644 index 0000000..8a1a373 --- /dev/null +++ b/app/src/main/java/com/xwad/os/network/api/GetWhoisApi.java @@ -0,0 +1,22 @@ +package com.xwad.os.network.api; + +import com.xwad.os.bean.WhoisBean; +import com.xwad.os.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +/** + * @author : fanhuitong + * e-mail : + * @date : 2021/10/1814:39 + * desc : + * version: 1.0 + */ +public interface GetWhoisApi { + @GET(UrlAddress.WHOIS) + Observable getWhois( + @Query("json") boolean json + ); +} diff --git a/app/src/main/java/com/xwad/os/network/api/SnInfoApi.java b/app/src/main/java/com/xwad/os/network/api/SnInfoApi.java index 77e48fe..f61e25e 100644 --- a/app/src/main/java/com/xwad/os/network/api/SnInfoApi.java +++ b/app/src/main/java/com/xwad/os/network/api/SnInfoApi.java @@ -1,6 +1,7 @@ package com.xwad.os.network.api; import com.xwad.os.bean.BaseResponse; +import com.xwad.os.bean.ScreenPassword; import com.xwad.os.bean.SnInfo; import com.xwad.os.bean.StudyStatBean; import com.xwad.os.bean.UserAvatarInfo; @@ -71,4 +72,30 @@ public interface SnInfoApi { @Field("latitude") double latitude ); + @FormUrlEncoded + @POST(UrlAddress.UPDATE_SNINFO) + Observable sendAdminSn( + @Field("sn") String sn, + @Field("address") String address, + @Field("machine") String machine, + @Field("hardware") String hardware, + @Field("software") String software + ); + + @GET(UrlAddress.GET_SCREEN_LOCK) + Observable getScreenshot( + @Query("sn")String sn + ); + + @GET(UrlAddress.LOCK_SCREEN_PWD) + Observable> getLockScreenPwd( + @Query("sn") String sn + ); + + @FormUrlEncoded + @POST(UrlAddress.UPDATE_LOCK_SCREEN) + Observable updateLockScreen( + @Field("sn") String sn + ); + } diff --git a/app/src/main/java/com/xwad/os/network/api/UploadAppImgApi.java b/app/src/main/java/com/xwad/os/network/api/UploadAppImgApi.java new file mode 100644 index 0000000..abb5da2 --- /dev/null +++ b/app/src/main/java/com/xwad/os/network/api/UploadAppImgApi.java @@ -0,0 +1,25 @@ +package com.xwad.os.network.api; + +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.network.UrlAddress; + +import java.util.Map; + +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.PartMap; +import retrofit2.http.Query; + +public interface UploadAppImgApi { + @Multipart + @POST(UrlAddress.UPLOAD_APP_IMG) + Call uploadAppImg( + @Query("sn") String sn, + @PartMap Map params, + @Part MultipartBody.Part file + ); +} diff --git a/app/src/main/java/com/xwad/os/network/api/UploadScreenshot.java b/app/src/main/java/com/xwad/os/network/api/UploadScreenshot.java new file mode 100644 index 0000000..42bd5c6 --- /dev/null +++ b/app/src/main/java/com/xwad/os/network/api/UploadScreenshot.java @@ -0,0 +1,35 @@ +package com.xwad.os.network.api; + +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import okhttp3.MultipartBody; +import retrofit2.Call; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.Query; + +public interface UploadScreenshot { + @Multipart + @POST(UrlAddress.UPLOAD_SCREEN_SNAPSHOT) + Observable uploadScreenshot( + @Query("sn") String sn, + @Part MultipartBody.Part file + ); + + @Multipart + @POST(UrlAddress.UPLOAD_SCREEN_SNAPSHOT) + Call uploadScreenshotCall( + @Query("sn") String sn, + @Part MultipartBody.Part file + ); + + @Multipart + @POST(UrlAddress.UPLOAD_CONTROL_SCREENSHOT) + Observable getControlScreenshot( + @Query("sn") String sn, + @Part MultipartBody.Part body + ); +} diff --git a/app/src/main/java/com/xwad/os/permission/PermissionUtils.java b/app/src/main/java/com/xwad/os/permission/PermissionUtils.java new file mode 100644 index 0000000..3b4fecd --- /dev/null +++ b/app/src/main/java/com/xwad/os/permission/PermissionUtils.java @@ -0,0 +1,20 @@ +package com.xwad.os.permission; + +import com.hjq.permissions.Permission; + +public class PermissionUtils { + public static final String[] PERMISSIONS = new String[]{ + Permission.CAMERA, + Permission.READ_PHONE_STATE, +// Permission.READ_SMS, + Permission.READ_PHONE_NUMBERS, + Permission.WRITE_EXTERNAL_STORAGE, + Permission.READ_EXTERNAL_STORAGE, + Permission.WRITE_SETTINGS, +// Permission.SYSTEM_ALERT_WINDOW, + Permission.ACCESS_FINE_LOCATION, + Permission.ACCESS_COARSE_LOCATION, +// Permission.ACCESS_BACKGROUND_LOCATION, +// Permission.REQUEST_INSTALL_PACKAGES + }; +} diff --git a/app/src/main/java/com/xwad/os/push/PushManager.java b/app/src/main/java/com/xwad/os/push/PushManager.java index be2a6ee..4d97f78 100644 --- a/app/src/main/java/com/xwad/os/push/PushManager.java +++ b/app/src/main/java/com/xwad/os/push/PushManager.java @@ -4,17 +4,61 @@ import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.graphics.Bitmap; +import android.os.PowerManager; +import android.text.TextUtils; +import android.util.Log; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.tencent.mmkv.MMKV; +import com.xwad.os.BuildConfig; import com.xwad.os.activity.home.HomeActivity; +import com.xwad.os.activity.homework.HomeworkDetailsActivity; +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.config.CommonConfig; import com.xwad.os.disklrucache.CacheHelper; import com.xwad.os.fragment.user.UserFragment; +import com.xwad.os.gson.GsonUtils; +import com.xwad.os.manager.ControlManager; +import com.xwad.os.mdm.AdminManager; import com.xwad.os.network.NetInterfaceManager; import com.hjq.toast.Toaster; +import com.xwad.os.network.RetryCallback; +import com.xwad.os.service.ManagerService; +import com.xwad.os.service.main.MainService; +import com.xwad.os.utils.ApkUtils; +import com.xwad.os.utils.BitmapUtils; +import com.xwad.os.utils.JgyUtils; +import com.xwad.os.utils.ServiceAliveUtils; +import com.xwad.os.utils.Utils; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableEmitter; +import io.reactivex.rxjava3.core.ObservableOnSubscribe; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.Response; public class PushManager { private static final String TAG = "PushManager"; public static final String SET_ALARMCLOCK = "zuoyeos.action.change.alarmclaock"; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); @SuppressLint("StaticFieldLeak") @@ -45,10 +89,186 @@ public class PushManager { return sInstance; } + + //1.获取设备在线信息 + private static final String GET_DRIVELINE = "1"; + // 2.获取当前正在运行得应用和电量 + private static final String GET_STARTTIME = "2"; + // 3.数据线传输管控 + private static final String USB_STATE = "3"; + // 4.TF卡管控 + private static final String TFCARD_STATE = "4"; + // 5.蓝牙管控 + private static final String BLUETOOTH_STATE = "5"; + // 6.浏览器上网管控 + private static final String BROWSER_URLPATH = "6"; + // 7.应用联网管控 + private static final String APP_NETWORKSTATE = "7"; + // 8.应用锁管控 + private static final String APP_LOCKEDSTATE = "8"; + // 9.强制安装应用 + private static final String FORCE_INSTALLAPK = "9"; + // 10.强制卸载应用 + private static final String FORCE_UNINSTALLAPK = "10"; + // 11.绑定设备 + private static final String BIND_DEVIVES = "11"; + //12.影音格式管控 + private static final String TFMEDIA = "12"; + //13.摄像头管控 + private static final String CAMRERA = "13"; + //14.电话管控管控 + private static final String PHONE = "14"; + //15.禁止升级 + private static final String DISABLE_UPDATAE = "15"; + //16.app内部网址管控 + private static final String APP_WEBSITE = "16"; + //设备恢复出厂设置 + private static final String RESET_DEVICES = "17"; + //浏览器书签 + private static final String BROWSER_LABEL = "18"; + //APP联网自启管控 + private static final String APP_NET_AUTO = "19"; + //系统管控 + private static final String SYSTEM_SETTING = "21"; + //重启 + private static final String REBOOT_DEVICES = "22"; + //获取app管控设置 + private static final String APP_SETTING = "23"; + //强制停止应用 + private static final String FORCE_KILL = "24"; + //锁屏 + private static final String LOCK_SCREEN = "25"; + //截图 + private static final String SNAPSHOT = "26"; + //时间管控 + private static final String JIGUANG_TIME_CONTROL = "27"; + //热点管控 + private static final String HOTSPOT_CONTROL = "29"; + //禁止恢复出厂设置 + private static final String RESTORE_CONTROL = "30"; + //浏览器禁止输入 + private static final String BROWSER_CONTROL = "32"; + //开发人员选项 + private static final String DEVELOPER_CONTROL = "33"; + //清除应用缓存 + private static final String CLEAN_APP_CACHE = "34"; + //几个桌面图标 + private static final String APP_RECORDER = "35"; + private static final String APP_FILE_MANAGER = "36"; + private static final String APP_GALLERY = "37"; + private static final String APP_MUSIC = "38"; + private static final String APP_BROWSER = "43"; + //搜题开关 + private static final String SEARCH_TOPIC = "39"; + //电话白名单推送 + private static final String PHONE_LIST = "40"; + //调整套餐 + private static final String CHANGE_COMBO = "41"; + //取消所有套餐 + private static final String CANCEL_COMBO = "42"; + //升级套餐 + private static final String UPGRADE_COMBO = "44"; + //设备授权和解除 + private static final String BIND_UNBIND = "45"; + //飞行模式 + private static final String FLIGHT_MODE = "47"; + //勿扰模式 + private static final String NOTDISTURB_MODE = "48"; + //定位 + private static final String LOCATION = "49"; + //充电提醒 + private static final String CHARGING_REMINDER = "50"; + //显示用户下载的应用 + private static final String SHOW_THIRD_APP = "51"; + //音量调节 + private static final String VOLUME = "52"; + //亮度调节 + private static final String LUMINANCE = "53"; + //字体大小调节 + private static final String TYPEFACE = "54"; + //自动旋转 + private static final String SCREEN_ROTATION = "55"; + //WiFi设置 + private static final String WIFI_SET = "56"; //闹钟 - private static final String JIGUANG_ALARM_CLOCK = "57"; + private static final String ALARM_CLOCK = "57"; + //应用白名单 + private static final String APP_WHITELIST = "58"; + //隐藏图标 + private static final String HIDE_APPICON = "59"; + //优化内存 + private static final String KILL_APP = "60"; + //SOS联系人 + private static final String SOS_PHONENUM = "61"; + //重新安装应用 + private static final String REINSTALL_APP = "62"; + //显示所有的admin应用 + private static final String ADMIN_APP = "63"; /*网课模式*/ private static final String ONLINE_COURSE_MODE = "71"; + /*投屏开关*/ + private static final String SCRENN_SHARED = "74"; + /*移动热点开关*/ + private static final String HOT_SPOT = "75"; + /*桌面默认应用*/ + private static final String ACTION_DEFAULT_DESKTOP = "76"; + /*浏览器默认应用*/ + private static final String ACTION_DEFAULT_BRPWSER = "77"; + /*输入法默认应用*/ + private static final String ACTION_DEFAULT_INPUT_METHOD = "78"; + /*家长管控开关*/ + private static final String ACTION_PARENTAL_CONTROL = "79"; + /*更新白名单*/ + private static final String UPDATE_WHITE_LIST = "83"; + /*应用市场下载管控*/ + private static final String STORE_INSTALL = "85"; + /*管理员设置*/ + private static final String ADMIN_SN_SETTING = "87"; + /*安装小程序上传应用*/ + private static final String FORCE_INSTALL_WECHAT_RUL = "88"; + + private static final String UNBIND_DEVICES = "90"; + /*快捷应用*/ + private static final String SET_QUICKAPP = "91"; + /*应用市场安装开关*/ + private static final String APP_INSTALL_SWITCH = "93"; + /*时间控制*/ + private static final String TIME_CONTROL = "94"; + //浏览器禁止输入 + private static final String BROWSER_CONTROL2 = "98"; + /*更新设备信息*/ + private static final String UPDATE_INFO = "99"; + /*清除激活推送*/ + private static final String UNBIND_DEVICE = "100"; + /*返回安卓界面*/ + private static final String GO_ANDROID = "101"; + /*九学王激活*/ + private static final String ACTIVATION_JXW = "102"; + /*更新锁屏密码*/ + private static final String UPGRADE_PASSWD = "103"; + /*前置拍照*/ + private static final String TAKE_FRONT_PICTURE = "104"; + /*同意申请安装*/ + private static final String ALLOW_APP_INSTALL = "107"; + /*USB文件传输开关*/ + private static final String USB_TRANSFER = "108"; + /*蓝牙文件传输开关*/ + private static final String BLUETOOTH_TRANSFER = "109"; + /*开发者模式开关*/ + private static final String DEVELOPER_MODE = "110"; + /*设备恢复出厂开关*/ + private static final String RESTORE_FACTORY_MODE = "111"; + /*顶部通知栏开关*/ + private static final String ACTION_BAR_MODE = "112"; + /*底部导航条开关*/ + private static final String NAVIGATION_BAR_MODE = "113"; + /*顶部通知栏开关 */ + private static final String NOTIFY_BAR_SHOW = "114"; + /*上传截图并刷新接口*/ + private static final String REFRESH_NETWORK = "116"; + /*禁止联网APP设置*/ + private static final String DISALLOW_APP_NETWORK = "117"; + /*付款成功*/ private static final String WECHAT_PAY_COMPLETE = "97"; /*作业提醒*/ @@ -59,10 +279,40 @@ public class PushManager { public void setPushContent(String title, String extras) { switch (title) { - case JIGUANG_ALARM_CLOCK: + case GET_DRIVELINE: + Toaster.debugShow("收到推送消息: 获取在线信息"); +// NetInterfaceManager.getInstance().getDriveState(member_id, sn_id); + break; + case GET_STARTTIME: + Toaster.debugShow("收到推送消息: 获取运行应用"); + sendStartTime(extras); + break; + case USB_STATE: + Toaster.debugShow("收到推送消息: USB连接模式管控"); + setUsbStatus(extras); + break; + case REBOOT_DEVICES: + Toaster.debugShow("收到推送消息: 重启"); + AdminManager.getInstance().rebootDevice(); + break; + case LOCK_SCREEN: + Toaster.debugShow("收到推送消息: 锁屏"); + setLockScreen(extras); + Log.e(TAG, extras); + break; + case SNAPSHOT: + Toaster.debugShow("收到推送消息: 截图"); + screenshot(extras); + Log.e(TAG, extras); + break; + case ALARM_CLOCK: Toaster.debugShow("收到推送消息: 设置闹钟"); sendAlarmClock(extras); break; + case KILL_APP: + Toaster.debugShow("收到推送消息: 内存优化"); + killBackgroundApp(); + break; case ONLINE_COURSE_MODE: Toaster.debugShow("收到推送消息: 网课模式"); NetInterfaceManager.getInstance().getCloudLessonSettings(); @@ -71,8 +321,39 @@ public class PushManager { startHome(); break; case HOMEWORK_REMINDERS: + Toaster.debugShow("收到推送消息: 作业提醒"); sendHomework(extras); break; + case UNBIND_DEVICE: + cleanCache(); + break; + case GO_ANDROID: + setReturnAndrdoid(extras); + break; + case BLUETOOTH_TRANSFER: + setBluetoothTransfer(extras); + break; + case DEVELOPER_MODE: + setDeveloperMode(extras); + break; + case RESTORE_FACTORY_MODE: + setResetMode(extras); + break; + case ACTION_BAR_MODE: + setActionBarMode(extras); + break; + case NAVIGATION_BAR_MODE: + setNavigationBarMode(extras); + break; + case NOTIFY_BAR_SHOW: + setNotification(extras); + break; + case REFRESH_NETWORK: + Toaster.debugShow("收到推送消息: 刷新并截图"); + screenshot(extras); + sendStartTime(extras); +// sendRefreshSeeting(); + break; case LOVE_ENCOURAGEMENT: Toaster.debugShow("收到推送消息: 爱的鼓励"); sendEncouragement(extras); @@ -80,6 +361,179 @@ public class PushManager { } } + private void setNotification(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("is_notify_bar_show"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setNotification: jsonElement is null"); + return; + } + int is_notify_bar_show = jsonElement.getAsInt(); + mMMKV.encode(CommonConfig.NOTIFY_BAR_SHOW_KEY, is_notify_bar_show); + mContext.startService(new Intent(mContext, MainService.class)); + } + + private void setNavigationBarMode(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("is_bottom_bar"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setNavigationBarMode: jsonElement is null"); + return; + } + int is_bottom_bar = jsonElement.getAsInt(); + ControlManager.getInstance().setBottomBar(is_bottom_bar); + } + + private void setActionBarMode(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("is_top_notify"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setActionBarMode: jsonElement is null"); + return; + } + int is_top_notify = jsonElement.getAsInt(); + ControlManager.getInstance().setTopNotify(is_top_notify); + } + + private void setResetMode(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("is_device_recover"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setDeveloperMode: jsonElement is null"); + return; + } + int is_device_recover = jsonElement.getAsInt(); + ControlManager.getInstance().setDeviceRecover(is_device_recover); + } + + private void setDeveloperMode(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("is_developer_mode"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setDeveloperMode: jsonElement is null"); + return; + } + int is_developer_mode = jsonElement.getAsInt(); + ControlManager.getInstance().setDeveloperMode(is_developer_mode); + } + + private void setBluetoothTransfer(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("is_bluetooth_share"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setBluetoothTransfer: jsonElement is null"); + return; + } + int is_bluetooth_share = jsonElement.getAsInt(); + ControlManager.getInstance().setBluetoothShare(is_bluetooth_share); + } + + private void setUsbTransfer(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("is_usb_share"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setUsbTransfer: jsonElement is null"); + return; + } + int is_usb_share = jsonElement.getAsInt(); + Intent usbIntent = new Intent(); + if (is_usb_share == 0) { + usbIntent.setAction(CommonConfig.AOLE_ACTION_USB_USB_CHARGE); + } else { + usbIntent.setAction(CommonConfig.AOLE_ACTION_USB_USB_MTP); + } + mContext.sendBroadcast(usbIntent); + } + + private void cleanCache() { + mMMKV.remove(CommonConfig.isLogined); + mMMKV.remove(CommonConfig.UIUI_ACTIVATION_KEY); + mMMKV.remove(CommonConfig.UIUI_CODE_TYPE_KEY); + mMMKV.remove(CommonConfig.UIUI_EXPIRE_TIME_KEY); + mMMKV.remove(CommonConfig.ACTIVATIONBEAN_CODE_KEY); + + mMMKV.remove(CommonConfig.ACCOUNT_LOGIN_STATU); + mMMKV.remove(CommonConfig.ACCOUNT_LOGIN_TOKEN); + mMMKV.remove(CommonConfig.ACCOUNT_LOGIN_MOBILE); + mMMKV.remove(CommonConfig.ACCOUNT_LOGIN_ID); + + mMMKV.clearAll(); + + Utils.triggerRebirth(mContext); + } + + private void setLockScreen(String jsonString) { + int type = 0; + JsonObject jSONObject = GsonUtils.getJsonObject(jsonString); + type = jSONObject.get("type").getAsInt(); + + if (!ServiceAliveUtils.isServiceAlive(mContext, ManagerService.class.getName())) { + mContext.startService(new Intent(mContext, ManagerService.class)); + } + Intent intent = new Intent(); +// intent.putExtra("name", name); + mMMKV.encode(ManagerService.LOCK_STATE, type); + if (1 == type) { + intent.setAction(ManagerService.ACTION_LOCK); + } else if (0 == type) { + intent.setAction(ManagerService.ACTION_UNLOCK); + } + mContext.sendBroadcast(intent); + NetInterfaceManager.getInstance().getLockScreenPwd(); + } + + private void killBackgroundApp() { + List pkgList = ApkUtils.queryFilterAppList(mContext); + for (String pkg : pkgList) { + if (runningAppWhitelist.contains(pkg)) continue; + AdminManager.getInstance().killApplicationProcess(pkg); + Log.e(TAG, "killBackgroundApp: " + pkg); + } + } + + public static Set runningAppWhitelist = new HashSet() {{ + this.add(BuildConfig.APPLICATION_ID); + this.add("com.android.launcher3"); + this.add("com.uiui.info"); + this.add("com.uiui.os"); + this.add("com.uiui.health"); + this.add("com.uiui.videoplayer"); + this.add("com.uiui.aios"); + this.add("com.uiui.sn"); + this.add("com.uiui.appstore"); + this.add("com.uiui.browser"); + this.add("com.uiui.zyos"); + this.add("com.uiui.zy"); + this.add("com.uiui.zyappstore"); + this.add("com.uiui.zybrowser"); + this.add("com.uiui.zysn"); + this.add("com.sohu.inputmethod.sogou"); + }}; + + private void sendStartTime(String jsonString) { +// MapManager.getInstance().startPositioning(); + Intent intent = new Intent(CommonConfig.IFLYTEK_UPDATE_ADDRESS_ACTION); +// intent.setPackage(JgyUtils.PACKAGE_OS); + mContext.sendBroadcast(intent); +// NetInterfaceManager.getInstance().sendRunningApp(); + NetInterfaceManager.getInstance().updateAdminInfo(); + NetInterfaceManager.getInstance().SendAppInstallInfo(); + if (JgyUtils.getInstance().isScreenOn()) { + NetInterfaceManager.getInstance().screenshot(); + } + } + + private void setUsbStatus(String jsonString) { + if (!TextUtils.isEmpty(jsonString)) { + JsonObject jsonObject = GsonUtils.getJsonObject(jsonString); + String setting_usb = jsonObject.get("setting_usb").getAsString(); +// ControlPanelManager.getInstance().setUsbStatus(setting_usb); + AdminManager.getInstance().setUSBDataDisabled(!"usb_mtp".equals(setting_usb)); + } else { + Toaster.debugShow("setUsbState jsonString is NULL"); + } + } + private void startHome() { Intent intent = new Intent(mContext, HomeActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -95,13 +549,118 @@ public class PushManager { } private void sendHomework(String extras) { - Intent intent = new Intent(UserFragment.ACTION_REFRESH_HOMEWORK_REMINDERS); + Intent intent = new Intent(HomeActivity.ACTION_REFRESH_HOMEWORK_REMINDERS); mContext.sendBroadcast(intent); + + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + int id = jsonObject.get("id").getAsInt(); + Intent homeworkIntent = new Intent(mContext, HomeworkDetailsActivity.class); + homeworkIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + homeworkIntent.putExtra("HomeworkBeanID", id); + mContext.startActivity(homeworkIntent); } private void sendEncouragement(String extras) { - Intent intent = new Intent(UserFragment.ACTION_REFRESH_LOVE_ENCOURAGEMENT); + Intent intent = new Intent(HomeActivity.ACTION_REFRESH_LOVE_ENCOURAGEMENT); mContext.sendBroadcast(intent); } + public void screenshot(String s) { + long createTime = System.currentTimeMillis() / 1000; + PowerManager.WakeLock mWakeLock = JgyUtils.acquireWakeLock(mContext, 60 * 1000); + JgyUtils.release(mWakeLock); + Log.e("createTime", String.valueOf(createTime)); + doscreenshot(createTime); + } + + public void doscreenshot(long time) { + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter e) throws Exception { + String filepath = mContext.getExternalFilesDir("db").getAbsolutePath() + File.separator + time + ".db"; + Bitmap bitmap = AdminManager.getInstance().captureScreen(); + File file = BitmapUtils.saveBitmap(bitmap, filepath); + e.onNext(file); + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("doscreenshot", "onSubscribe: "); + } + + @Override + public void onNext(File file) { + if (file != null && file.exists() && !file.isDirectory()) { + uplaodImage(time); + } else { + Log.e("doscreenshot", "onNext: " + "失败"); + } + } + + @Override + public void onError(Throwable e) { + Log.e("doscreenshot", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("doscreenshot", "onComplete: "); + } + }); + } + + private void uplaodImage(long time) { + String filepath = mContext.getExternalFilesDir("db").getAbsolutePath(); +// String filepath = mContext.getFileStreamPath("screenshot").getAbsolutePath(); + //放在app内部data下面 + File file = new File(filepath + File.separator + time + ".db"); + //不要直接使用常用图片格式 + if (!file.exists()) { + Log.e("uplaodImage", "File does not exists"); + return; + } + //设置图片格式 +// RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), file); + //File转RequestBody + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody fileBody = RequestBody.Companion.create(file, mediaType); + //设置一个file文件 + MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), fileBody); + Map params = new HashMap<>(); + params.put("sn", Utils.getSerial(mContext)); + params.put("createtime", String.valueOf(time)); + Call call = NetInterfaceManager.getInstance().getUploadScreenshotControl().uploadScreenshotCall(Utils.getSerial(mContext), body); + call.enqueue(new RetryCallback(call, 10, 30 * 1000) { + @Override + public void onRequestResponse(Call call, Response response) { + Log.e(TAG, "onRequestResponse: " + response.body().toString()); + } + + @Override + public void onRequestFail(Call call, Throwable t) { + Log.e(TAG, "onRequestFail: "); + } + + @Override + public void onStartRetry() { + Log.e(TAG, "onStartRetry: "); + } + }); + } + + private void sendZyosRefreshIntent() { + Intent intent = new Intent(UserFragment.ACTION_REFRESH_BINDING_STATUS); + intent.setPackage("com.uiui.zyos"); + mContext.sendBroadcast(intent); + } + + private void setReturnAndrdoid(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + int isReturnAndroid = jsonObject.get("is_return_android").getAsInt(); + mMMKV.encode(CommonConfig.UIUI_RETURN_ANDROID_KEY, isReturnAndroid); + sendZyosRefreshIntent(); + } + } diff --git a/app/src/main/java/com/xwad/os/service/DownloadService.java b/app/src/main/java/com/xwad/os/service/DownloadService.java index 5e152ba..4101416 100644 --- a/app/src/main/java/com/xwad/os/service/DownloadService.java +++ b/app/src/main/java/com/xwad/os/service/DownloadService.java @@ -24,6 +24,7 @@ import com.google.gson.reflect.TypeToken; import com.hjq.toast.Toaster; import com.xwad.os.R; import com.xwad.os.bean.AriaDownloadInfo; +import com.xwad.os.mdm.AdminManager; import com.xwad.os.utils.ApkUtils; import java.io.File; @@ -204,7 +205,7 @@ public class DownloadService extends Service { @Download.onTaskComplete void taskComplete(DownloadTask task) { Log.e(TAG, "taskComplete: " + task.getFilePath()); - ApkUtils.installApkFile(DownloadService.this, task.getFilePath()); + ApkUtils.installApp(DownloadService.this, task.getFilePath()); String jsonString = task.getExtendField(); Log.e(TAG, "taskComplete: " + "下载完成:" + jsonString); AriaDownloadInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString); diff --git a/app/src/main/java/com/xwad/os/service/ManagerService.java b/app/src/main/java/com/xwad/os/service/ManagerService.java new file mode 100644 index 0000000..b9dfa14 --- /dev/null +++ b/app/src/main/java/com/xwad/os/service/ManagerService.java @@ -0,0 +1,808 @@ +package com.xwad.os.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.graphics.Color; +import android.graphics.PixelFormat; +import android.media.AudioAttributes; +import android.media.SoundPool; +import android.os.Build; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.alibaba.sdk.android.push.PushControlService; +import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory; +import com.blankj.utilcode.util.NetworkUtils; +import com.google.gson.JsonObject; +import com.tencent.mmkv.MMKV; +import com.tuo.customview.VerificationCodeView; +import com.uiui.zy.KeepAliveConnection; +import com.xwad.os.BuildConfig; +import com.xwad.os.R; +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.config.CommonConfig; +import com.xwad.os.gson.GsonUtils; +import com.xwad.os.mdm.AdminManager; +import com.xwad.os.network.NetInterfaceManager; +import com.xwad.os.receiver.ApkInstallReceiver; +import com.xwad.os.receiver.BootReceiver; +import com.xwad.os.service.main.MainService; +import com.xwad.os.utils.ActivationUtil; +import com.xwad.os.utils.ApkUtils; +import com.xwad.os.utils.JgyUtils; +import com.xwad.os.utils.ServiceAliveUtils; +import com.xwad.os.utils.TimeUtils; +import com.xwad.os.utils.Utils; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableEmitter; +import io.reactivex.rxjava3.core.ObservableOnSubscribe; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; + +public class ManagerService extends Service implements NetworkUtils.OnNetworkStatusChangedListener { + private static final String TAG = "ManagerService"; + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + public static final String ACTION_LOCK = BuildConfig.APPLICATION_ID + "_LockScreenReceiver_lockscreen"; + public static final String ACTION_UNLOCK = BuildConfig.APPLICATION_ID + "_LockScreenReceiver_unlockscreen"; + public static final String ACTION_UPDATE = BuildConfig.APPLICATION_ID + "_TimeChangedReceiver_update"; + public static final String LOCK_SCREEN_PASSWORD = "Iflytek_lockScreenPasswordKey"; + public static final String DEFAULT_PASSWORD = "072814"; + + private WindowManager windowManager; + private View topView; + /*是否锁屏*/ + private boolean screenlocked = false; + /*是否时间控制*/ + private boolean timelocked = false; + + private SoundPool soundPool; + private int soundId; + + + @Override + public void onDisconnected() { + + } + + @Override + public void onConnected(NetworkUtils.NetworkType networkType) { +// getScreenLockState(); + } + + + private interface Start { + void onstar(long time); + } + + private Start start; + + private final ObservableOnSubscribe subscribe = new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + start = new Start() { + @Override + public void onstar(long time) { + emitter.onNext(time); + } + }; + } + }; + + private Observer timeObserver = new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(Long aLong) { + Log.e("TimeObserver", "onNext: " + aLong); + int isLogined = mMMKV.decodeInt(CommonConfig.isLogined, 0); + if (isLogined != 1) { + + } + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }; + + + private static KillAppListener killAppListener; + + public interface KillAppListener { + void killApp(String action); + } + + private final ObservableOnSubscribe killSubscribe = new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + killAppListener = new KillAppListener() { + @Override + public void killApp(String action) { + emitter.onNext(action); + } + }; + } + }; + + private Observer killObserver = new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("killObserver", "onSubscribe: "); + } + + @Override + public void onNext(String action) { + Log.e("killObserver", "onNext: " + action); + if (!JgyUtils.getInstance().isScreenOn()) { + AdminManager.getInstance().killApplicationProcess("com.jxw.mskt.video"); + AdminManager.getInstance().killApplicationProcess("com.jxw.teacher.video"); + AdminManager.getInstance().killApplicationProcess("com.jxw.newyouer.video"); + AdminManager.getInstance().killApplicationProcess("com.jxw.question"); + AdminManager.getInstance().killApplicationProcess(JgyUtils.PACKAGE_APPSTORE); + AdminManager.getInstance().killApplicationProcess(JgyUtils.PACKAGE_BROWSER); + int is_activation = ActivationUtil.getInstance().getActivationStateCode(); + Log.e(TAG, "onReceive: is_activation = " + is_activation); +// if (is_activation == 0) { + AdminManager.getInstance().killApplicationProcess("com.jxw.launcher"); + AdminManager.getInstance().killApplicationProcess("com.jxw.online_study"); +// } + if (!ActivationUtil.getInstance().isActivation()) { + AdminManager.getInstance().killApplicationProcess(JgyUtils.PACKAGE_OS); + } + } else { + Log.e("killObserver", "onNext: ScreenOn"); + } + } + + @Override + public void onError(Throwable e) { + Log.e("killObserver", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("killObserver", "onComplete: "); + } + }; + + private ServiceConnection mServiceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName componentName, IBinder iBinder) { + Log.e(TAG, "onServiceConnected: componentName = " + componentName); + boolean isServiceRunning = ServiceAliveUtils.isServiceAlive(ManagerService.this, MainService.class.getName()); + Log.e(TAG, "onServiceConnected: isServiceRunning = " + isServiceRunning); + if (!isServiceRunning) { + startService(new Intent(ManagerService.this, MainService.class)); + } + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + Log.e(TAG, "onServiceDisconnected: "); + // 断开链接 + startService(new Intent(ManagerService.this, MainService.class)); + // 重新绑定 + bindService(new Intent(ManagerService.this, MainService.class), mServiceConnection, Context.BIND_IMPORTANT); + } + }; + + @Override + public IBinder onBind(Intent intent) { + return new KeepAliveConnection.Stub() { + }; + } + + @Override + public void onCreate() { + super.onCreate(); + AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME) // 设置音效使用场景 + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build(); // 设置音效的类型 + soundPool = new SoundPool.Builder().setAudioAttributes(attr) // 设置音效池的属性 + .setMaxStreams(1) // 设置最多可容纳10个音频流 + .build(); // ① + // load方法加载指定音频文件,并返回所加载的音效ID + // 此处使用HashMap来管理这些音频流 + soundId = soundPool.load(this, R.raw.click, 1); + NetworkUtils.registerNetworkStatusChangedListener(this); + registerReceivers(); + setFloatingWindow(); + Observable.create(subscribe) + .throttleFirst(3, TimeUnit.HOURS) + .subscribe(timeObserver); + + Observable.create(killSubscribe) + .throttleLast(1, TimeUnit.MINUTES) +// .throttleLast(3, TimeUnit.SECONDS) + .subscribe(killObserver); + + boolean isServiceRunning = ServiceAliveUtils.isServiceAlive(this, MainService.class.getName()); + Log.e(TAG, "onCreate: isServiceRunning = " + isServiceRunning); + if (!isServiceRunning) { + startService(new Intent(this, MainService.class)); + } + bindService(new Intent(this, MainService.class), mServiceConnection, Context.BIND_IMPORTANT); + + PushServiceFactory.getPushControlService().setConnectionChangeListener(new PushControlService.ConnectionChangeListener() { + @Override + public void onConnect() { + Log.e("ConnectionChange", "onConnect: "); + } + + @Override + public void onDisconnect(String code, String msg) { + Log.e("ConnectionChange", "onConnect: code = " + code + " msg = " + msg); + PushServiceFactory.getPushControlService().reconnect(); + } + }); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + start.onstar(System.currentTimeMillis()); + return START_STICKY; + } + + private void getScreenLockState() { + NetInterfaceManager.getInstance() + .getSnInfoApi() + .getScreenshot(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("getScreenLockState", "onSubscribe: "); + } + + @Override + public void onNext(BaseResponse baseResponse) { + Log.e("getScreenLockState", "onNext: "); + int code = baseResponse.code; + if (code == 200) { + JsonObject jsonObject = GsonUtils.getJsonObject(GsonUtils.toJSONString(baseResponse.data)); + int is_screen_lock = jsonObject.get("is_screen_lock").getAsInt(); + setLockedState(is_screen_lock); + } else { + if (!timelocked) { + hideFloatingWindow(); + } + screenlocked = false; + mMMKV.encode(LOCK_STATE, 0); + } + } + + @Override + public void onError(Throwable e) { + Log.e("getScreenLockState", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getScreenLockState", "onComplete: "); + } + }); + } + + private void setLockedState(int lockedState) { + if (lockedState == 1) { + if (!timelocked) { + showFloatingWindow("屏幕已锁定"); + } + screenlocked = true; + mMMKV.encode(LOCK_STATE, 1); + } else { + if (!timelocked) { + hideFloatingWindow(); + } + screenlocked = false; + mMMKV.encode(LOCK_STATE, 0); + } + } + + public static final String LOCK_STATE = "SCRENN_LOOCKED_STATE"; + + private void showFloatingWindow(String name) { + AdminManager.getInstance().setStatusBarExpandPanelDisabled(true); + AdminManager.getInstance().setNavigationBarDisabled(true); + if (Settings.canDrawOverlays(this)) { + // 获取WindowManager服务 + if (null == windowManager) { + windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); + } + DisplayMetrics dm = new DisplayMetrics(); + windowManager.getDefaultDisplay().getRealMetrics(dm); + int width = dm.widthPixels; // 屏幕宽度(像素) + int height = dm.heightPixels; // 屏幕高度(像素) + // 新建悬浮窗控件 + final Button button = new Button(getApplicationContext()); + button.setText("霸屏测试"); + button.setAlpha(0.9f); + button.setBackgroundColor(Color.BLACK); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// windowManager.removeView(button); + } + }); + if (null == topView) { + topView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_screen_lock, null); + initTopView(topView, name); + } else { + if ("added".equals(topView.getTag())) { + initTopView(topView, name); + } else { + return; + } + return; + } + // topView.setAlpha(0.8f); + // 设置LayoutParam + WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { +// layoutParams.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; + layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + //TYPE_SYSTEM_OVERLAY可以下滑通知栏 +// layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; + } else { + layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; + } + layoutParams.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; + layoutParams.format = PixelFormat.RGBA_8888; + layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; + layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT; + //systemUiVisibility 关闭通知栏和导航栏 + layoutParams.systemUiVisibility = + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_IMMERSIVE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + layoutParams.x = 0; + layoutParams.y = 0; + // 将悬浮窗控件添加到WindowManager + windowManager.addView(topView, layoutParams); + topView.setTag("added"); + } else { + Log.e(TAG, "showFloatingWindow: floating window permission not granted"); + } + } + + private void initTopView(View view, String name) { + TextView textView = view.findViewById(R.id.textView); + TextView tv_hint = view.findViewById(R.id.tv_hint); + textView.setText(name); + LinearLayout ll_keyboard = view.findViewById(R.id.ll_keyboard); + VerificationCodeView codeView = view.findViewById(R.id.icv); + codeView.getEditText().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + ll_keyboard.setVisibility(View.VISIBLE); + } + }); + codeView.setInputCompleteListener(new VerificationCodeView.InputCompleteListener() { + @Override + public void inputComplete() { + checkPassword(codeView, tv_hint); + } + + @Override + public void deleteContent() { + + } + }); + TextView bt0 = view.findViewById(R.id.bt_0); + TextView bt1 = view.findViewById(R.id.bt_1); + TextView bt2 = view.findViewById(R.id.bt_2); + TextView bt3 = view.findViewById(R.id.bt_3); + TextView bt4 = view.findViewById(R.id.bt_4); + TextView bt5 = view.findViewById(R.id.bt_5); + TextView bt6 = view.findViewById(R.id.bt_6); + TextView bt7 = view.findViewById(R.id.bt_7); + TextView bt8 = view.findViewById(R.id.bt_8); + TextView bt9 = view.findViewById(R.id.bt_9); + TextView tv_del = view.findViewById(R.id.tv_del); +// ImageView bt_del = view.findViewById(R.id.bt_del); +// ImageView bt_confirm = view.findViewById(R.id.bt_confirm); + bt0.setOnClickListener(view1 -> add(codeView, "0")); + bt1.setOnClickListener(view1 -> add(codeView, "1")); + bt2.setOnClickListener(view1 -> add(codeView, "2")); + bt3.setOnClickListener(view1 -> add(codeView, "3")); + bt4.setOnClickListener(view1 -> add(codeView, "4")); + bt5.setOnClickListener(view1 -> add(codeView, "5")); + bt6.setOnClickListener(view1 -> add(codeView, "6")); + bt7.setOnClickListener(view1 -> add(codeView, "7")); + bt8.setOnClickListener(view1 -> add(codeView, "8")); + bt9.setOnClickListener(view1 -> add(codeView, "9")); + tv_del.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + tv_hint.setText(""); + codeView.clearInputContent(); + } + }); +// bt_confirm.setOnClickListener(new View.OnClickListener() { +// @Override +// public void onClick(View view) { +// checkPassword(codeView, tv_hint); +// } +// }); + } + + private void checkPassword(VerificationCodeView codeView, TextView tv_hint) { + String content = codeView.getInputContent(); + if (TextUtils.isEmpty(content) || content.length() != 6) { + return; + } + Log.e(TAG, "inputComplete: " + content); + String password = mMMKV.decodeString(LOCK_SCREEN_PASSWORD, DEFAULT_PASSWORD); + if (password.equals(content)) { + hide(); + } else if (DEFAULT_PASSWORD.equals(content)) { + hide(); + } else { + postDelayed(codeView, tv_hint); + tv_hint.setText("密码错误"); + } + } + + private void postDelayed(VerificationCodeView view, TextView tv_hint) { + tv_hint.setText("密码错误"); + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + view.clearInputContent(); + tv_hint.setText(""); + } + }, 1000); + } + + private void hide() { + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + hideFloatingWindow(); + } + }, 1000); + screenlocked = false; + mMMKV.encode(ManagerService.LOCK_STATE, 0); + mMMKV.encode(TimeUtils.AOLELEARN_TIME_CONTROL_KEY, 0); + NetInterfaceManager.getInstance().getUpdateLockScreenObservable() + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("getUpdateLockScreen", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + + } + + @Override + public void onComplete() { + + } + }); + JgyUtils.getInstance().setDefaultDesktop("com.uiui.zyos", "com.uiui.zyos.activity.main.MainActivity"); + ApkUtils.openApp(ManagerService.this, "com.uiui.zyos"); + } + + private void add(VerificationCodeView codeView, String text) { + Log.e(TAG, "add: text = " + text); + String oldText = codeView.getEditText().getText().toString(); + Log.e(TAG, "add: " + oldText); + codeView.getEditText().setText(text); +// soundPool.play(soundId, 1, 1, 0, 0, 1); + } + + private void hideFloatingWindow() { + + AdminManager.getInstance().setStatusBarExpandPanelDisabled(false); + AdminManager.getInstance().setNavigationBarDisabled(false); + + if (null == windowManager) { + return; + } + if (null != topView) { + windowManager.removeView(topView); + topView = null; + NetInterfaceManager.getInstance().getSystemSettings(); + } + } + + private void registerReceivers() { + registLockReceiver(); + registerTimeReceiver(); + registerScreenLockReceiver(); + registAppReceive(); + registBootReceive(); + registerBatteryReceiver(); + } + + private void unregisterReceivers() { + if (null != mTimeChangedReceiver) { + unregisterReceiver(mTimeChangedReceiver); + } + if (null != mLockScreenReceiver) { + unregisterReceiver(mLockScreenReceiver); + } + if (null != mScreenLockReceiver) { + unregisterReceiver(mScreenLockReceiver); + } + if (null != mApkInstallReceiver) { + unregisterReceiver(mApkInstallReceiver); + } + if (null != mBootReceiver) { + unregisterReceiver(mBootReceiver); + } + if (null != mBatteryReceiver) { + unregisterReceiver(mBatteryReceiver); + } + } + + private LockScreenReceiver mLockScreenReceiver; + + private void registLockReceiver() { + if (null == mLockScreenReceiver) { + mLockScreenReceiver = new LockScreenReceiver(); + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(ACTION_LOCK); + filter.addAction(ACTION_UNLOCK); + registerReceiver(mLockScreenReceiver, filter); + } + } + + private class LockScreenReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.e("LockScreenReceiver", "onReceive: " + action); + if (TextUtils.isEmpty(action)) { + getScreenLockState(); + return; + } + if (ACTION_LOCK.equals(action)) { +// String name = intent.getStringExtra("name"); + String name = "屏幕已锁定"; + if (!timelocked) { + showFloatingWindow(name); + } + screenlocked = true; + } else if (ACTION_UNLOCK.equals(action)) { + if (!timelocked) { + hideFloatingWindow(); + } + screenlocked = false; + } + } + } + + private TimeChangedReceiver mTimeChangedReceiver; + + /** + * 监听时间和日期变化 + */ + private void registerTimeReceiver() { + mTimeChangedReceiver = new TimeChangedReceiver(); + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_DATE_CHANGED); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(Intent.ACTION_TIME_TICK); + filter.addAction(ACTION_UPDATE); + registerReceiver(mTimeChangedReceiver, filter); + } + + private class TimeChangedReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_DATE_CHANGED.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "data changed"); + } else if (Intent.ACTION_TIME_CHANGED.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "time changed"); + } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "timezone changed"); + } else if (Intent.ACTION_TIME_TICK.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "time tick"); + setFloatingWindow(); + } else if (ACTION_UPDATE.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "date update"); + setFloatingWindow(); + } + + // String packages = ForegroundAppUtil.getForegroundPackageName(context); +// if (!packages.equals("com.estrongs.android.pop")) { +// ApkUtils.openApp(context, "com.estrongs.android.pop"); +// } +// Log.e("TimeChangedReceiver", "packages:" + packages); + } + } + + private void setFloatingWindow() { +// TimeUtils.ContralTime workingContralTime = TimeUtils.getWorkingDayContralTime(ManagerService.this); +// TimeUtils.ContralTime weekContralTime = TimeUtils.getWeekDayContralTime(ManagerService.this); +// TimeUtils.ContralTime contralTime = TimeUtils.getDayContralTime(ManagerService.this); + List contralTimes = TimeUtils.getDayContralTimeList(ManagerService.this); +// if (null != workingContralTime) { +// if (TimeUtils.inContralTime(workingContralTime, weekContralTime)) { + if (TimeUtils.inDayContralTime(contralTimes)) { + if (!screenlocked) { + showFloatingWindow(getString(R.string.available_time) + TimeUtils.getDayTimeString(ManagerService.this)); + } else { + TextView textView = topView.findViewById(R.id.textView); + textView.setText(getString(R.string.available_time) + TimeUtils.getDayTimeString(ManagerService.this)); + } + timelocked = true; + } else { +// getScreenLockState(); + int isScreenLock = mMMKV.decodeInt(LOCK_STATE, 0); + setLockedState(isScreenLock); + if (!screenlocked) { + hideFloatingWindow(); + } + timelocked = false; + } +// } else { +// if (!screenlocked) { +// hideFloatingWindow() +// } +// getScreenLockState() +// timelocked = false +// } + } + + private ScreenLockReceiver mScreenLockReceiver; + + private void registerScreenLockReceiver() { + if (null == mScreenLockReceiver) { + mScreenLockReceiver = 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("android.intent.action.FACTORY_RESET"); + filter.addAction("android.intent.action.MASTER_CLEAR"); + registerReceiver(mScreenLockReceiver, 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_USER_PRESENT: + case Intent.ACTION_SCREEN_ON: +// JgyUtils.getInstance().startJxwLauncher(); + PushServiceFactory.getPushControlService().reconnect(); + + break; + case Intent.ACTION_SCREEN_OFF: + case Intent.ACTION_SHUTDOWN: + case "android.intent.action.FACTORY_RESET": + case "android.intent.action.MASTER_CLEAR": + killAppListener.killApp(action); + break; + default: + break; + } + } + } + + private ApkInstallReceiver mApkInstallReceiver; + + private void registAppReceive() { + if (null == mApkInstallReceiver) { + mApkInstallReceiver = new ApkInstallReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_PACKAGE_ADDED); + filter.addAction(Intent.ACTION_PACKAGE_REPLACED); + filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addDataScheme("package"); + registerReceiver(mApkInstallReceiver, filter); + } + + private BootReceiver mBootReceiver; + + private void registBootReceive() { + if (null == mBootReceiver) { + mBootReceiver = new BootReceiver(); + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_USER_PRESENT); + registerReceiver(mBootReceiver, filter); + } + } + + private BatteryReceiver mBatteryReceiver; + + private void registerBatteryReceiver() { + if (null == mBatteryReceiver) { + mBatteryReceiver = new BatteryReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_POWER_DISCONNECTED); + registerReceiver(mBatteryReceiver, filter); + } + + private class BatteryReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { + + } else if (Intent.ACTION_POWER_CONNECTED.equals(action) || Intent.ACTION_POWER_DISCONNECTED.equals(action)) { +// ControlManager.getInstance().setDefaultUSBstate(); + } else if (Intent.ACTION_BATTERY_LOW.equals(action) || Intent.ACTION_BATTERY_OKAY.equals(action)) { + + } + } + } + + + @Override + public void onDestroy() { + super.onDestroy(); + NetworkUtils.unregisterNetworkStatusChangedListener(this); + unregisterReceivers(); + if (soundPool != null) { + soundPool.release(); + soundPool = null; + } + unbindService(mServiceConnection); + } + +} diff --git a/app/src/main/java/com/xwad/os/service/SocketService.java b/app/src/main/java/com/xwad/os/service/SocketService.java index da0d70c..3ad93e5 100644 --- a/app/src/main/java/com/xwad/os/service/SocketService.java +++ b/app/src/main/java/com/xwad/os/service/SocketService.java @@ -26,6 +26,7 @@ import com.xwad.os.activity.login.LoginActivity; import com.xwad.os.config.CommonConfig; import com.xwad.os.gson.GsonUtils; import com.xwad.os.manager.DeviceSNManager; +import com.xwad.os.mdm.AdminManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.network.UrlAddress; import com.xwad.os.utils.ActivationUtil; @@ -207,7 +208,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat } private void bindSn() { - String sn = DeviceSNManager.getDeviceSN(); + String sn = AdminManager.getInstance().getSerial(); if (TextUtils.isEmpty(sn)) { return; } @@ -250,8 +251,8 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat 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); + filter.addAction("android.intent.action.FACTORY_RESET"); + filter.addAction("android.intent.action.MASTER_CLEAR"); registerReceiver(mScreenLockReceiver, filter); } @@ -273,8 +274,8 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat break; case Intent.ACTION_SCREEN_OFF: case Intent.ACTION_SHUTDOWN: - case Intent.ACTION_FACTORY_RESET: - case Intent.ACTION_MASTER_CLEAR: + case "android.intent.action.FACTORY_RESET": + case "android.intent.action.MASTER_CLEAR": sendOnlineMsgScreen(); break; default: @@ -324,7 +325,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat * 初始化websocket连接 */ private void initOnlineSocketClient() { - URI uri = URI.create(UrlAddress.WEBSOCKET_URL_ONLINE + "?sn=" + DeviceSNManager.getDeviceSN()); + URI uri = URI.create(UrlAddress.WEBSOCKET_URL_ONLINE + "?sn=" + AdminManager.getInstance().getSerial()); mOnlineJWebSocketClient = new JWebSocketClient(uri) { @Override public void onMessage(String message) { @@ -403,7 +404,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat */ public void sendOnlinePingMsg() { JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("sn", DeviceSNManager.getDeviceSN()); + jsonObject.addProperty("sn", AdminManager.getInstance().getSerial()); jsonObject.addProperty("type", "ping"); if (null != mOnlineJWebSocketClient) { Log.i(TAG, "sendOnlinePingMsg: 发送的消息:" + jsonObject.toString()); @@ -413,7 +414,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat public void sendOnlineMsgScreen() { JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("sn", DeviceSNManager.getDeviceSN()); + jsonObject.addProperty("sn", AdminManager.getInstance().getSerial()); if (Utils.isScreenOn(SocketService.this)) { jsonObject.addProperty("type", "device_open_screen"); } else { @@ -475,7 +476,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat * 初始化websocket连接 */ private void initSsoSocketClient() { - URI uri = URI.create(UrlAddress.WEBSOCKET_URL_SSO + "?sn=" + DeviceSNManager.getDeviceSN() + "&token=" + NetInterfaceManager.getInstance().getToken()); + URI uri = URI.create(UrlAddress.WEBSOCKET_URL_SSO + "?sn=" + AdminManager.getInstance().getSerial() + "&token=" + NetInterfaceManager.getInstance().getToken()); mSsoJWebSocketClient = new JWebSocketClient(uri) { @Override public void onMessage(String message) { @@ -558,7 +559,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat public void sendSsoPingMsg() { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("type", "ping"); - jsonObject.addProperty("sn", DeviceSNManager.getDeviceSN()); + jsonObject.addProperty("sn", AdminManager.getInstance().getSerial()); jsonObject.addProperty("token", NetInterfaceManager.getInstance().getToken()); if (null != mSsoJWebSocketClient) { Log.i(TAG, "sendPingMsg: 发送的消息:" + jsonObject.toString()); diff --git a/app/src/main/java/com/xwad/os/service/main/MainSContact.java b/app/src/main/java/com/xwad/os/service/main/MainSContact.java index 1ecee21..60d1699 100644 --- a/app/src/main/java/com/xwad/os/service/main/MainSContact.java +++ b/app/src/main/java/com/xwad/os/service/main/MainSContact.java @@ -2,14 +2,100 @@ package com.xwad.os.service.main; import com.xwad.os.base.mvp.BasePresenter; import com.xwad.os.base.mvp.BaseView; +import com.xwad.os.bean.AppInfo; +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.bean.IsActivationBean; +import com.xwad.os.bean.SnInfo; + +import java.util.List; public class MainSContact { public interface Presenter extends BasePresenter { + /*是否已经激活*/ + void getSnIsActivation(); + + /*上传未激活设备的信息*/ + void uploadNotActivate(); + /*获取公网ip*/ + void getPublicIp(); + /*激活九学王*/ + void setJxwActivation(); + /*激活后获取九学王app*/ + void getJxwApp(); + + /*获取设备信息*/ + void getSnInfo(); + + + /*需要绑定设备才能使用的功能*/ /*获取网课模式*/ void getCloudLessonSettings(); + /*上传设备信息*/ + void updateDeviceInfo(); + + /*获取时间管控*/ + void getTimeControl(); + /*获取所有app包名*/ + void getAllApp(); + /*获取强制下载*/ + void getForceInstall(); + /*图标隐藏*/ + void getAppIcon(); + /*获取wifi密码*/ + void getWiFiPasswd(); + /*获取锁屏管控*/ + void getScreenLock(); + + /*获取锁定状态*/ + void getLocked(); + /*检查更新*/ + void checkUpdate(); + /*获取灰度更新*/ + void getTestApp(); + /*获取管理员应用*/ + void getAdminApp(); + /*获取id管控*/ + void getAppInside(); + + /*获取app联网管控*/ + void getAppNetwork(); + /*获取系统设置*/ + void getSystemSettings(); + /*获取锁屏密码*/ + void getLockScreenPwd(); } public interface MainSView extends BaseView { + void isActivation(IsActivationBean isActivationBean); + + void uploadNotActivateFinish(); + void setPublicIp(String ip); +// void activationJxw(JxwResponse jxwResponse); + void activationJxwComplete(); + void setJxwApp(List appInfos); + + void setSnInfo(BaseResponse response); + + /*需要绑定设备才能使用的功能*/ void setCloudLessonSettings(); + + void updateInfoFinish(); + + void getTimeControlFinish(); + void getAllAppFinish(); + void setForceInstall(); + void setAppIcon(); + void setWiFiPasswd(); + void setScreenLock(); + + void setLocked(int lockedStatus); + void checkUpdateFinish(); + void getTestAppFinish(); + void getAdminAppFinish(); + void setAppInside(); + + void setAppNetwork(); + void setSystemSettings(); + void setLockScreenPwd(); } } diff --git a/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java b/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java index ce64b6c..54a3250 100644 --- a/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java +++ b/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java @@ -1,16 +1,32 @@ package com.xwad.os.service.main; import android.content.Context; +import android.content.Intent; import android.util.Log; +import com.google.gson.JsonObject; import com.tencent.mmkv.MMKV; +import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.android.ActivityEvent; import com.xwad.os.bean.AlarmClockData; +import com.xwad.os.bean.AppInfo; +import com.xwad.os.bean.BaseResponse; import com.xwad.os.config.CommonConfig; +import com.xwad.os.gson.GsonUtils; import com.xwad.os.network.NetInterfaceManager; +import com.xwad.os.service.ManagerService; +import com.xwad.os.utils.ServiceAliveUtils; +import com.xwad.os.utils.Utils; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; import io.reactivex.rxjava3.subjects.BehaviorSubject; @@ -51,9 +67,39 @@ public class MainSPresenter implements MainSContact.Presenter { this.mView = null; } + @Override + public void getSnIsActivation() { + + } + + @Override + public void uploadNotActivate() { + + } + + @Override + public void getPublicIp() { + + } + + @Override + public void setJxwActivation() { + + } + + @Override + public void getJxwApp() { + + } + + @Override + public void getSnInfo() { + + } + @Override public void getCloudLessonSettings() { - NetInterfaceManager.getInstance().getCloudLessonSettings(lifecycle, new NetInterfaceManager.onCompleteCallback() { + NetInterfaceManager.getInstance().getCloudLessonSettings(lifecycle, new NetInterfaceManager.OnCompleteCallback() { @Override public void onComplete() { mView.setCloudLessonSettings(); @@ -61,22 +107,154 @@ public class MainSPresenter implements MainSContact.Presenter { }); } - public void getAlarmClock() { - NetInterfaceManager.getInstance().getAlarmClock(true, getLifecycle(), new NetInterfaceManager.AlarmClockCallback() { - @Override - public void setAlarmClock(List alarmClockList) { - Log.e(TAG, "setAlarmClock: " + alarmClockList); - } + @Override + public void updateDeviceInfo() { - @Override - public void setAlarmClockEmpty() { - Log.e(TAG, "setAlarmClock: setAlarmClockEmpty"); - } - - @Override - public void onError() { - Log.e(TAG, "setAlarmClock: onError"); - } - }); } + + @Override + public void getTimeControl() { + + } + + @Override + public void getAllApp() { + + } + + @Override + public void getForceInstall() { + + } + + @Override + public void getAppIcon() { + + } + + @Override + public void getWiFiPasswd() { + + } + + @Override + public void getScreenLock() { + NetInterfaceManager.getInstance() + .getSnInfoApi() + .getScreenshot(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("getScreenLock", "onSubscribe: "); + } + + @Override + public void onNext(BaseResponse baseResponse) { + Log.e("getScreenLock", "onNext: " + baseResponse); + int code = baseResponse.code; + if (code == 200) { + JsonObject jsonObject = GsonUtils.getJsonObject(GsonUtils.toJSONString(baseResponse.data)); + int is_screen_lock = jsonObject.get("is_screen_lock").getAsInt(); + if (!ServiceAliveUtils.isServiceAlive(mContext, ManagerService.class.getName())) { + mContext.startService(new Intent(mContext, ManagerService.class)); + } + mMMKV.encode(ManagerService.LOCK_STATE, is_screen_lock); + Intent intent = new Intent(); +// intent.putExtra("name", name); + if (1 == is_screen_lock) { + intent.setAction(ManagerService.ACTION_LOCK); + } else if (0 == is_screen_lock) { + intent.setAction(ManagerService.ACTION_UNLOCK); + } + mContext.sendBroadcast(intent); + } + } + + @Override + public void onError(Throwable e) { + Log.e("getScreenLock", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getScreenLock", "onComplete: "); + mView.setScreenLock(); + } + }); + } + + @Override + public void getLocked() { + + } + + @Override + public void checkUpdate() { + + } + + @Override + public void getTestApp() { + + } + + @Override + public void getAdminApp() { + NetInterfaceManager.getInstance().getAdminAppObservable() + .subscribe(new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAdminApp", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> listBaseResponse) { + Log.e("getAdminApp", "onNext: " + listBaseResponse); + if (listBaseResponse.code == 200) { + List appInfoList = listBaseResponse.data; + Set pkgList = appInfoList.stream().map(AppInfo::getApp_package).collect(Collectors.toSet()); + Log.e("getAdminApp", "onNext: " + pkgList); + mMMKV.encode(CommonConfig.ADMIN_APP_LIST, pkgList); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAdminApp", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAdminApp", "onComplete: "); + mView.getAdminAppFinish(); + } + }); + } + + @Override + public void getAppInside() { + + } + + @Override + public void getAppNetwork() { + + } + + @Override + public void getSystemSettings() { + NetInterfaceManager.getInstance().getSystemSettings(); + } + + @Override + public void getLockScreenPwd() { + + } + + } diff --git a/app/src/main/java/com/xwad/os/service/main/MainService.java b/app/src/main/java/com/xwad/os/service/main/MainService.java index f723398..c2d80df 100644 --- a/app/src/main/java/com/xwad/os/service/main/MainService.java +++ b/app/src/main/java/com/xwad/os/service/main/MainService.java @@ -23,11 +23,16 @@ import com.xwad.os.activity.main.MainActivity; import com.xwad.os.alarm.AlarmUtils; import com.xwad.os.base.rx.BaseRxService; import com.xwad.os.bean.AlarmClockData; +import com.xwad.os.bean.AppInfo; +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.bean.IsActivationBean; +import com.xwad.os.bean.SnInfo; import com.xwad.os.config.CommonConfig; import com.xwad.os.service.SocketService; import java.util.Calendar; import java.util.HashMap; +import java.util.List; public class MainService extends BaseRxService implements MainSContact.MainSView, NetworkUtils.OnNetworkStatusChangedListener { private static final String TAG = "MainService"; @@ -63,10 +68,16 @@ public class MainService extends BaseRxService implements MainSContact.MainSView public void onCreate() { super.onCreate(); Log.e(TAG, "onCreate: "); + long time = System.currentTimeMillis(); + mPresenter = new MainSPresenter(this); mPresenter.attachView(this); mPresenter.setLifecycle(getLifecycleSubject()); + mPresenter.getCloudLessonSettings(); + mPresenter.getScreenLock(); + mPresenter.getAdminApp(); + registerReceivers(); NetworkUtils.registerNetworkStatusChangedListener(this); startJxwLauncher(); @@ -77,6 +88,9 @@ public class MainService extends BaseRxService implements MainSContact.MainSView sendSimpleNotification(); startService(new Intent(MainService.this, SocketService.class)); + + Log.e(TAG, "setDefault: startServices time = " + (System.currentTimeMillis() - time) + "ms"); + } @Override @@ -218,11 +232,6 @@ public class MainService extends BaseRxService implements MainSContact.MainSView } } - @Override - public void setCloudLessonSettings() { - - } - public static final String JXW_REGISTER_SUCCESS = "com.zzj.regist_success"; private JxwRegisterReceiver mJxwRegisterReceiver; @@ -247,4 +256,115 @@ public class MainService extends BaseRxService implements MainSContact.MainSView } } + + @Override + public void isActivation(IsActivationBean isActivationBean) { + + } + + @Override + public void uploadNotActivateFinish() { + + } + + @Override + public void setPublicIp(String ip) { + + } + + @Override + public void activationJxwComplete() { + + } + + @Override + public void setJxwApp(List appInfos) { + + } + + @Override + public void setSnInfo(BaseResponse response) { + + } + + @Override + public void setCloudLessonSettings() { + + } + + @Override + public void updateInfoFinish() { + + } + + @Override + public void getTimeControlFinish() { + + } + + @Override + public void getAllAppFinish() { + + } + + @Override + public void setForceInstall() { + + } + + @Override + public void setAppIcon() { + + } + + @Override + public void setWiFiPasswd() { + + } + + @Override + public void setScreenLock() { + + } + + @Override + public void setLocked(int lockedStatus) { + + } + + @Override + public void checkUpdateFinish() { + + } + + @Override + public void getTestAppFinish() { + + } + + @Override + public void getAdminAppFinish() { + + } + + @Override + public void setAppInside() { + + } + + @Override + public void setAppNetwork() { + + } + + @Override + public void setSystemSettings() { + + } + + @Override + public void setLockScreenPwd() { + + } + } diff --git a/app/src/main/java/com/xwad/os/utils/ApkUtils.java b/app/src/main/java/com/xwad/os/utils/ApkUtils.java index 2fc3a8e..f8f34d7 100644 --- a/app/src/main/java/com/xwad/os/utils/ApkUtils.java +++ b/app/src/main/java/com/xwad/os/utils/ApkUtils.java @@ -23,6 +23,7 @@ import androidx.core.content.FileProvider; import com.hjq.toast.Toaster; import com.xwad.os.BuildConfig; import com.xwad.os.R; +import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.AppUpdateInfo; import com.xwad.os.bean.DesktopIcon; import com.xwad.os.mdm.AdminManager; @@ -133,6 +134,61 @@ public class ApkUtils { this.add("com.android.uiuios"); }}; + public static final List mJxwApps = new ArrayList() {{ + this.add("air.com.zhihuiyoujiao.flashplayer"); + this.add("com.example.arithmeticformula"); + this.add("com.example.elementcycleapp"); + this.add("com.example.pianpangbushou"); + this.add("com.iflytek.cyber.iot.show.core"); + this.add("com.iflytek.speechcloud"); + this.add("com.jxw.bihuamingcheng"); + this.add("com.jxw.bishunguize"); + this.add("com.jxw.characterlearning"); + this.add("com.jxw.dmxcy"); + this.add("com.jxw.englishsoundmark"); + this.add("com.jxw.examsystem"); + this.add("com.jxw.game"); + this.add("com.jxw.gb.zwpg"); + this.add("com.jxw.handwrite"); + this.add("com.jxw.jinfangyici"); + this.add("com.jxw.jxwbook"); + this.add("com.jxw.jxwcalculator"); + this.add("com.jxw.laboratory"); + this.add("com.jxw.learnchinesepinyin"); + this.add("com.jxw.letterstudynew"); + this.add("com.jxw.liancichengju"); + this.add("com.jxw.mskt.video"); + this.add("com.jxw.newyouer.video"); + this.add("com.jxw.online_study"); + this.add("com.jxw.question"); + this.add("com.jxw.schultegrid"); + this.add("com.jxw.singsound"); + this.add("com.jxw.studydigital"); + this.add("com.jxw.teacher.video"); + this.add("com.jxw.wuweijidanci"); + this.add("com.jxw.youer.video"); + this.add("com.jxw.yuwenxiezuo"); + this.add("com.jxw.yyhb"); + this.add("com.jxw.zncd"); + this.add("com.jxw.souti"); + this.add("com.jxw.xdfzq"); + this.add("com.jxw.huiben"); + this.add("com.oirsdfg89.flg"); + this.add("com.study.flashplayer"); + this.add("com.tech.translate"); + this.add("com.uiui.zybrowser"); + this.add("com.uiui.zysn "); + this.add("com.jxw.launcher"); + this.add("com.uiui.zyappstore"); + this.add("com.uiui.zy"); + this.add("com.uiui.zyos"); + this.add("com.teclast.zyos"); + this.add("com.teclast.zybrowser"); + this.add("com.teclast.zyappstore"); + this.add("com.teclast.zy"); + }}; + + public static final String ANDROID_LAUNCHER3_PACKAGE_NAME = "com.android.launcher3"; public static final String ANDROID_LAUNCHER3_CLASS_NAME = "com.android.launcher3.Launcher"; public static final String ANDROID_LAUNCHER3_Quickstep_CLASS_NAME = "com.android.launcher3.uioverrides.QuickstepLauncher"; @@ -248,7 +304,7 @@ public class ApkUtils { // if (adminApp.contains(pkg)) { // resolveInfos.add(resolveInfo); // } else if (showPackageName.contains(pkg)) { - resolveInfos.add(resolveInfo); + resolveInfos.add(resolveInfo); // } } // } @@ -470,6 +526,24 @@ public class ApkUtils { return versionName; } + public static long getAppLastUpdateTime(Context context, String pkg) { + if (TextUtils.isEmpty(pkg)) { + return 0; + } + PackageManager pm = context.getPackageManager(); + PackageInfo packageInfo = null; + try { + packageInfo = pm.getPackageInfo(pkg, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo == null) { + return 0; + } else { + return packageInfo.lastUpdateTime / 1000; + } + } + public static String getAppNameByPackage(Context context, String pkg) { PackageManager packageManager = context.getPackageManager(); try { @@ -780,6 +854,11 @@ public class ApkUtils { } } + public static boolean isUpdate(Context context, AppInfo appUpdateInfo) { + String packageName = appUpdateInfo.getApp_package(); + long versionCode = appUpdateInfo.getApp_version_code(); + return isUpdate(context, packageName, versionCode); + } public static boolean isUpdate(Context context, AppUpdateInfo appUpdateInfo) { String packageName = appUpdateInfo.getApp().getApp_package(); @@ -817,6 +896,33 @@ public class ApkUtils { installApkFile(context, apk); } + public static void checkAppUpdate(Context context, AppInfo appUpdateInfo) { + String packageName = appUpdateInfo.getApp_package(); + long versionCode = appUpdateInfo.getApp_version_code(); + String url = appUpdateInfo.getApp_url(); + PackageInfo packageInfo = null; + try { + packageInfo = context.getPackageManager().getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo == null) { + FileUtil.ariaDownload(context, url, appUpdateInfo); + } else { + long appVersionCode; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + appVersionCode = packageInfo.getLongVersionCode(); + } else { + appVersionCode = packageInfo.versionCode; + } + if (appVersionCode < versionCode) { + FileUtil.ariaDownload(context, url, appUpdateInfo); + } else { + Log.e(TAG, "checkUpdate: " + packageName + "\t已经是最新版"); + } + } + } + public static void checkAppUpdate(Context context, AppUpdateInfo appUpdateInfo) { String packageName = appUpdateInfo.getApp().getApp_package(); long versionCode = appUpdateInfo.getApp_version_code(); diff --git a/app/src/main/java/com/xwad/os/utils/BitmapUtils.java b/app/src/main/java/com/xwad/os/utils/BitmapUtils.java index 17e866b..c636edd 100644 --- a/app/src/main/java/com/xwad/os/utils/BitmapUtils.java +++ b/app/src/main/java/com/xwad/os/utils/BitmapUtils.java @@ -14,6 +14,7 @@ import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Build; +import android.util.Log; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; @@ -24,10 +25,46 @@ import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.xwad.os.R; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; import java.util.HashMap; import java.util.Map; public class BitmapUtils { + private static final String TAG = "BitmapUtils"; + + public static File saveBitmap(Bitmap bitmap, String filePath) { + long time = System.currentTimeMillis(); + Log.e(TAG, "saveBitmap: " + time); + File file = new File(filePath); + // 打开输出流,并将Bitmap压缩成PNG格式输出到文件中 + OutputStream fos = null; + try { + fos = new FileOutputStream(file); + // png 1550ms jpeg 358 + long time2 = System.currentTimeMillis(); + Log.e(TAG, "saveBitmap: compress " + time2); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); + Log.e(TAG, "saveBitmap: compress " + System.currentTimeMillis()); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } finally { + try { + if (fos != null) { + fos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + Log.e(TAG, "saveBitmap: " + (System.currentTimeMillis() - time)); + return file; + } + public static Bitmap Bytes2Bimap(byte[] b) { if (b.length != 0) { return BitmapFactory.decodeByteArray(b, 0, b.length); @@ -186,4 +223,37 @@ public class BitmapUtils { } return null; } + + /** + * drawable转为file + * + * @param mContext + * @param drawable drawable + * @param fileName 转换后的文件名 + * @return + */ + public static File drawableToFile(Context mContext, Drawable drawable, String fileName) { +// InputStream is = view.getContext().getResources().openRawResource(R.drawable.logo); + Bitmap bitmap = drawableToBitmap(drawable); +// Bitmap bitmap = BitmapFactory.decodeStream(is); + String defaultPath = Utils.getCacheDir(mContext) + "/iconCache"; + File file = new File(defaultPath); + if (!file.exists()) { + file.mkdirs(); + } + String defaultImgPath = defaultPath + "/" + fileName; + File iconFile = new File(defaultImgPath); + try { + iconFile.createNewFile(); + FileOutputStream fOut = new FileOutputStream(iconFile); + bitmap.compress(Bitmap.CompressFormat.PNG, 20, fOut); +// is.close(); + fOut.flush(); + fOut.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return iconFile; + } + } diff --git a/app/src/main/java/com/xwad/os/utils/BrightnessUtils.java b/app/src/main/java/com/xwad/os/utils/BrightnessUtils.java new file mode 100644 index 0000000..0620517 --- /dev/null +++ b/app/src/main/java/com/xwad/os/utils/BrightnessUtils.java @@ -0,0 +1,140 @@ + +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.xwad.os.utils; + +public class BrightnessUtils { + + public static final int GAMMA_SPACE_MIN = 0; + public static final int GAMMA_SPACE_MAX = 65535; + + // Hybrid Log Gamma constant values + private static final float R = 0.5f; + private static final float A = 0.17883277f; + private static final float B = 0.28466892f; + private static final float C = 0.55991073f; + + /** + * A function for converting from the gamma space that the slider works in to the + * linear space that the setting works in. + *

+ * The gamma space effectively provides us a way to make linear changes to the slider that + * result in linear changes in perception. If we made changes to the slider in the linear space + * then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law). + *

+ * Internally, this implements the Hybrid Log Gamma electro-optical transfer function, which is + * a slight improvement to the typical gamma transfer function for displays whose max + * brightness exceeds the 120 nit reference point, but doesn't set a specific reference + * brightness like the PQ function does. + *

+ * Note that this transfer function is only valid if the display's backlight value is a linear + * control. If it's calibrated to be something non-linear, then a different transfer function + * should be used. + * + * @param val The slider value. + * @param min The minimum acceptable value for the setting. + * @param max The maximum acceptable value for the setting. + * @return The corresponding setting value. + */ + public static final int convertGammaToLinear(int val, int min, int max) { + final float normalizedVal = MathUtils.norm(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, val); + final float ret; + if (normalizedVal <= R) { + ret = MathUtils.sq(normalizedVal / R); + } else { + ret = MathUtils.exp((normalizedVal - C) / A) + B; + } + + // HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1] + // in order to derive the correct setting value. + return Math.round(MathUtils.lerp(min, max, ret / 12)); + } + + /** + * Version of {@link #convertGammaToLinear} that takes and returns float values. + * TODO(flc): refactor Android Auto to use float version + * + * @param val The slider value. + * @param min The minimum acceptable value for the setting. + * @param max The maximum acceptable value for the setting. + * @return The corresponding setting value. + */ + public static final float convertGammaToLinearFloat(int val, float min, float max) { + final float normalizedVal = MathUtils.norm(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, val); + final float ret; + if (normalizedVal <= R) { + ret = MathUtils.sq(normalizedVal / R); + } else { + ret = MathUtils.exp((normalizedVal - C) / A) + B; + } + + // HLG is normalized to the range [0, 12], ensure that value is within that range, + // it shouldn't be out of bounds. + final float normalizedRet = MathUtils.constrain(ret, 0, 12); + + // Re-normalize to the range [0, 1] + // in order to derive the correct setting value. + return MathUtils.lerp(min, max, normalizedRet / 12); + } + + /** + * A function for converting from the linear space that the setting works in to the + * gamma space that the slider works in. + *

+ * The gamma space effectively provides us a way to make linear changes to the slider that + * result in linear changes in perception. If we made changes to the slider in the linear space + * then we'd see an approximately logarithmic change in perception (c.f. Fechner's Law). + *

+ * Internally, this implements the Hybrid Log Gamma opto-electronic transfer function, which is + * a slight improvement to the typical gamma transfer function for displays whose max + * brightness exceeds the 120 nit reference point, but doesn't set a specific reference + * brightness like the PQ function does. + *

+ * Note that this transfer function is only valid if the display's backlight value is a linear + * control. If it's calibrated to be something non-linear, then a different transfer function + * should be used. + * + * @param val The brightness setting value. + * @param min The minimum acceptable value for the setting. + * @param max The maximum acceptable value for the setting. + * @return The corresponding slider value + */ + public static final int convertLinearToGamma(int val, int min, int max) { + return convertLinearToGammaFloat((float) val, (float) min, (float) max); + } + + /** + * Version of {@link #convertLinearToGamma} that takes float values. + * TODO: brightnessfloat merge with above method(?) + * + * @param val The brightness setting value. + * @param min The minimum acceptable value for the setting. + * @param max The maximum acceptable value for the setting. + * @return The corresponding slider value + */ + public static final int convertLinearToGammaFloat(float val, float min, float max) { + // For some reason, HLG normalizes to the range [0, 12] rather than [0, 1] + final float normalizedVal = MathUtils.norm(min, max, val) * 12; + final float ret; + if (normalizedVal <= 1f) { + ret = MathUtils.sqrt(normalizedVal) * R; + } else { + ret = A * MathUtils.log(normalizedVal - B) + C; + } + + return Math.round(MathUtils.lerp(GAMMA_SPACE_MIN, GAMMA_SPACE_MAX, ret)); + } +} diff --git a/app/src/main/java/com/xwad/os/utils/FileUtil.java b/app/src/main/java/com/xwad/os/utils/FileUtil.java index 82131be..3eafcf6 100644 --- a/app/src/main/java/com/xwad/os/utils/FileUtil.java +++ b/app/src/main/java/com/xwad/os/utils/FileUtil.java @@ -19,6 +19,7 @@ import com.xwad.os.bean.AppUpdateInfo; import com.xwad.os.bean.AriaDownloadInfo; import com.xwad.os.bean.HomeworkBean; import com.xwad.os.gson.GsonUtils; +import com.xwad.os.mdm.AdminManager; import java.io.File; import java.io.FileInputStream; @@ -254,7 +255,7 @@ public class FileUtil { String fileMd5 = com.blankj.utilcode.util.FileUtils.getFileMD5ToString(file); Log.e("ariaDownload", "fileMD5 = " + fileMd5); if (fileMd5.equalsIgnoreCase(app_md5)) { - ApkUtils.installApkFile(context, file); + ApkUtils.installApp(context, file.getAbsolutePath()); } else { file.delete(); Aria.download(context) diff --git a/app/src/main/java/com/xwad/os/utils/GlideLoadUtils.java b/app/src/main/java/com/xwad/os/utils/GlideLoadUtils.java index 63d782e..b2ab4bb 100644 --- a/app/src/main/java/com/xwad/os/utils/GlideLoadUtils.java +++ b/app/src/main/java/com/xwad/os/utils/GlideLoadUtils.java @@ -61,6 +61,14 @@ public class GlideLoadUtils { } } + public void glideLoad(Context context, Drawable drawable, ImageView imageView) { + if (context != null) { + Glide.with(context).load(drawable).centerCrop().into(imageView); + } else { + Log.i(TAG, "Picture loading failed,context is null"); + } + } + public void glideLoad(Context context, File file, ImageView imageView, int default_image) { if (context != null) { Glide.with(context).load(file).centerCrop().error(default_image).into(imageView); diff --git a/app/src/main/java/com/xwad/os/utils/JgyUtils.java b/app/src/main/java/com/xwad/os/utils/JgyUtils.java index 6f1c9ad..9237e96 100644 --- a/app/src/main/java/com/xwad/os/utils/JgyUtils.java +++ b/app/src/main/java/com/xwad/os/utils/JgyUtils.java @@ -4,7 +4,6 @@ import android.annotation.SuppressLint; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.ActivityTaskManager; -import android.app.NotificationManager; import android.app.role.RoleManager; import android.content.ComponentName; import android.content.ContentResolver; @@ -84,13 +83,13 @@ public class JgyUtils { private ContentResolver resolver; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); - public static final int MINI2_PLATFORM = 28; - public static final int HONER_PLATFORM = 29; + public static final int HONOR_PLATFORM = 1; + public static final int LENOVO_PLATFORM = 2; public static final int UNKNOW_PLATFORM = 0; - public static final String MINI2_TAG = "6gen1s"; - public static final String HONER2_TAG = "honer"; + public static final String HONOR_TAG = "HONOR"; + public static final String LENOVO_TAG = "lenovo"; private HashSet ownApp = new HashSet() {{ @@ -405,13 +404,6 @@ public class JgyUtils { } } - public void killPackage(String pkg) { - Log.e(TAG, "killPackage: " + pkg); - ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); - manager.killBackgroundProcesses(pkg); - CmdUtil.execute("am force-stop " + pkg); - } - public void KillOTA() { ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); manager.killBackgroundProcesses("com.adups.fota"); @@ -435,7 +427,7 @@ public class JgyUtils { } public void openCubeOta() { - if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONER_PLATFORM + if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONOR_PLATFORM ) { openCubeUnisocOta(); // } else if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.MTKPlatform) { @@ -473,7 +465,7 @@ public class JgyUtils { public void openLauncher() { Log.e(TAG, "openLauncher: "); - killPackage("com.android.launcher3"); + AdminManager.getInstance().killApplicationProcess("com.android.launcher3"); Intent intent = new Intent(); // 为Intent设置Action、Category属性 intent.setAction(Intent.ACTION_MAIN);// "android.intent.action.MAIN" @@ -494,12 +486,12 @@ public class JgyUtils { public int checkAppPlatform() { String platform = BuildConfig.platform; - if (HONER2_TAG.equalsIgnoreCase(platform)) { + if (HONOR_TAG.equalsIgnoreCase(platform)) { Log.i(TAG, "checkAppPlatform: " + "honer"); - return HONER_PLATFORM; - } else if (MINI2_TAG.equalsIgnoreCase(platform)) { + return HONOR_PLATFORM; + } else if (LENOVO_TAG.equalsIgnoreCase(platform)) { Log.i(TAG, "checkAppPlatform: " + "6gen1s"); - return MINI2_PLATFORM; + return LENOVO_PLATFORM; } else { Log.i(TAG, "checkAppPlatform: " + "没有数据"); return UNKNOW_PLATFORM; @@ -512,17 +504,17 @@ public class JgyUtils { public void getAppPlatform(GetAppPlatformCallback getAppPlatformCallback) { String platform = BuildConfig.platform; - if (HONER2_TAG.equalsIgnoreCase(platform)) { - getAppPlatformCallback.AppPlatform(HONER_PLATFORM); - } else if (MINI2_TAG.equalsIgnoreCase(platform)) { - getAppPlatformCallback.AppPlatform(MINI2_PLATFORM); + if (HONOR_TAG.equalsIgnoreCase(platform)) { + getAppPlatformCallback.AppPlatform(HONOR_PLATFORM); + } else if (LENOVO_TAG.equalsIgnoreCase(platform)) { + getAppPlatformCallback.AppPlatform(LENOVO_PLATFORM); } else { getAppPlatformCallback.AppPlatform(UNKNOW_PLATFORM); } } public static String getCustomVersion() { - if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONER_PLATFORM + if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONOR_PLATFORM ) { return getProperty("ro.build.display.id", "获取失败"); } else { @@ -531,7 +523,7 @@ public class JgyUtils { } public static String getRomVersion() { - if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONER_PLATFORM + if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONOR_PLATFORM ) { return getProperty("ro.build.id", "获取失败"); } else { @@ -1306,7 +1298,9 @@ public class JgyUtils { Log.e(TAG, "startServices: noti = " + noti); if (noti) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + long time = System.currentTimeMillis(); mContext.startForegroundService(new Intent(mContext, MainService.class)); + Log.e(TAG, "setDefault: startServices time = " + (System.currentTimeMillis() - time) + "ms"); } else { mContext.startService(new Intent(mContext, MainService.class)); } diff --git a/app/src/main/java/com/xwad/os/utils/MathUtils.java b/app/src/main/java/com/xwad/os/utils/MathUtils.java new file mode 100644 index 0000000..4790c06 --- /dev/null +++ b/app/src/main/java/com/xwad/os/utils/MathUtils.java @@ -0,0 +1,196 @@ +package com.xwad.os.utils; + +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by Fernflower decompiler) +// + +public final class MathUtils { + private static final float DEG_TO_RAD = 0.017453292F; + private static final float RAD_TO_DEG = 57.295784F; + + private MathUtils() { + } + + public static float abs(float v) { + return v > 0.0F ? v : -v; + } + + public static int constrain(int amount, int low, int high) { + return amount < low ? low : (amount > high ? high : amount); + } + + public static long constrain(long amount, long low, long high) { + return amount < low ? low : (amount > high ? high : amount); + } + + public static float constrain(float amount, float low, float high) { + return amount < low ? low : (amount > high ? high : amount); + } + + public static float log(float a) { + return (float) Math.log((double) a); + } + + public static float exp(float a) { + return (float) Math.exp((double) a); + } + + public static float pow(float a, float b) { + return (float) Math.pow((double) a, (double) b); + } + + public static float sqrt(float a) { + return (float) Math.sqrt((double) a); + } + + public static float max(float a, float b) { + return a > b ? a : b; + } + + public static float max(int a, int b) { + return a > b ? (float) a : (float) b; + } + + public static float max(float a, float b, float c) { + return a > b ? (a > c ? a : c) : (b > c ? b : c); + } + + public static float max(int a, int b, int c) { + return a > b ? (float) (a > c ? a : c) : (float) (b > c ? b : c); + } + + public static float min(float a, float b) { + return a < b ? a : b; + } + + public static float min(int a, int b) { + return a < b ? (float) a : (float) b; + } + + public static float min(float a, float b, float c) { + return a < b ? (a < c ? a : c) : (b < c ? b : c); + } + + public static float min(int a, int b, int c) { + return a < b ? (float) (a < c ? a : c) : (float) (b < c ? b : c); + } + + public static float dist(float x1, float y1, float x2, float y2) { + float x = x2 - x1; + float y = y2 - y1; + return (float) Math.hypot((double) x, (double) y); + } + + public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) { + float x = x2 - x1; + float y = y2 - y1; + float z = z2 - z1; + return (float) Math.sqrt((double) (x * x + y * y + z * z)); + } + + public static float mag(float a, float b) { + return (float) Math.hypot((double) a, (double) b); + } + + public static float mag(float a, float b, float c) { + return (float) Math.sqrt((double) (a * a + b * b + c * c)); + } + + public static float sq(float v) { + return v * v; + } + + public static float dot(float v1x, float v1y, float v2x, float v2y) { + return v1x * v2x + v1y * v2y; + } + + public static float cross(float v1x, float v1y, float v2x, float v2y) { + return v1x * v2y - v1y * v2x; + } + + public static float radians(float degrees) { + return degrees * 0.017453292F; + } + + public static float degrees(float radians) { + return radians * 57.295784F; + } + + public static float acos(float value) { + return (float) Math.acos((double) value); + } + + public static float asin(float value) { + return (float) Math.asin((double) value); + } + + public static float atan(float value) { + return (float) Math.atan((double) value); + } + + public static float atan2(float a, float b) { + return (float) Math.atan2((double) a, (double) b); + } + + public static float tan(float angle) { + return (float) Math.tan((double) angle); + } + + public static float lerp(float start, float stop, float amount) { + return start + (stop - start) * amount; + } + + public static float lerpInv(float a, float b, float value) { + return a != b ? (value - a) / (b - a) : 0.0F; + } + + public static float saturate(float value) { + return constrain(value, 0.0F, 1.0F); + } + + public static float lerpInvSat(float a, float b, float value) { + return saturate(lerpInv(a, b, value)); + } + + public static float lerpDeg(float start, float end, float amount) { + float minAngle = (end - start + 180.0F) % 360.0F - 180.0F; + return minAngle * amount + start; + } + + public static float norm(float start, float stop, float value) { + return (value - start) / (stop - start); + } + + public static float map(float minStart, float minStop, float maxStart, float maxStop, float value) { + return maxStart + (maxStop - maxStart) * ((value - minStart) / (minStop - minStart)); + } + + public static float constrainedMap(float rangeMin, float rangeMax, float valueMin, float valueMax, float value) { + return lerp(rangeMin, rangeMax, lerpInvSat(valueMin, valueMax, value)); + } + + public static float smoothStep(float start, float end, float x) { + return constrain((x - start) / (end - start), 0.0F, 1.0F); + } + + public static int addOrThrow(int a, int b) throws IllegalArgumentException { + if (b == 0) { + return a; + } else if (b > 0 && a <= 2147483647 - b) { + return a + b; + } else if (b < 0 && a >= -2147483648 - b) { + return a + b; + } else { + throw new IllegalArgumentException("Addition overflow: " + a + " + " + b); + } + } + +// public static void fitRect(Rect outToResize, int largestSide) { +// if (!outToResize.isEmpty()) { +// float maxSize = (float)Math.max(outToResize.width(), outToResize.height()); +// outToResize.scale((float)largestSide / maxSize); +// } +// } +} + diff --git a/app/src/main/java/com/xwad/os/utils/ScreenUtils.java b/app/src/main/java/com/xwad/os/utils/ScreenUtils.java index de03bdb..795173f 100644 --- a/app/src/main/java/com/xwad/os/utils/ScreenUtils.java +++ b/app/src/main/java/com/xwad/os/utils/ScreenUtils.java @@ -1,9 +1,15 @@ package com.xwad.os.utils; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; +import android.util.Log; + +import java.lang.reflect.Method; public class ScreenUtils { + private static final String TAG = "ScreenUtils"; + /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ @@ -29,4 +35,51 @@ public class ScreenUtils { final float scale = resources.getDisplayMetrics().scaledDensity; return (int) (sp * scale); } + + public static String getSystemProperties(String key, String defaultValue) { + String value = defaultValue; + try { + Class c = Class.forName("android.os.SystemProperties"); + Method get = c.getMethod("get", String.class, String.class); + value = (String) (get.invoke(c, key, defaultValue)); + } catch (Exception e) { + e.printStackTrace(); + } finally { + return value; + } + } + + /** + * 应用需反射调用 + */ + public static boolean isTablet() { +// String characteristics = android.os.SystemProperties.get("ro.build.characteristics"); + String characteristics = getSystemProperties("ro.build.characteristics", "unknow"); + Log.e(TAG, "isTablet: " + characteristics); + return characteristics.contains("tablet"); + } + + public static boolean isTablet(Context context) { + boolean isTablet = (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; + Log.e(TAG, "isTablet: " + isTablet); + return isTablet; + } + + + public static int isTabletInt(Context context) { + boolean isTablet = (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; + Log.e(TAG, "isTablet: " + isTablet); + return isTablet ? 1 : 0; + } + + /** + * 是否是平板 + * + * @param context 上下文 + * @return 是平板则返回true,反之返回false + */ + public static boolean isPad(Context context) { + return (context.getResources().getConfiguration().screenLayout + & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE; + } } diff --git a/app/src/main/java/com/xwad/os/utils/TimeUtils.java b/app/src/main/java/com/xwad/os/utils/TimeUtils.java index 0523d15..d610e49 100644 --- a/app/src/main/java/com/xwad/os/utils/TimeUtils.java +++ b/app/src/main/java/com/xwad/os/utils/TimeUtils.java @@ -1,44 +1,86 @@ package com.xwad.os.utils; import android.content.Context; +import android.content.Intent; import android.os.Build; +import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.tencent.mmkv.MMKV; +import com.xwad.os.bean.TimeControl; +import com.xwad.os.config.CommonConfig; +import com.xwad.os.service.ManagerService; + +import java.lang.reflect.Type; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; +import java.util.List; import java.util.Locale; +import java.util.Objects; +import java.util.TimeZone; +import java.util.function.Function; +import java.util.stream.Collectors; public class TimeUtils { private static final String TAG = "TimeUtils"; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); - private static DateFormat df = new SimpleDateFormat("HH:mm", Locale.getDefault()); + private static DateFormat df = new SimpleDateFormat("HH:mm", Locale.CHINA); public static final long DAY_TIME = 60 * 60 * 24 * 1000; public static final long MINUTE_TIME = 60 * 1000; - @RequiresApi(api = Build.VERSION_CODES.O) - public static boolean isTodayTime(long timeStamp) { - String time = transferLongToDate(timeStamp); - DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - LocalDateTime localTime = LocalDateTime.parse(time, dtf); - LocalDateTime startTime = LocalDate.now().atTime(0, 0, 0); - LocalDateTime endTime = LocalDate.now().atTime(23, 59, 59); - return localTime.isAfter(startTime) && localTime.isBefore(endTime); + public static final String START_TIME_KEY = "START_TIME"; + public static final String END_TIME_KEY = "END_TIME"; + public static final String WEEK_START_TIME_KEY = "WEEK_START_TIME"; + public static final String WEEK_END_TIME_KEY = "WEEK_END_TIME"; + + /*新增 时间控制开关*/ + public static final String AOLELEARN_TIME_CONTROL_KEY = "aolelearn_time_control"; + /*多个时间段*/ + public static final String AOLELEARN_TTIMECONTROL_LIST_KEY = "aolelearn_timecontrol_list"; + + /*可以使用时间开始*/ + @Deprecated + public static final String AOLELEARN_TTIMECONTROL_START_KEY = "aolelearn_timecontrol_start"; + /*可以使用时间结束*/ + @Deprecated + public static final String AOLELEARN_TTIMECONTROL_END_KEY = "aolelearn_timecontrol_end"; + + + public static String getNowTime() { + long nowTime = System.currentTimeMillis(); + DateFormat df = ContralTime.getDf(); + return df.format(nowTime); } - public static String transferLongToDate(Long millisecond) { - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - Date date = new Date(millisecond); +// public static boolean CurrentInTimeScope(ContralTime contralTime) { +// boolean result = true; +// final long aDayInMillis = 1000 * 60 * 60 * 24; +// long currentTimeMillis = System.currentTimeMillis(); +// +// } + + public static String transferLongToDate(Long millSec) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); + Date date = new Date(millSec); return sdf.format(date); } @@ -55,6 +97,28 @@ public class TimeUtils { return dateString + "\t" + getWeek(); } + + public static String transferSecondToDate(long second) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); + + Date date = new Date(second * 1000); + return sdf.format(date); + } + + public static String transferSecond(long second) { + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); + sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + Date date = new Date(second * 1000); + return sdf.format(date); + } + + public static String getPhotoDate() { + long millisecond = System.currentTimeMillis(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + Date date = new Date(millisecond); + return sdf.format(date); + } + public static String getHomeworkTime(String timeString) { SimpleDateFormat old = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); @@ -168,6 +232,244 @@ public class TimeUtils { return String.format("%d小时%d分", hour, min); } + private static final long ONE_DAY_TIME_OF_SECOND = 24 * 60 * 60; + + public static long timestampInterval(long nowTime, long expireTime) { + long num = expireTime - nowTime;//时间戳相差的毫秒数 + long day = num / ONE_DAY_TIME_OF_SECOND; + return day; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public static boolean isTodayTime(long timeStamp) { + String time = transferLongToDate(timeStamp); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + LocalDateTime localTime = LocalDateTime.parse(time, dtf); + LocalDateTime startTime = LocalDate.now().atTime(0, 0, 0); + LocalDateTime endTime = LocalDate.now().atTime(23, 59, 59); + return localTime.isAfter(startTime) && localTime.isBefore(endTime); + } + + public static ContralTime String2WorkingTime(Context context, @NonNull String timeText) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + DateFormat df = ContralTime.getDf(); + String[] time = timeText.trim().split("-"); + if (time.length != 2) { +// return null; + throw new RuntimeException("Time format error!" + Arrays.toString(time)); + } + try { + mmkv.encode(START_TIME_KEY, time[0].trim()); + mmkv.encode(END_TIME_KEY, time[1].trim()); + Date startDate = df.parse(time[0].trim()); + Date endDate = df.parse(time[1].trim()); + ContralTime contralTime = new ContralTime(); +// if (date1.getTime() < date2.getTime()) { + contralTime.setStartTime(df.format(startDate)); + contralTime.setEndTime(df.format(endDate)); +// } else { +// contralTime.setStartTime(df.format(date2)); +// contralTime.setEndTime(df.format(date1)); +// } + return contralTime; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * @param context + * @param timeText HH:mm-HH:mm 格式转化为ContralTime + * @return + */ + public static ContralTime string2WeekTime(Context context, @NonNull String timeText) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + DateFormat df = ContralTime.getDf(); + String[] time = timeText.trim().split("-"); + if (time.length != 2) { +// return null; + throw new RuntimeException("Time format error!" + Arrays.toString(time)); + } + try { + mmkv.encode(WEEK_START_TIME_KEY, time[0].trim()); + mmkv.encode(WEEK_END_TIME_KEY, time[1].trim()); + Date startDate = df.parse(time[0].trim()); + Date endDate = df.parse(time[1].trim()); + ContralTime contralTime = new ContralTime(); +// if (date1.getTime() < date2.getTime()) { + contralTime.setStartTime(df.format(startDate)); + contralTime.setEndTime(df.format(endDate)); +// } else { +// contralTime.setStartTime(df.format(date2)); +// contralTime.setEndTime(df.format(date1)); +// } + return contralTime; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取工作日时间控制 + * + * @param context + * @return + */ + @Deprecated + public static ContralTime getWorkingDayContralTime(Context context) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + String startTime = mmkv.decodeString(START_TIME_KEY, "00:00"); + String endTime = mmkv.decodeString(END_TIME_KEY, "00:00"); + return getContralTime(context, startTime, endTime); + } + + /** + * 获取休息日时间控制 + * + * @param context + * @return + */ + @Deprecated + public static ContralTime getWeekDayContralTime(Context context) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + String startTime = mmkv.decodeString(WEEK_START_TIME_KEY, "00:00"); + String endTime = mmkv.decodeString(WEEK_END_TIME_KEY, "00:00"); + return getContralTime(context, startTime, endTime); + } + + /** + * 是否在管控时间内 + * + * @param workingTime + * @param weekTime + * @return + */ + @Deprecated + public static boolean inContralTime(ContralTime workingTime, ContralTime weekTime) { + if (inWeekDay()) { + if (weekTime == null) { + return false; + } else { + return weekTime.inControlTime(); + } + } else { + if (workingTime == null) { + return false; + } else { + return workingTime.inControlTime(); + } + } + } + + /** + * 获取新的时间管控 + * + * @param context + * @return + */ + @Deprecated + public static ContralTime getDayContralTime(Context context) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + String timecontrol_start = mmkv.decodeString(AOLELEARN_TTIMECONTROL_START_KEY, "00:00"); + String timecontrol_end = mmkv.decodeString(AOLELEARN_TTIMECONTROL_END_KEY, "00:00"); + return getContralTime(context, timecontrol_start, timecontrol_end); + } + + @Deprecated + public static boolean inDayContralTime(ContralTime contralTime) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + int is_timecontrol = mmkv.decodeInt(TimeUtils.AOLELEARN_TIME_CONTROL_KEY, 0); + if (is_timecontrol == 0) { + return false; + } + if (contralTime == null) { + return false; + } + if ("00:00".equals(contralTime.getStartTime()) && "00:00".equals(contralTime.getEndTime()) + || "00:00".equals(contralTime.getStartTime()) && "24:00".equals(contralTime.getEndTime()) + || "24:00".equals(contralTime.getStartTime()) && "00:00".equals(contralTime.getEndTime()) + || Objects.equals(contralTime.getStartTime(), contralTime.getEndTime()) + ) { + return false; + } + return contralTime.inControlTime(); + } + + public static List getDayContralTimeList(Context context) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + String listJsonString = mmkv.decodeString(AOLELEARN_TTIMECONTROL_LIST_KEY, ""); + if (!TextUtils.isEmpty(listJsonString)) { + Gson gson = new Gson(); + Type listType = new TypeToken>() { + }.getType(); + try { + List timeControls = gson.fromJson(listJsonString, listType); + List contralTimes = timeControls.stream().map(new Function() { + @Override + public ContralTime apply(TimeControl timeControl) { + return getContralTime(context, timeControl.getStart_time(), timeControl.getEnd_time()); + } + }).collect(Collectors.toList()); + return contralTimes; + } catch (Exception e) { + Log.e(TAG, "getDayContralTimeList: " + e.getMessage()); + mmkv.remove(AOLELEARN_TTIMECONTROL_LIST_KEY); + } + } + return null; + } + + public static boolean inDayContralTime(List contralTimes) { + Log.e(TAG, "inDayContralTime: " + contralTimes); + if (contralTimes == null || contralTimes.isEmpty()) { + Log.e(TAG, "inDayContralTime: isEmpty"); + return false; + } + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + int is_timecontrol = mmkv.decodeInt(TimeUtils.AOLELEARN_TIME_CONTROL_KEY, 0); + if (is_timecontrol == 0) { + Log.e(TAG, "inDayContralTime: false"); + return false; + } + List booleans = new ArrayList<>(); + for (ContralTime contralTime : contralTimes) { + if (contralTime == null) { + continue; + } + if ("00:00".equals(contralTime.getStartTime()) && "00:00".equals(contralTime.getEndTime()) + || "00:00".equals(contralTime.getStartTime()) && "24:00".equals(contralTime.getEndTime()) + || "24:00".equals(contralTime.getStartTime()) && "00:00".equals(contralTime.getEndTime()) + || Objects.equals(contralTime.getStartTime(), contralTime.getEndTime()) + ) { + continue; + } + booleans.add(contralTime.inControlTime()); +// if (!contralTime.inControlTime()) { +// Log.e(TAG, "inDayContralTime: " + contralTime + " true"); +// return true; +// } + } + Log.e(TAG, "inDayContralTime: " + booleans); + return !booleans.contains(false); +// Log.e(TAG, "inDayContralTime: false"); +// return false; + } + + public static String getDayTimeString(Context context) { +// ContralTime contralTime = getDayContralTime(context); + List contralTimes = TimeUtils.getDayContralTimeList(context); + StringBuilder stringBuilder = new StringBuilder(); + if (contralTimes != null) { + for (ContralTime contralTime : contralTimes) { + stringBuilder.append(contralTime).append("\t"); + } + } + return stringBuilder.toString(); + } + + /** * 是否在管控时间内 * @@ -194,7 +496,6 @@ public class TimeUtils { } } - /** * @return 根据日期取得星期几 */ @@ -210,6 +511,140 @@ public class TimeUtils { return weeks[weekIndex]; } + /** + * 获取控制时间文本 + * + * @param context + * @return + */ + @Deprecated + public static String getNowTimeString(Context context) { + ContralTime work = getWorkingDayContralTime(context); + ContralTime week = getWeekDayContralTime(context); + StringBuilder stringBuilder = new StringBuilder(); + if (work != null) { + stringBuilder.append("周一至周五:").append(work).append("\n"); + } + if (week != null) { + stringBuilder.append("周末:").append(week); + } + return stringBuilder.toString(); + } + + /** + * 设置为空 + * + * @param context + */ + public static void setEmpty(Context context) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + mmkv.encode(START_TIME_KEY, "00:00"); + mmkv.encode(END_TIME_KEY, "00:00"); + mmkv.encode(WEEK_START_TIME_KEY, "00:00"); + mmkv.encode(WEEK_END_TIME_KEY, "00:00"); + Intent intent = new Intent(); + intent.setAction(ManagerService.ACTION_UPDATE); + context.sendBroadcast(intent); + } + + /** + * 获取格式化后的时间 + * + * @param time 时间戳 + * @return 时间戳格式化文本 + */ + public static String getDate(long time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String finaWayDate = sdf.format(time); + Log.e(TAG, "getDate: " + finaWayDate); + return finaWayDate; + } + + /** + * 获取周几 + * + * @return 周几的数字 + */ + public static int getWeekDay() { + long time = System.currentTimeMillis(); + Log.e(TAG, "getWeekDay: " + time); + return getWeekDay(time); + } + + /** + * 获取周几 + * + * @param time 时间戳 + * @return 周几的数字 1-7 + */ + public static int getWeekDay(long time) { + getDate(time); + Calendar now = Calendar.getInstance(); + now.setTimeInMillis(time); + //一周第一天是否为星期天 + boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY); + //获取周几 + int weekDay = now.get(Calendar.DAY_OF_WEEK); + //若一周第一天为星期天,则-1 + if (isFirstSunday) { + weekDay = weekDay - 1; + if (weekDay == 0) { + weekDay = 7; + } + } + return weekDay; + } + + private String[] weekDays = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"}; + + /** + * 获取星期几 + * + * @return 星期的文本 + */ + public String getWeekDayString() { + return weekDays[getWeekDay() - 1]; + } + + /** + * 获取星期几 + * + * @param time 时间戳 + * @return 星期的文本 + */ + public String getWeekDayString(long time) { + return weekDays[getWeekDay(time) - 1]; + } + + /** + * 是否未周末 + * + * @return 周末返回ture 工作日返回false + */ + public static boolean inWeekDay() { + long time = System.currentTimeMillis(); + return inWeekDay(time); + } + + /** + * 是否未周末 + * + * @param time 时间戳 + * @return 周末返回ture 工作日返回false + */ + public static boolean inWeekDay(long time) { + int weekDay = getWeekDay(time); + if (weekDay > 5) { + return true; + } else { + return false; + } + } + + public static void setSystemTime(long time) { + SystemClock.setCurrentTimeMillis(time); + } + public static class ContralTime { //format HH:mm String startTime; @@ -253,13 +688,16 @@ public class TimeUtils { return df.format(new Date(time)); } + public boolean inControlTime() { long time = System.currentTimeMillis(); return inControlTime(time); } public boolean inControlTime(long time) { - return inControlTime(df.format(new Date(time))); + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + return inControlTime(sdf.format(new Date(time))); } public boolean inControlTime(String time) { @@ -280,8 +718,7 @@ public class TimeUtils { } Log.e(TAG, "inControlTime: " + (startDate.getTime() - MINUTE_TIME)); assert nowDate != null; -// if (nowDate.getTime() <= startDate.getTime() - MINUTE_TIME || nowDate.getTime() >= endDate.getTime()) { - if (nowDate.getTime() >= startDate.getTime() && nowDate.getTime() <= endDate.getTime()) { + if (nowDate.getTime() <= startDate.getTime() - MINUTE_TIME || nowDate.getTime() >= endDate.getTime()) { return true; } else { return false; @@ -295,8 +732,221 @@ public class TimeUtils { @NonNull @Override public String toString() { - return startTime + "\t-\t" + endTime; + return startTime + " - " + endTime; } } + private static SntpClient mNtpClient; + + public static long getTimeFromNtpServer(String hostAddress) { + Log.d(TAG, "getTimeFromNtpServer()"); + if (TextUtils.isEmpty(hostAddress)) { + Log.e(TAG, "Ntp host is null."); + return -1; + } + if (mNtpClient == null) { + mNtpClient = new SntpClient(); + } + boolean isSuccessful = mNtpClient.requestTime(hostAddress, 20000); + Log.e(TAG, "requestTime:" + isSuccessful); + if (isSuccessful) { + long now = mNtpClient.getNtpTime();//now就是获取的时间 + return now; + } else { + + } + return -1; + } + + public static class SntpClient { + private static final String TAG = "SntpClient"; + + private static final int REFERENCE_TIME_OFFSET = 16; + private static final int ORIGINATE_TIME_OFFSET = 24; + private static final int RECEIVE_TIME_OFFSET = 32; + private static final int TRANSMIT_TIME_OFFSET = 40; + private static final int NTP_PACKET_SIZE = 48; + + private static final int NTP_PORT = 123; + private static final int NTP_MODE_CLIENT = 3; + private static final int NTP_VERSION = 3; + + // Number of seconds between Jan 1, 1900 and Jan 1, 1970 + // 70 years plus 17 leap days + private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L; + + // system time computed from NTP server response + private long mNtpTime; + + // value of SystemClock.elapsedRealtime() corresponding to mNtpTime + private long mNtpTimeReference; + + // round trip time in milliseconds + private long mRoundTripTime; + + /** + * Sends an SNTP request to the given host and processes the response. + * + * @param host host name of the server. + * @param timeout network timeout in milliseconds. + * @return true if the transaction was successful. + */ + public boolean requestTime(String host, int timeout) { + DatagramSocket socket = null; + try { + socket = new DatagramSocket(); + socket.setSoTimeout(timeout); + InetAddress address = InetAddress.getByName(host); + byte[] buffer = new byte[NTP_PACKET_SIZE]; + DatagramPacket request = new DatagramPacket(buffer, + buffer.length, address, NTP_PORT); + + // set mode = 3 (client) and version = 3 + // mode is in low 3 bits of first byte + // version is in bits 3-5 of first byte + buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3); + + // get current time and write it to the request packet + long requestTime = System.currentTimeMillis(); + Log.d(TAG, "RequestTime:" + new Date(requestTime)); + long requestTicks = SystemClock.elapsedRealtime(); + writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime); + + socket.send(request); + + // read the response + DatagramPacket response = new DatagramPacket(buffer, + buffer.length); + socket.receive(response); + long responseTicks = SystemClock.elapsedRealtime(); + long responseTime = requestTime + + (responseTicks - requestTicks); + + // extract the results + long originateTime = readTimeStamp(buffer, + ORIGINATE_TIME_OFFSET); + long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET); + long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET); + long roundTripTime = responseTicks - requestTicks + - (transmitTime - receiveTime); + // receiveTime = originateTime + transit + skew + // responseTime = transmitTime + transit - skew + // clockOffset = ((receiveTime - originateTime) + (transmitTime + // - responseTime))/2 + // = ((originateTime + transit + skew - originateTime) + + // (transmitTime - (transmitTime + transit - skew)))/2 + // = ((transit + skew) + (transmitTime - transmitTime - transit + // + skew))/2 + // = (transit + skew - transit + skew)/2 + // = (2 * skew)/2 = skew + long clockOffset = ((receiveTime - requestTime) + (transmitTime - System.currentTimeMillis())) / 2; + // if (false) Log.d(TAG, "round trip: " + roundTripTime + + // " ms"); + // if (false) Log.d(TAG, "clock offset: " + clockOffset + + // " ms"); + + // save our results - use the times on this side of the network + // latency + // (response rather than request time) + mNtpTime = System.currentTimeMillis() + clockOffset; +// mNtpTime = transmitTime; + mNtpTimeReference = responseTicks; + mRoundTripTime = roundTripTime; + } catch (Exception e) { + if (false) + Log.e(TAG, "request time failed:" + e); + e.printStackTrace(); + return false; + } finally { + if (socket != null) { + socket.close(); + } + } + + return true; + } + + /** + * Returns the time computed from the NTP transaction. + * + * @return time value computed from NTP server response. + */ + public long getNtpTime() { + return mNtpTime; + } + + /** + * Returns the reference clock value (value of + * SystemClock.elapsedRealtime()) corresponding to the NTP time. + * + * @return reference clock corresponding to the NTP time. + */ + public long getNtpTimeReference() { + return mNtpTimeReference; + } + + /** + * Returns the round trip time of the NTP transaction + * + * @return round trip time in milliseconds. + */ + public long getRoundTripTime() { + return mRoundTripTime; + } + + /** + * Reads an unsigned 32 bit big endian number from the given offset in + * the buffer. + */ + private long read32(byte[] buffer, int offset) { + byte b0 = buffer[offset]; + byte b1 = buffer[offset + 1]; + byte b2 = buffer[offset + 2]; + byte b3 = buffer[offset + 3]; + + // convert signed bytes to unsigned values + int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0); + int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1); + int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2); + int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3); + + return ((long) i0 << 24) + ((long) i1 << 16) + ((long) i2 << 8) + + (long) i3; + } + + /** + * Reads the NTP time stamp at the given offset in the buffer and + * returns it as a system time (milliseconds since January 1, 1970). + */ + private long readTimeStamp(byte[] buffer, int offset) { + long seconds = read32(buffer, offset); + long fraction = read32(buffer, offset + 4); + return ((seconds - OFFSET_1900_TO_1970) * 1000) + + ((fraction * 1000L) / 0x100000000L); + } + + /** + * Writes system time (milliseconds since January 1, 1970) as an NTP + * time stamp at the given offset in the buffer. + */ + private void writeTimeStamp(byte[] buffer, int offset, long time) { + long seconds = time / 1000L; + long milliseconds = time - seconds * 1000L; + seconds += OFFSET_1900_TO_1970; + + // write seconds in big endian format + buffer[offset++] = (byte) (seconds >> 24); + buffer[offset++] = (byte) (seconds >> 16); + buffer[offset++] = (byte) (seconds >> 8); + buffer[offset++] = (byte) (seconds >> 0); + + long fraction = milliseconds * 0x100000000L / 1000L; + // write fraction in big endian format + buffer[offset++] = (byte) (fraction >> 24); + buffer[offset++] = (byte) (fraction >> 16); + buffer[offset++] = (byte) (fraction >> 8); + // low order bits should be random data + buffer[offset++] = (byte) (Math.random() * 255.0); + } + } } diff --git a/app/src/main/java/com/xwad/os/utils/Utils.java b/app/src/main/java/com/xwad/os/utils/Utils.java index 48d6e18..825463e 100644 --- a/app/src/main/java/com/xwad/os/utils/Utils.java +++ b/app/src/main/java/com/xwad/os/utils/Utils.java @@ -2,6 +2,9 @@ package com.xwad.os.utils; import android.Manifest; import android.app.Activity; +import android.app.ActivityManager; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; @@ -14,13 +17,19 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; +import android.media.AudioManager; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.BatteryManager; import android.os.Build; import android.os.Environment; import android.os.PowerManager; +import android.os.StatFs; +import android.os.SystemClock; +import android.provider.Settings; +import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.text.format.Formatter; import android.util.DisplayMetrics; import android.util.Log; import android.view.WindowManager; @@ -28,18 +37,23 @@ import android.view.WindowManager; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; +import com.google.gson.JsonObject; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import com.tencent.mmkv.MMKV; import com.xwad.os.BuildConfig; import com.xwad.os.R; +import com.xwad.os.config.CommonConfig; import com.xwad.os.mdm.AdminManager; +import com.xwad.os.network.NetInterfaceManager; import java.io.BufferedReader; import java.io.File; +import java.io.FileFilter; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; @@ -47,11 +61,17 @@ import java.io.LineNumberReader; import java.io.Reader; import java.lang.reflect.Method; import java.net.NetworkInterface; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import static android.content.Context.WIFI_SERVICE; public class Utils { private static final String TAG = "Utils"; @@ -333,6 +353,60 @@ public class Utils { return "未获取到设备Mac地址"; } + public static String getIMEI(Context context) { + String IMEI = "unknown"; + String IMEI1, IMEI2, IMEI3; + //获取手机设备号 + TelephonyManager TelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + //8.0及以后版本获取 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + try { + IMEI = TelephonyMgr.getDeviceId(); + } catch (Exception e) { + Log.e(TAG, "getIMEI: " + e.getMessage()); + } + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { +// try { +// Method method = TelephonyMgr.getClass().getMethod("getImei"); +// IMEI = (String) method.invoke(TelephonyMgr); +// } catch (Exception e) { +// e.printStackTrace(); +// Log.e("getIMEI", e.getMessage()); +// } +// IMEI = TelephonyMgr.getDeviceId(); + +// } else {//9.0到10.0获取 + IMEI = Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); + } +// Log.e("IMEI:", "IMEI: " + IMEI); + if (null == IMEI) { + return "-"; + } else { + return IMEI.toUpperCase(); + } + } + + /** + * 获取电池容量 + * + * @param context + * @return + */ + public static double getBatterymAh(Context context) { + Object mPowerProfile; + double batteryCapacity = 0; //电池的容量mAh + final String POWER_PROFILE_CLASS = "com.android.internal.os.PowerProfile"; + try { + mPowerProfile = Class.forName(POWER_PROFILE_CLASS).getConstructor(Context.class).newInstance(context); + batteryCapacity = (double) Class.forName(POWER_PROFILE_CLASS).getMethod("getBatteryCapacity").invoke(mPowerProfile); + Log.e("getBattery", "battery mAh: " + batteryCapacity); + } catch (Exception e) { + Log.e("getBattery", "get batteryCapacity mAh error:" + batteryCapacity); + e.printStackTrace(); + } + return batteryCapacity; + } + /** * 获取电量 * @@ -571,6 +645,28 @@ public class Utils { return macSerial; } + // MD5 设备地址标识 + public static String getMAC(Context context) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 如果当前设备系统大于等于6.0 使用下面的方法 + return getMac(); + } else { + try { + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + // 获取MAC地址 + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + String mac = wifiInfo.getMacAddress(); + if (null == mac) { + // 未获取到 + mac = ""; + } + return mac; + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + } + } + public static String loadFileAsString(String fileName) throws Exception { FileReader reader = new FileReader(fileName); String text = loadReaderAsString(reader); @@ -605,4 +701,287 @@ public class Utils { } return cachePath; } + + public static String getMachine(Context context) { + MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + String device = Build.MODEL;//机型 + String imei = getIMEI(context); + Log.e(TAG, "getMachine: " + imei); + String system_version = Build.VERSION.RELEASE; + String firmware_version = JgyUtils.getRomVersion(); + String rom = JgyUtils.getCustomVersion(); + String pushid = mMMKV.decodeString(CommonConfig.ALIYUN_PUSH_ID, ""); + String screen_rate = getAndroiodScreenProperty(context); + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("device", device); + jsonObject.addProperty("imei", imei); + jsonObject.addProperty("system_version", system_version); + jsonObject.addProperty("firmware_version", firmware_version); + jsonObject.addProperty("rom", rom); + jsonObject.addProperty("push_id", pushid); + jsonObject.addProperty("screen_rate", screen_rate); + return jsonObject.toString(); + } + + public static String getHardware(Context context) { + MMKV mmkv = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + int electric = getBattery(context); + int charging = getIsCharging(context); + String memory = Formatter.formatFileSize(context, getUsedMemory(context)) + "\t 已用" + "/" + "共" + Formatter.formatFileSize(context, getTotalMemory(context)); + Log.e(TAG, "getHardware: memory = " + memory); + int use_ram = (int) ((float) (1.0 * getUsedMemory(context)) / (1.0 * getTotalMemory(context)) * 100); + Log.e(TAG, "getHardware: use_ram = " + use_ram); + String storage = getUsedSize(context) + "/" + getDataTotalSize(context); + Log.e(TAG, "getHardware: storage = " + storage); + double use_space = getUse_space(context); + Log.e(TAG, "getHardware: use_space = " + use_space); + long wifi_time = mmkv.decodeLong("wifi_last_connect_time", 0L) / 1000; + Log.e(TAG, "getHardware: wifi_time" + wifi_time); + int CPU = getNumCores(); + WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE); + // WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + WifiInfo info = wifiManager.getConnectionInfo(); + + AudioManager mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + //最大音量 + int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + Log.e(TAG, "getHardware: maxVolume = " + maxVolume); + //音量 + int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); + Log.e(TAG, "getHardware: streamVolume = " + streamVolume); + int currentVolume = (int) (((double) streamVolume / (double) maxVolume) * 100f); + Log.e(TAG, "getHardware: currentVolume = " + currentVolume); + + //亮度 + int brightness = Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0); + Log.e(TAG, "getHardware: brightness = " + brightness); + int gamma = BrightnessUtils.convertLinearToGamma(brightness, 1, 255); + Log.e(TAG, "getHardware: gamma = " + gamma); + long percentage = Math.round((((double) gamma / 65535) * 100f)); + Log.e(TAG, "getHardware: percentage = " + percentage); + + //字体大小 + float fontScale = Settings.System.getFloat(context.getContentResolver(), Settings.System.FONT_SCALE, 0.0f); + Log.e(TAG, "getHardware: fontScale = " + fontScale); + List mEntries = Arrays.asList(context.getResources().getStringArray(R.array.entries_font_size)); + List strEntryValues = Arrays.asList(context.getResources().getStringArray(R.array.entryvalues_font_size)); + String font_size; + int index = strEntryValues.indexOf(String.valueOf(fontScale)); + if (index == -1) { + font_size = "默认"; + } else { + font_size = mEntries.get(index); + } + Log.e(TAG, "getHardware: font_size = " + font_size); + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("electric", electric); + jsonObject.addProperty("charging", charging); + jsonObject.addProperty("memory", memory); + jsonObject.addProperty("mac", getMAC(context)); + jsonObject.addProperty("storage", storage); + jsonObject.addProperty("is_wifi", JgyUtils.getInstance().isWifiConnect()); + jsonObject.addProperty("CPU", CPU + "核"); + jsonObject.addProperty("use_space", use_space); + jsonObject.addProperty("use_ram", use_ram); + jsonObject.addProperty("wifi_ssid", getWifiSSID(context)); + jsonObject.addProperty("wifi_time", wifi_time); + jsonObject.addProperty("boot_time", SystemClock.elapsedRealtime()); + jsonObject.addProperty("battery_capacity", getBatterymAh(context)); + jsonObject.addProperty("wifi_signal", info.getRssi()); + jsonObject.addProperty("bluetooth", getBluetoothList()); + jsonObject.addProperty("current_volume", currentVolume); + jsonObject.addProperty("current_brightness", percentage); + jsonObject.addProperty("font_scale", font_size); + jsonObject.addProperty("ip", MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE).decodeString(NetInterfaceManager.WHOIS_IP, "未知")); + + Log.e(TAG, "getHardware: " + jsonObject.toString()); + return jsonObject.toString(); + } + + public static String getWifiSSID(Context context) { + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + if (wifiInfo != null) { + return wifiInfo.getSSID(); + } else { + return ""; + } + } + + public static String getBluetoothList() { + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (bluetoothAdapter == null) { + return "没有蓝牙设备"; + } else { + if (!bluetoothAdapter.isEnabled())//判断蓝牙设备是否已开起 + { + return "蓝牙未开启"; +// //开起蓝牙设备 +// Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); +// context.startActivity(intent); + } else { + Set devices = bluetoothAdapter.getBondedDevices(); + StringBuilder stringBuilder = new StringBuilder(); + for (Iterator iterator = devices.iterator(); iterator.hasNext(); ) { + BluetoothDevice device = iterator.next(); + stringBuilder.append(device.getAlias()).append(";"); + } + Log.e(TAG, "getBluetoothList: " + stringBuilder.toString()); + return stringBuilder.toString(); + } + } + } + + public static int getBattery(Context context) { + try { + BatteryManager batteryManager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE); + return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); + } catch (Exception e) { + Log.e("getBattery", "getBattery" + e.getMessage()); + } + return 0; + } + + public static int getIsCharging(Context context) { + IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); + Intent batteryStatus = context.registerReceiver(null, ifilter); + // Are we charging / charged? + int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); + boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || + status == BatteryManager.BATTERY_STATUS_FULL; + + // How are we charging? +// int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); +// boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; +// boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; + if (isCharging) { + return 1; + } else { + return 0; + } + } + + /** + * @param context + * @return 已经使用 + */ + public static long getUsedMemory(Context context) { + ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); + activityManager.getMemoryInfo(memoryInfo); + long freeMem = memoryInfo.totalMem - memoryInfo.availMem; +// Log.e("getHardware", "getFreeMemory: " + freeMem); + return freeMem; + } + + /** + * 描述:获取可用内存. + * + * @param context + * @return + */ + public static long getAvailMemory(Context context) { + // 获取android当前可用内存大小 + ActivityManager activityManager = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); + activityManager.getMemoryInfo(memoryInfo); + // 当前系统可用内存 ,将获得的内存大小规格化 + + return memoryInfo.availMem; + } + + /** + * 描述:总内存. + * + * @param context + * @return + */ + public static long getTotalMemory(Context context) { + // 系统内存信息文件 + String file = "/proc/meminfo"; + String memInfo; + String[] strs; + long memory = 0; + + try { + FileReader fileReader = new FileReader(file); + BufferedReader bufferedReader = new BufferedReader(fileReader, 8192); + // 读取meminfo第一行,系统内存大小 + memInfo = bufferedReader.readLine(); + strs = memInfo.split("\\s+"); +// for (String str : strs) { +// L.d(AppUtil.class, str + "\t"); +// } + // 获得系统总内存,单位KB + memory = Integer.valueOf(strs[1]).intValue(); + bufferedReader.close(); + } catch (Exception e) { + e.printStackTrace(); + } + // Byte转位KB或MB + return memory * 1024; + } + + public static float getUse_space(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long availableSize = sf.getAvailableBytes(); + Log.e(TAG, "getUse_space: availableSize = " + availableSize); + long blockSize = sf.getBlockSize(); + Log.e(TAG, "getUse_space: blockSize = " + blockSize); + long totalBlocks = sf.getBlockCount(); + Log.e(TAG, "getUse_space: totalBlocks = " + totalBlocks); + + return (float) 100.0 * ((blockSize * totalBlocks) - availableSize) / (blockSize * totalBlocks); + } + + public static String getRemnantSize(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long availableSize = sf.getAvailableBytes(); + return Formatter.formatFileSize(context, availableSize); + } + + public static String getUsedSize(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long availableSize = sf.getAvailableBytes(); + long blockSize = sf.getBlockSize(); + long totalBlocks = sf.getBlockCount(); + return Formatter.formatFileSize(context, blockSize * totalBlocks - availableSize); + } + + public static String getDataTotalSize(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long blockSize = sf.getBlockSize(); + long totalBlocks = sf.getBlockCount(); + return Formatter.formatFileSize(context, blockSize * totalBlocks); + } + + private static int getNumCores() { + // Private Class to display only CPU devices in the directory listing + class CpuFilter implements FileFilter { + @Override + public boolean accept(File pathname) { + // Check if filename is "cpu", followed by a single digit number + if (Pattern.matches("cpu[0-9]", pathname.getName())) { + return true; + } + return false; + } + } + + try { + // Get directory containing CPU info + File dir = new File("/sys/devices/system/cpu/"); + // Filter to only list the devices we care about + File[] files = dir.listFiles(new CpuFilter()); + // Return the number of cores (virtual CPU devices) + return files.length; + } catch (Exception e) { + // Default to return 1 core + return 1; + } + } } diff --git a/app/src/main/res/drawable-hdpi/icon_homework.png b/app/src/main/res/drawable-hdpi/icon_homework.png new file mode 100644 index 0000000..bb2ac25 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_homework.png differ diff --git a/app/src/main/res/drawable/bt_disable.xml b/app/src/main/res/drawable/bt_disable.xml new file mode 100644 index 0000000..90c8cfd --- /dev/null +++ b/app/src/main/res/drawable/bt_disable.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_main_background.xml b/app/src/main/res/drawable/bt_main_background.xml new file mode 100644 index 0000000..7233ecf --- /dev/null +++ b/app/src/main/res/drawable/bt_main_background.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_pressed.xml b/app/src/main/res/drawable/bt_pressed.xml new file mode 100644 index 0000000..9b667f9 --- /dev/null +++ b/app/src/main/res/drawable/bt_pressed.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/debug_edit_background.xml b/app/src/main/res/drawable/debug_edit_background.xml new file mode 100644 index 0000000..6130919 --- /dev/null +++ b/app/src/main/res/drawable/debug_edit_background.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/home_card_bg.xml b/app/src/main/res/drawable/home_card_bg.xml new file mode 100644 index 0000000..86f1dd3 --- /dev/null +++ b/app/src/main/res/drawable/home_card_bg.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_debug.xml b/app/src/main/res/layout/activity_debug.xml new file mode 100644 index 0000000..75aa6e4 --- /dev/null +++ b/app/src/main/res/layout/activity_debug.xml @@ -0,0 +1,514 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index aee66b2..30dbf4e 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -39,6 +39,24 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + android:layout_marginStart="3dp" + android:visibility="gone" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_update.xml b/app/src/main/res/layout/activity_update.xml index a5207e6..3b953e8 100644 --- a/app/src/main/res/layout/activity_update.xml +++ b/app/src/main/res/layout/activity_update.xml @@ -8,7 +8,7 @@ + type="com.xwad.os.bean.AppInfo" /> + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/eula_layout.xml b/app/src/main/res/layout/eula_layout.xml new file mode 100644 index 0000000..b415519 --- /dev/null +++ b/app/src/main/res/layout/eula_layout.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/license_layout.xml b/app/src/main/res/layout/license_layout.xml new file mode 100644 index 0000000..f461a2a --- /dev/null +++ b/app/src/main/res/layout/license_layout.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + +