version:1.2.5

fix:
update:优化退出桌面,增加通知权限检查,增加推送标签
This commit is contained in:
2026-03-09 17:52:18 +08:00
parent 516faa9e87
commit 7e2b3f5165
18 changed files with 429 additions and 83 deletions

View File

@@ -17,8 +17,8 @@ android {
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 29 targetSdkVersion 29
versionCode 24 versionCode 26
versionName "1.2.3" versionName "1.2.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -278,6 +278,7 @@
android:theme="@style/AppWhiteThemeWithoutFitsSystemWindows" /> android:theme="@style/AppWhiteThemeWithoutFitsSystemWindows" />
<activity <activity
android:name=".eula.LicenseActivity" android:name=".eula.LicenseActivity"
android:theme="@style/AppWhiteTheme"
android:exported="false" /> android:exported="false" />
<activity <activity
android:name=".activity.download.DownloadActivity" android:name=".activity.download.DownloadActivity"

View File

@@ -1,24 +1,149 @@
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html>
<!DOCTYPE html <html lang="zh-CN">
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="UTF-8">
<style type="text/css"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
p { <title>学王365-学习型平板电脑智慧教育软终端系统软件 (AI旗舰版) 用户使用协议</title>
margin-top: 0px;
}
.first_indent {}
</style>
</head> </head>
<body> <body>
<p></p> <div class="container">
<strong>您可以根据软件的具体业务场景声明您的免责协议,本协议与荣耀公司无关。</strong> <h1>学王365-学习型平板电脑智慧教育软终端系统软件 (AI旗舰版)</h1>
<h1>用户使用协议</h1>
<div class="update-info">
更新日期2025年12月31日<br>
生效日期2025年12月31日
</div>
<h2>前言</h2>
<div class="preface">
<p>感谢您使用推信科技 (深圳)
有限公司(以下简称“本公司”)提供的产品和/或服务。在完成注册并使用本公司产品和/或服务前,请您务必仔细阅读本协议,在确认充分理解后选择接受或不接受本协议条款。一旦您完成“同意并注册”,即表明您已阅读并同意受本协议条款的约束。如您不同意本协议条款约定,您应不再进行下一步或停止注册程序。</p>
<p>若您未满14周岁请务必在父母或法定监护人陪同下阅读本协议并在其同意后使用本服务。您使用本服务即视为您已获得监护人的授权。</p>
<p class="important">再次提示您审慎阅读、充分理解各条款内容,特别是限制或免除责任的相应条款,限制或免除责任条款会以加粗或其他醒目形式提示您注意。</p>
</div>
<h2>一、签约主体以及协议范围</h2>
<p>学王365-学习型平板电脑智慧教育软终端系统软件 (AI 旗舰版) (以下简称“本平台”)用户协议是您与推信科技 (深圳) 有限公司就使用学王365-学习型平板电脑智慧教育软终端系统软件
(AI 旗舰版)(以下简称“本服务”)而订立的有效合约。</p>
<p>本服务包含【学王365】App、【学王365】微信小程序。</p>
<h2>二、账户注册、使用与安全</h2>
<h3>(一)注册</h3>
<p>除本协议另有规定或相关产品另有规则外您通过本平台注册并取得本公司提供给您的学王365-学习型平板电脑智慧教育软终端系统软件 (AI
旗舰版)账户并且按照本公司要求提供相关信息完成激活后方可使用本服务。您需使用本人手机号码登录学王365-学习型平板电脑智慧教育软终端系统软件 (AI
旗舰版)账户。您可自行为该账户设置密码。</p>
<p>
您同意:按照本平台要求准确提供并及时更新您的身份信息及相关资料。若本公司有合理理由怀疑您提供的身份信息及相关资料错误、不实、过时或不完整的,本公司有权暂停或终止向您提供部分或全部服务。本公司对此不承担任何责任,您将承担因此产生的任何直接或间接损失。若因国家法律法规、部门规章或监管机构的要求,本公司需要您补充提供任何相关资料时,如您不能及时配合提供,本公司有权暂停或终止向您提供部分或全部服务。</p>
<h3>(二)使用</h3>
<ul>
<li>
1、您在使用本服务时应遵守中华人民共和国相关法律法规不得将本服务用于任何非法目的不得利用本服务从事侵害他人合法权益的行为否则本公司有权拒绝提供服务同时您应承担所有相关的法律责任。
</li>
<li>
2、您同意本公司有权基于单方合理判断对您的名下的账户暂停、中断或终止向您提供服务。本公司在发现您或有违反法律规定或本协议约定之情形时有权不经通知先行停用您名下的账户并且停止您使用本服务部分或全部功能并通过短信等方式通知您。
</li>
</ul>
<h3>(三)安全</h3>
<ul>
<li>1、 本公司通过您的手机号和密码识别您的指示,您应当妥善保管您的手机号和密码及身份信息,对于因密码泄露、身份信息泄露所致的损失,由您自行承担。</li>
<li>2、 您同意,如您发现有他人冒用或盗用您的平台账户、密码或任何其他违法情形,应立即以有效方式通知本公司,向本公司申请暂停相关服务,以保障您的合法权益</li>
<li>3、 您确认,只有您本人方可使用该账户。该账户不可转让、不可赠与、不可继承。</li>
<li>4、
您同意,基于运行安全的需要,本公司可以暂时停止向您提供或者限制本服务部分功能。在任何功能减少、增加或者变化时,只要您仍然使用本服务,表示您仍然同意本协议或者更新后的协议。
</li>
<li>5、 您同意,本公司有权根据国家法律或和行政法规,或根据有权机关的要求,对您的个人信息以及在本平台服务中的账户等进行查询、停用。</li>
</ul>
<h2>三、责任范围及责任限制</h2>
<ul>
<li>(一) 在适用法律许可的范围内,本公司不对与本服务有关或由本服务引起的任何间接的、惩罚性的、特殊的、派生的损失承担赔偿责任。</li>
<li>(二)
您在使用本服务期间应当遵守中华人民共和国的法律,不得危害网络安全,不得利用本服务从事侵犯他人名誉、隐私、知识产权和其他合法权益的活动,不得出现任何破坏或试图破坏网络安全等的行为,不会利用技术或其他手段破坏或扰乱本网站。本公司不对您使用本服务的违法或违约行为承担任何责任。
</li>
<li>(三) 您经由本服务下载或取得任何资料,应仅由您个人使用,不得传播、销售。因资料下载后传播、销售的行为导致您可能面临民事法律责任的,您应负完全责任。</li>
<li>(四) 您自本公司工作人员或经由本服务取得的任何建议和资讯,无论其为书面或口头形式,均不构成本公司的任何承诺、保证。</li>
<li>(五) 本服务如涉及合作单位或第三方公司,所提供服务的品质及内容由该合作单位或第三方公司自行负责。</li>
<li>(六) 本公司仅对本协议中列明的责任承担范围负责。除本协议另有规定外,在任何情况下,本公司因本协议所承担的违约赔偿责任总额不超过向您收取的当次服务费用总额。</li>
<li>(七) 如您违反上述保证,本公司有权根据相关服务条款采取删除信息、中止服务、终止服务的措施,并有权冻结或注销您账户的部分或全部功能。</li>
</ul>
<h2>四、隐私及个人信息保护</h2>
<ul>
<li>(一)
注册账号时本公司仅收集您的手机号以及提供学习服务所必需的信息如年级、学科等用于身份验证、账号登录及找回密码及提供相应服务。本公司遵循“最小、必要”原则不额外收集其他信息。若您的孩子未满14周岁本公司将通过弹窗等方式单独征得您的明示同意后方可处理其个人信息。手机号仅用于提供核心服务不会用于营销推送等其他用途未经您同意不向第三方共享。账号注销后本公司将在15个工作日内删除您的手机号或进行匿名化处理法律法规另有规定除外。您可通过APP设置或联系本公司查询、更正您的账号信息也可申请注销账号。
</li>
<li>(二) 本条款遵循《个人信息保护法》等法规,若条款更新,将通过页面公告、系统消息等方式通知您,继续使用服务即视为同意更新内容。</li>
<li>(三) 如您希望进一步了解我们如何收集、使用您的个人信息或如何保障您的隐私您可参见《学王365软终端-用户隐私政策》,请访问:<a
href="https://www.uiuios.com/agreement.html?section=2-2&projectId=10&status=1"
target="_blank">https://www.uiuios.com/agreement.html?section=2-2&projectId=10&status=1</a>
</li>
</ul>
<h2>五、知识产权</h2>
<ul>
<li>(一) 除非另行说明本公司Logo、文字、图形及其组合以及本公司网站的其他标识、徽记、服务的名称、技术文档等的知识产权均为本公司及其关联公司所有。</li>
<li>(二)
您不得攻击本公司网站,不得修改、改编、翻译本平台或本服务所使用的软件、技术、材料等,不得通过反向工程、反编译、反汇编或其他类似行为获得本平台或本服务涉及的源代码,否则由此引起的一切法律后果由您负责,本公司有权依法追究您的法律责任。
</li>
<li>(三)
您应尊重本公司和第三方的知识产权和其他合法权利/权益,并保证在发生侵犯前述权益的违法事件时,保护本公司及其雇员、股东、合作伙伴等免于因该等事件受到影响或损失,本公司保留在您侵犯本公司及/或其他第三方的合法权利/权益时终止向您提供服务并不退还任何款项的权利。
</li>
<li>(四) 本产品相关版权方包括深圳九学王信息科技有限公司、学王课堂 OS (数字教材版权合作分发平台)。本产品软件著作权权利人为推信科技 (深圳) 有限公司。</li>
</ul>
<h2>六、AI工具服务条款</h2>
<p>“AI 工具服务” 指本平台利用人工智能技术为用户提供个性化学习支持、交互式辅导等服务。AI
工具服务为平台基于现有技术能力提供的辅助性工具,其输出结果仅供用户参考,不构成本公司对结果准确性、适用性的保证,不构成专业教育建议。</p>
<h3>AI 工具使用规则与用户义务</h3>
<p>您保证输入AI工具的数据如文本、图像等不违反法律法规不侵犯第三方知识产权、隐私权等权益。若因用户数据违规导致本公司或第三方损失您需承担赔偿责任。</p>
<h3>(二)输出结果的使用限制</h3>
<p>您需自行判断AI工具输出结果的合理性并理解其可能存在错误或遗漏仅供参考不构成专业教育建议。您基于 AI
输出结果做出的任何判断或操作,相关后果均由您自行承担,本公司不承担责任。</p>
<h3>(三)生成内容标识</h3>
<p>您发布或传播生成内容时,应在显著位置标明 “由人工智能生成”,并不得删除、篡改平台对生成内容添加的隐式标识(如数字水印、元数据标签)。</p>
<h3>AI 工具的免责声明与责任限制</h3>
<ul>
<li>1、 技术局限性免责<br>
由于 AI 技术存在算法偏差、数据依赖、场景适配限制等固有缺陷,本平台不保证 AI 工具输出结果的绝对准确、完整。AI
工具输出结果仅供参考,不构成专业教育建议。若因技术局限性导致用户损失,本公司在已尽合理技术审核义务的前提下免除责任。
</li>
<li>2、 第三方数据与模型免责<br>
本产品使用第三方人工智能AI技术服务来为您提供智能问答、内容生成等功能。您的输入内容将被发送至合作的AI服务提供商【深圳九学王信息科技有限公司】用于生成回答。本公司已要求AI服务提供商不得留存或用于模型训练除非另行获得您的明确授权。本公司不对AI服务提供商内容的合法性、准确性负责相关风险由用户自行承担。
</li>
</ul>
<h2>七、保密</h2>
<p>本公司承诺对您注册账户时或使用本公司服务时提交的信息采取保密措施,不向第三方披露您的信息,除非:</p>
<ul>
<li>1、 依据本服务条款或者您与本公司之间其他服务协议或约定,可以提供的;</li>
<li>2、 依据法律法规或行政、司法机关要求应当提供的;</li>
<li>3、 在不违反本服务协议约定责任的前提下,该保密信息已经公开或能从公开领域获得的;</li>
<li>4、 为提供您要求的服务所必需的。</li>
</ul>
<h2>八、不可抗力和意外事件</h2>
<p>
本产品及服务是按照现有技术和条件所能达到的现状提供的,本公司会尽最大努力保障服务的连贯性和安全性,但不能随时预见和防范法律、技术以及其他风险,在法律允许的范围内,如因下列不可抗力或意外事件无法正常提供服务的,本公司不承担任何法律责任:</p>
<ul>
<li>1、
不可抗力,即双方所不能预见、并且它的发生及其后果是不能克服和不能避免的客观情况,包括但不限于如下情形:自然灾害如洪水、冰雹、海啸、台风、旱灾、火灾;社会因素如罢工、暴乱、战争;以及因政策、法律、法规导致不能履行的;
</li>
<li>2、 因电信部门、电力供应故障,或通讯网络故障等公共服务因素导致的;</li>
<li>3、 因黑客攻击、病毒、您自身软硬件设备异常等非本公司因素导致的;</li>
<li>4、 经提前公告或通知的,本公司在短时间内的系统维护(包括但不限于排除故障、系统升级、系统扩容、服务器迁移)。</li>
</ul>
<h2>十、法律适用与管辖</h2>
<p>
本协议之效力、解释、变更、执行与争议解决均适用中华人民共和国法律。因本协议产生的争议,双方同意提交深圳市仲裁委员会,按其届时有效的仲裁规则就全部争议事项进行仲裁,仲裁裁决为终局,对双方具有约束力。</p>
<h2>十一、条款的更新和终止</h2>
<p>
本公司有权对本协议条款及相应的服务规则内容进行变更,并以平台公告、系统消息、短信通知等方式予以公告或通知;若您在本服务条款内容变更后继续使用本服务的,表示您已充分阅读、理解并接受修改后的内容,也将遵循修改后的条款内容。</p>
<p>在您的账户注销或经双方协商一致终止服务的,本服务条款终止。</p>
<h2>十二、其他</h2>
<p>
您理解并同意,本公司可通过平台公告、电子邮件、短信、电话、系统消息等以上一种或多种通知方式向您发送通知,且本公司可以信赖您所提供的联系信息是完整、准确且当前有效的;上述通知在发送成功后视为已送达。</p>
<p>如果您对本政策有任何疑问、意见或建议,可通过以下方式与我们联系:</p>
<div class="contact-info">
<ul>
<li>1联系电话18682260825</li>
<li>2发送电子邮件至278359328@qq.com</li>
<li>3联系地址深圳市龙岗区坂田街道科尔达大厦C栋209联系人杨先生</li>
</ul>
<p>我们的客服部门将会同个人信息保护部门30天内进行回复并协助解决您的问题。</p>
<p>
如果您对我们的回复不满意,特别是我们的个人信息处理行为损害了您的合法权益,您还可以通过以下外部途径寻求解决方式:向推信科技(深圳)有限公司所在地人民法院提起诉讼,或向网信、工商、公安等监管部门进行投诉或举报。</p>
</div>
</div>
</body> </body>
</html> </html>

View File

@@ -7,7 +7,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.media.AudioAttributes; import android.media.AudioAttributes;
import android.media.SoundPool; import android.media.SoundPool;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.TextUtils; import android.text.TextUtils;
@@ -26,7 +25,6 @@ import com.xwad.os.base.BaseDataBindingActivity;
import com.xwad.os.config.CommonConfig; import com.xwad.os.config.CommonConfig;
import com.xwad.os.databinding.ActivityExitBinding; import com.xwad.os.databinding.ActivityExitBinding;
import com.xwad.os.mdm.AdminManager; import com.xwad.os.mdm.AdminManager;
import com.xwad.os.utils.ApkUtils;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
@@ -125,14 +123,14 @@ public class ExitActivity extends BaseDataBindingActivity {
if ((!TextUtils.isEmpty(content) && !TextUtils.isEmpty(password))) { if ((!TextUtils.isEmpty(content) && !TextUtils.isEmpty(password))) {
if (password.equals(content)) { if (password.equals(content)) {
// Utils.exitDesktop(this); // Utils.exitDesktop(this);
exitDesktop(); AdminManager.getInstance().exitDesktop(this);
} else { } else {
setEmpty(); setEmpty();
mBinding.tvHint.setText("密码错误"); mBinding.tvHint.setText("密码错误");
} }
} else if (CommonConfig.DEFAULT_PASSWORD.equals(content)) { } else if (CommonConfig.DEFAULT_PASSWORD.equals(content)) {
// Utils.exitDesktop(this); // Utils.exitDesktop(this);
exitDesktop(); AdminManager.getInstance().exitDesktop(this);
} else { } else {
setEmpty(); setEmpty();
mBinding.tvHint.setText("密码错误"); mBinding.tvHint.setText("密码错误");
@@ -166,37 +164,6 @@ public class ExitActivity extends BaseDataBindingActivity {
return launcherPackageList; return launcherPackageList;
} }
private void exitDesktop() {
// List<ComponentName> 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));
AdminManager.getInstance().removeDisallowedRunningApp("com.hihonor.android.launcher");
AdminManager.getInstance().clearDefaultLauncher();
AdminManager.getInstance().setDefaultLauncher("com.hihonor.android.launcher", "com.hihonor.android.launcher.unihome.UniHomeLauncher");
ApkUtils.openPackage(this, "com.hihonor.android.launcher", "com.hihonor.android.launcher.unihome.UniHomeLauncher");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
finishAndRemoveTask();
} else {
finishAffinity();
}
// AdminManager.getInstance().killApplicationProcess(BuildConfig.APPLICATION_ID);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
private void setEmpty() { private void setEmpty() {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override @Override

View File

@@ -7,6 +7,7 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.BatteryManager; import android.os.BatteryManager;
@@ -21,8 +22,11 @@ import android.view.animation.Animation;
import android.view.animation.TranslateAnimation; import android.view.animation.TranslateAnimation;
import android.widget.Toast; import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentPagerAdapter;
@@ -33,6 +37,7 @@ import androidx.viewpager.widget.ViewPager;
import com.blankj.utilcode.util.ServiceUtils; import com.blankj.utilcode.util.ServiceUtils;
import com.hihonor.android.app.admin.DeviceControlManager; import com.hihonor.android.app.admin.DeviceControlManager;
import com.hjq.permissions.OnPermissionCallback; import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions; import com.hjq.permissions.XXPermissions;
import com.hjq.toast.Toaster; import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV; import com.tencent.mmkv.MMKV;
@@ -144,6 +149,21 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
private TabAdapter tabAdapter; private TabAdapter tabAdapter;
private static final int REQUEST_CODE_POST_NOTIFICATIONS = 100;
// 使用新的Activity Result API推荐
private ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(),
isGranted -> {
if (isGranted) {
// 权限已授予,可以发送通知
sendNotification();
} else {
// 权限被拒绝,向用户解释必要性或提供备选方案
// showPermissionDeniedMessage();
}
});
@Override @Override
public int getLayoutId() { public int getLayoutId() {
return R.layout.activity_home; return R.layout.activity_home;
@@ -891,17 +911,45 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
showPolicyDialog(); showPolicyDialog();
} else { } else {
checkEula(); checkEula();
if (!ServiceUtils.isServiceRunning(MainService.class)) { checkAndRequestNotificationPermission();
startService(new Intent(HomeActivity.this, MainService.class));
}
if (!ServiceUtils.isServiceRunning(SocketService.class)) {
startService(new Intent(HomeActivity.this, SocketService.class));
}
}
}
setDefaultDesktop(); setDefaultDesktop();
} }
private void checkAndRequestNotificationPermission() {
// Android 13API 33/TIRAMISU及以上版本需要动态申请
if (Build.VERSION.SDK_INT >= 33) {
if (ContextCompat.checkSelfPermission(this,
Permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
// 使用新的API请求权限
requestPermissionLauncher.launch(Permission.POST_NOTIFICATIONS);
// 或者使用传统方式(兼容旧代码)
// ActivityCompat.requestPermissions(this,
// new String[]{Manifest.permission.POST_NOTIFICATIONS},
// REQUEST_CODE_POST_NOTIFICATIONS);
} else {
// 权限已授予,直接发送通知
sendNotification();
}
} else {
// Android 12及以下版本无需动态申请通知权限
sendNotification();
}
}
private void sendNotification() {
if (!ServiceUtils.isServiceRunning(MainService.class)) {
startService(new Intent(HomeActivity.this, MainService.class));
}
if (!ServiceUtils.isServiceRunning(SocketService.class)) {
startService(new Intent(HomeActivity.this, SocketService.class));
}
}
@Override @Override
protected void onRestart() { protected void onRestart() {
super.onRestart(); super.onRestart();

View File

@@ -142,8 +142,8 @@ public class HomeViewModel extends BaseViewModel<ActivityHomeBinding, ActivityEv
public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) { public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) {
Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse);
if (appUpdateInfoBaseResponse.code == 200) { if (appUpdateInfoBaseResponse.code == 200) {
AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; AppInfo appInfo = appUpdateInfoBaseResponse.data;
mAppUpdateInfoData.setValue(appUpdateInfo); mAppUpdateInfoData.setValue(appInfo);
} else { } else {
mAppUpdateInfoData.setValue(null); mAppUpdateInfoData.setValue(null);
} }

View File

@@ -136,8 +136,8 @@ public class MainViewModel extends BaseViewModel<ActivityMainBinding, ActivityEv
public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) { public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) {
Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse);
if (appUpdateInfoBaseResponse.code == 200) { if (appUpdateInfoBaseResponse.code == 200) {
AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; AppInfo appInfo = appUpdateInfoBaseResponse.data;
mAppUpdateInfoData.setValue(appUpdateInfo); mAppUpdateInfoData.setValue(appInfo);
} else { } else {
mAppUpdateInfoData.setValue(null); mAppUpdateInfoData.setValue(null);
} }

View File

@@ -46,6 +46,13 @@ public class UpdateActivity extends BaseMvvmActivity<UpdateViewModel, ActivityUp
mViewDataBinding.setMsg("检测到新版本,是否更新"); mViewDataBinding.setMsg("检测到新版本,是否更新");
} }
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
mAppInfoData = (AppInfo) intent.getSerializableExtra("appUpdateInfo");
mViewDataBinding.setAppUpdateInfo(mAppInfoData);
mViewDataBinding.setMsg("检测到新版本,是否更新");
}
public class BtnClick { public class BtnClick {
public void empty(View view) { public void empty(View view) {

View File

@@ -83,8 +83,8 @@ public class UserViewModel extends BaseViewModel<ActivityUserBinding, ActivityEv
public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) { public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) {
Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse);
if (appUpdateInfoBaseResponse.code == 200) { if (appUpdateInfoBaseResponse.code == 200) {
AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; AppInfo appInfo = appUpdateInfoBaseResponse.data;
mAppUpdateInfoData.setValue(appUpdateInfo); mAppUpdateInfoData.setValue(appInfo);
} else { } else {
mAppUpdateInfoData.setValue(null); mAppUpdateInfoData.setValue(null);
} }

View File

@@ -36,6 +36,11 @@ import com.xwad.os.utils.JgyUtils;
import com.xwad.os.utils.OpenApkUtils; import com.xwad.os.utils.OpenApkUtils;
import com.xwad.os.utils.SystemUtils; import com.xwad.os.utils.SystemUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class BaseApplication extends Application { public class BaseApplication extends Application {
private static final String TAG = "BaseApplication"; private static final String TAG = "BaseApplication";
@@ -166,6 +171,22 @@ public class BaseApplication extends Application {
} else { } else {
Log.e(TAG, "onSuccess: admin not Activation"); Log.e(TAG, "onSuccess: admin not Activation");
} }
Set<String> tagSets = new HashSet<>();
tagSets.add(BuildConfig.platform);
String[] tag = new ArrayList<>(tagSets).toArray(new String[tagSets.size()]);
pushService.bindTag(CloudPushService.DEVICE_TARGET, tag, null, new CommonCallback() {
@Override
public void onSuccess(String s) {
Log.e("AliyunPush", "bind tag " + Arrays.toString(tag) + " success\n");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
Log.e("AliyunPush", "bind tag " + Arrays.toString(tag) + " failed." +
"errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
} }
@Override @Override

View File

@@ -30,7 +30,7 @@ public class LicenseActivity extends Activity {
Button acceptBtn = findViewById(R.id.cancelBtn); Button acceptBtn = findViewById(R.id.cancelBtn);
acceptBtn.setOnClickListener(view -> finish()); acceptBtn.setOnClickListener(view -> finish());
TextView licenseText = findViewById(R.id.license_content); TextView licenseText = findViewById(R.id.license_content);
String content = Utils.getStringFromHtmlFile(this, LICENSE_FILE); String content = Utils.readAssetsFileToString(this, LICENSE_FILE);
licenseText.setText(Html.fromHtml(content)); licenseText.setText(Html.fromHtml(content));
} }
} }

View File

@@ -9,6 +9,7 @@ import android.util.Log;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
/** /**
@@ -62,4 +63,46 @@ public class Utils {
} }
return result; return result;
} }
public static String readAssetsFileToString(Context context, String fileName) {
// 用于拼接读取的内容
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
// 1. 获取AssetManager并打开文件输入流
inputStream = context.getAssets().open(fileName);
// 2. 创建BufferedReader读取内容指定UTF-8编码避免中文乱码
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line;
// 3. 逐行读取并拼接
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
// 保留换行符(如果不需要换行符可删除此行)
stringBuilder.append("\n");
}
} catch (IOException e) {
// 捕获IO异常并打印日志
Log.e(TAG, "读取Assets文件失败: " + fileName, e);
return null;
} finally {
// 4. 关闭流资源,避免内存泄漏
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
Log.e(TAG, "关闭流失败", e);
}
}
// 返回读取到的字符串
return stringBuilder.toString();
}
} }

View File

@@ -28,6 +28,7 @@ import com.xwad.os.databinding.FragmentMineBinding;
import com.xwad.os.jxw.StudyRecordMng; import com.xwad.os.jxw.StudyRecordMng;
import com.xwad.os.jxw.ToastUtil; import com.xwad.os.jxw.ToastUtil;
import com.xwad.os.jxw.event.UpdateColorEvent; import com.xwad.os.jxw.event.UpdateColorEvent;
import com.xwad.os.mdm.AdminManager;
import com.xwad.os.utils.ActivationUtil; import com.xwad.os.utils.ActivationUtil;
import com.xwad.os.utils.OpenApkUtils; import com.xwad.os.utils.OpenApkUtils;
import com.xwad.os.view.jxw.view.dialog.QhbzDialog; import com.xwad.os.view.jxw.view.dialog.QhbzDialog;
@@ -389,12 +390,17 @@ public class MineFragment extends BaseMvvmFragment<MineViewModel, FragmentMineBi
} }
public void exit(View view) { public void exit(View view) {
int toAndroid = mMMKV.decodeInt(CommonConfig.UIUI_RETURN_ANDROID_KEY, 0); if (ActivationUtil.getInstance().isLogin()) {
if (toAndroid == 1) { int toAndroid = mMMKV.decodeInt(CommonConfig.UIUI_RETURN_ANDROID_KEY, 0);
startActivity(new Intent(mContext, ExitActivity.class)); if (toAndroid == 1) {
startActivity(new Intent(mContext, ExitActivity.class));
} else {
Toaster.show("小程序已设置禁止退出");
}
} else { } else {
Toaster.show("小程序已设置禁止退出"); AdminManager.getInstance().exitDesktop(mContext);
} }
// OpenApkUtils.getInstance().openJxwApp(mContext, "com.hihonor.android.launcher,com.hihonor.android.launcher.unihome.UniHomeLauncher,,,退出桌面"); // OpenApkUtils.getInstance().openJxwApp(mContext, "com.hihonor.android.launcher,com.hihonor.android.launcher.unihome.UniHomeLauncher,,,退出桌面");
} }

View File

@@ -44,8 +44,8 @@ public class DeviceViewModel extends BaseViewModel<FragmentDeviceBinding, Fragme
public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) { public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) {
Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse);
if (appUpdateInfoBaseResponse.code == 200) { if (appUpdateInfoBaseResponse.code == 200) {
AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; AppInfo appInfo = appUpdateInfoBaseResponse.data;
mAppUpdateInfoData.setValue(appUpdateInfo); mAppUpdateInfoData.setValue(appInfo);
} else { } else {
mAppUpdateInfoData.setValue(null); mAppUpdateInfoData.setValue(null);
} }
@@ -77,9 +77,9 @@ public class DeviceViewModel extends BaseViewModel<FragmentDeviceBinding, Fragme
public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) { public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) {
Log.e("checkStoreUpdate", "onNext: " + appUpdateInfoBaseResponse); Log.e("checkStoreUpdate", "onNext: " + appUpdateInfoBaseResponse);
if (appUpdateInfoBaseResponse.code == 200) { if (appUpdateInfoBaseResponse.code == 200) {
AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; AppInfo appInfo = appUpdateInfoBaseResponse.data;
if (ApkUtils.isUpdate(getCtx(), appUpdateInfo)) { if (ApkUtils.isUpdate(getCtx(), appInfo)) {
ApkUtils.checkAppUpdate(getCtx(), appUpdateInfo); ApkUtils.checkAppUpdate(getCtx(), appInfo);
// Toaster.show("有新的版本需要更新"); // Toaster.show("有新的版本需要更新");
} }
} }

View File

@@ -1,6 +1,7 @@
package com.xwad.os.mdm; package com.xwad.os.mdm;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
@@ -2149,4 +2150,39 @@ public class AdminManager {
} }
return false; return false;
} }
public void exitDesktop(Activity activity) {
// List<ComponentName> 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));
removePersistentApp(BuildConfig.APPLICATION_ID);
removeDisallowedRunningApp("com.hihonor.android.launcher");
clearDefaultLauncher();
setDefaultLauncher("com.hihonor.android.launcher", "com.hihonor.android.launcher.unihome.UniHomeLauncher");
ApkUtils.openPackage(activity, "com.hihonor.android.launcher", "com.hihonor.android.launcher.unihome.UniHomeLauncher");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.finishAndRemoveTask();
} else {
activity.finishAffinity();
}
// killApplicationProcess(BuildConfig.APPLICATION_ID);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
} }

View File

@@ -12,6 +12,8 @@ import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV; import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent; import com.trello.rxlifecycle4.android.ActivityEvent;
import com.xwad.os.BuildConfig;
import com.xwad.os.activity.update.UpdateActivity;
import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.AppInfo;
import com.xwad.os.bean.BaseResponse; import com.xwad.os.bean.BaseResponse;
import com.xwad.os.bean.UserInfo; import com.xwad.os.bean.UserInfo;
@@ -284,7 +286,42 @@ public class MainSPresenter implements MainSContact.Presenter {
@Override @Override
public void checkUpdate() { public void checkUpdate() {
NetInterfaceManager.getInstance().getUpdateObservable(BuildConfig.APPLICATION_ID)
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse<AppInfo>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("checkUpdate", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<AppInfo> appUpdateInfoBaseResponse) {
Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse);
if (appUpdateInfoBaseResponse.code == 200) {
AppInfo appInfo = appUpdateInfoBaseResponse.data;
if (ApkUtils.isUpdate(mContext, appInfo)) {
Intent intent = new Intent(mContext, UpdateActivity.class);
intent.putExtra("appUpdateInfo", appInfo);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
Toaster.show("有新的版本需要更新");
}
} else {
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("checkUpdate", "onError: " + e.getMessage());
// Toaster.show("网络连接失败");
}
@Override
public void onComplete() {
Log.e("checkUpdate", "onComplete: ");
}
});
} }
@Override @Override

View File

@@ -30,10 +30,18 @@ import com.xwad.os.bean.SnInfo;
import com.xwad.os.config.CommonConfig; import com.xwad.os.config.CommonConfig;
import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.network.NetInterfaceManager;
import com.xwad.os.service.SocketService; import com.xwad.os.service.SocketService;
import com.xwad.os.utils.Utils;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
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;
public class MainService extends BaseRxService implements MainSContact.MainSView, NetworkUtils.OnNetworkStatusChangedListener { public class MainService extends BaseRxService implements MainSContact.MainSView, NetworkUtils.OnNetworkStatusChangedListener {
private static final String TAG = "MainService"; private static final String TAG = "MainService";
@@ -54,11 +62,54 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
@Override @Override
public void onConnected(NetworkUtils.NetworkType networkType) { public void onConnected(NetworkUtils.NetworkType networkType) {
Log.e(TAG, "onConnected: "); Log.e(TAG, "onConnected: ");
// if (Utils.isScreenOn(MainService.this)) { if (Utils.isScreenOn(MainService.this)) {
// mPresenter.getCloudLessonSettings(); mPresenter.checkUpdate();
// } }
mInternetConnected.onConnected(networkType.name());
} }
private InternetConnected mInternetConnected;
public interface InternetConnected {
void onConnected(String alias);
}
private final ObservableOnSubscribe<String> networkSubscribe = new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
mInternetConnected = new InternetConnected() {
@Override
public void onConnected(String alias) {
Log.e(TAG, "networkSubscribe: onConnected " + alias);
emitter.onNext(alias);
}
};
}
};
private Observer<String> networkObserver = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("networkObserver", "onSubscribe: ");
}
@Override
public void onNext(String action) {
Log.e("networkObserver", "onNext: " + action);
getSystemSettings();
}
@Override
public void onError(Throwable e) {
Log.e("networkObserver", "onError: " + e.getMessage());
}
@Override
public void onComplete() {
Log.e("networkObserver", "onComplete: ");
}
};
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
Log.e(TAG, "onBind: "); Log.e(TAG, "onBind: ");
@@ -88,7 +139,11 @@ public class MainService extends BaseRxService implements MainSContact.MainSView
Log.e(TAG, "setDefault: startServices time = " + (System.currentTimeMillis() - time) + "ms"); Log.e(TAG, "setDefault: startServices time = " + (System.currentTimeMillis() - time) + "ms");
getSystemSettings(); getSystemSettings();
mPresenter.checkUpdate();
Observable.create(networkSubscribe)
.throttleFirst(1, TimeUnit.HOURS)
.subscribe(networkObserver);
} }
private void getSystemSettings() { private void getSystemSettings() {

View File

@@ -476,7 +476,7 @@ public class JgyUtils {
Log.i(TAG, "checkAppPlatform: " + "honer"); Log.i(TAG, "checkAppPlatform: " + "honer");
return HONOR_PLATFORM; return HONOR_PLATFORM;
} else if (LENOVO_TAG.equalsIgnoreCase(platform)) { } else if (LENOVO_TAG.equalsIgnoreCase(platform)) {
Log.i(TAG, "checkAppPlatform: " + "6gen1s"); Log.i(TAG, "checkAppPlatform: " + "lenovo");
return LENOVO_PLATFORM; return LENOVO_PLATFORM;
} else { } else {
Log.i(TAG, "checkAppPlatform: " + "没有数据"); Log.i(TAG, "checkAppPlatform: " + "没有数据");