diff --git a/app/build.gradle b/app/build.gradle index 9cc2ed0..9b1b2f2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,11 +13,12 @@ android { defaultConfig { applicationId "com.xwad.os" + //There are no CERT files because If the mini sdk version is 23+, the AGP will ignore the V1 scheme signature. minSdkVersion 23 targetSdkVersion 29 - versionCode 25 - versionName "1.2.4" + versionCode 26 + versionName "1.2.5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d930a6a..5364d95 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,9 +39,12 @@ - + + + + @@ -123,12 +126,12 @@ android:enabled="true" android:excludeFromRecents="true" android:exported="true" - android:launchMode="singleTask" + android:launchMode="singleTop" android:resizeableActivity="true" android:resumeWhilePausing="true" android:screenOrientation="landscape" android:stateNotNeeded="true" - android:theme="@style/AppThemeWithoutFitsSystemWindows" + android:theme="@style/HomeThemeWithoutFitsSystemWindows" android:windowSoftInputMode="adjustPan"> @@ -242,6 +245,14 @@ android:launchMode="singleTask" android:screenOrientation="landscape" android:theme="@style/AppWhiteTheme" /> + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ 本软件在使用过程中,为了更好的提供客户服务,基于技术必要性将会使用到如下的权限和功能: +
+
设备管理功能: +
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..a18dc9d 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; @@ -18,6 +19,7 @@ import android.view.inputmethod.InputMethodManager; import androidx.databinding.DataBindingUtil; +import com.tencent.mmkv.MMKV; import com.tuo.customview.VerificationCodeView; import com.xwad.os.BuildConfig; import com.xwad.os.R; @@ -34,6 +36,8 @@ import java.util.stream.Collectors; public class ExitActivity extends BaseDataBindingActivity { private static final String TAG = "ExitActivity"; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + private ActivityExitBinding mBinding; private SoundPool soundPool; @@ -117,7 +121,7 @@ public class ExitActivity extends BaseDataBindingActivity { return; } Log.e(TAG, "inputComplete: " + content); - String password = Settings.Global.getString(getContentResolver(), CommonConfig.LOCK_SCREEN_PASSWORD); + String password = mMMKV.decodeString(CommonConfig.LOCK_SCREEN_PASSWORD, CommonConfig.DEFAULT_PASSWORD); if ((!TextUtils.isEmpty(content) && !TextUtils.isEmpty(password))) { if (password.equals(content)) { // Utils.exitDesktop(this); @@ -188,7 +192,7 @@ public class ExitActivity 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/NoticeActivity.java b/app/src/main/java/com/xwad/os/activity/NoticeActivity.java index 4e9d964..a9bab22 100644 --- a/app/src/main/java/com/xwad/os/activity/NoticeActivity.java +++ b/app/src/main/java/com/xwad/os/activity/NoticeActivity.java @@ -12,7 +12,6 @@ import android.view.View; import androidx.databinding.DataBindingUtil; -import com.blankj.utilcode.util.FileUtils; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; @@ -23,7 +22,7 @@ import com.xwad.os.bean.AlarmClockData; import com.xwad.os.bean.BaseResponse; import com.xwad.os.databinding.ActivityNoticeBinding; import com.xwad.os.network.NetInterfaceManager; -import com.xwad.os.utils.FileUtil; +import com.xwad.os.utils.FileUtils; import com.xwad.os.utils.ScreenUtils; import com.xwad.os.utils.Utils; import com.xwad.os.utils.WakeUpUtils; @@ -139,7 +138,7 @@ public class NoticeActivity extends BaseDataBindingActivity { mBinding.clVoice.setVisibility(View.VISIBLE); String fileName = Utils.getFileNamefromURL(voiceUrl); File file = new File(Utils.getDownLoadPath(NoticeActivity.this) + fileName); - String fileMD5 = FileUtils.getFileMD5ToString(file); + String fileMD5 = com.blankj.utilcode.util.FileUtils.getFileMD5ToString(file); // if (!md5.equals(fileMD5)) { // // TODO: 2021/12/16 // } else { @@ -165,14 +164,14 @@ public class NoticeActivity extends BaseDataBindingActivity { } if (!TextUtils.isEmpty(filePath)) { mBinding.clVp.setVisibility(View.VISIBLE); - String fileType = FileUtil.getFileType(filePath); + String fileType = FileUtils.getFileType(filePath); Log.e(TAG, "showData: " + fileType); - if (FileUtil.isPictureFile(fileType)) { + if (FileUtils.isPictureFile(fileType)) { mBinding.jzVideo.setVisibility(View.GONE); mBinding.ivDictation.setVisibility(View.VISIBLE); RequestOptions options = new RequestOptions().transform(new RoundedCorners(ScreenUtils.dip2px(this, 16F))); Glide.with(NoticeActivity.this).load(filePath).apply(options).into(mBinding.ivDictation); - } else if (FileUtil.isVideoFile(fileType)) { + } else if (FileUtils.isVideoFile(fileType)) { mBinding.jzVideo.setVisibility(View.VISIBLE); mBinding.ivDictation.setVisibility(View.GONE); String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length()); 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..11d7749 100644 --- a/app/src/main/java/com/xwad/os/activity/PasswordActivity.java +++ b/app/src/main/java/com/xwad/os/activity/PasswordActivity.java @@ -4,7 +4,7 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Handler; -import android.provider.Settings; +import android.os.Looper; import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -13,6 +13,7 @@ import android.view.inputmethod.InputMethodManager; import androidx.databinding.DataBindingUtil; +import com.tencent.mmkv.MMKV; import com.tuo.customview.VerificationCodeView; import com.xwad.os.R; import com.xwad.os.activity.addicon.AddIconActivity; @@ -24,6 +25,8 @@ import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX; public class PasswordActivity extends BaseDataBindingActivity { private static final String TAG = "PasswordActivity"; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + private ActivityPasswdBinding mBinding; // @Override @@ -133,7 +136,7 @@ public class PasswordActivity extends BaseDataBindingActivity { return; } Log.e(TAG, "inputComplete: " + content); - String password = Settings.Global.getString(getContentResolver(), CommonConfig.LOCK_SCREEN_PASSWORD); + String password = mMMKV.decodeString(CommonConfig.LOCK_SCREEN_PASSWORD, CommonConfig.DEFAULT_PASSWORD); if ((!TextUtils.isEmpty(content) && !TextUtils.isEmpty(password))) { if (password.equals(content)) { startActivity(new Intent(PasswordActivity.this, AddIconActivity.class)); @@ -155,7 +158,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..f09c3be --- /dev/null +++ b/app/src/main/java/com/xwad/os/activity/debug/DebugActivity.java @@ -0,0 +1,156 @@ +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.xwad.os.R; +import com.xwad.os.base.mvvm.BaseMvvmActivity; +import com.xwad.os.databinding.ActivityDebugBinding; +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 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); + mAdminName = new ComponentName(this, AoleDeviceAdminReceiver.class); + + mViewDataBinding.swWindow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swYoyo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swRestore.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swUsbDebug.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swRemoveAdmin.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swExpandPanel.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swQuickTools.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swPowerOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + mViewDataBinding.swMultiWindow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + + } + }); + } + + @Override + protected void initData() { + + } + + @Override + protected void onResume() { + super.onResume(); + getAdminStatus(); + } + + private void getAdminStatus() { + if (isActiveMe()) { + mViewDataBinding.tvAdmin.setText("已激活"); + } 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/home/HomeActivity.java b/app/src/main/java/com/xwad/os/activity/home/HomeActivity.java index 7c136ee..87eb5dc 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 @@ -39,9 +39,11 @@ 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.AppUpdateInfo; +import com.xwad.os.bean.AppInfo; +import com.xwad.os.bean.PhraseContent; import com.xwad.os.bean.UserInfo; import com.xwad.os.bean.jxw.TabBean; +import com.xwad.os.bean.uiuios.AppUpdateInfo; import com.xwad.os.config.CommonConfig; import com.xwad.os.databinding.ActivityHomeBinding; import com.xwad.os.dialog.PermissionsDialog; @@ -62,8 +64,10 @@ import com.xwad.os.jxw.event.UpdateColorEvent; import com.xwad.os.jxw.event.UpdateGradeEvent; import com.xwad.os.jxw.fragment.SztzFragment; import com.xwad.os.jxw.util.Util; +import com.xwad.os.manager.AmapManager; import com.xwad.os.manager.DeviceSNManager; import com.xwad.os.manager.RemoteManager; +import com.xwad.os.permission.PermissionUtils; import com.xwad.os.service.main.MainService; import com.xwad.os.utils.ActivationUtil; import com.xwad.os.utils.ApkUtils; @@ -125,9 +129,11 @@ public class HomeActivity extends BaseMvvmActivity() { + @Override + public void onChanged(AppUpdateInfo appUpdateInfo) { + if (appUpdateInfo == null) { +// Toaster.show("已是最新版本"); + } else { + if (ApkUtils.isUpdate(HomeActivity.this, appUpdateInfo)) { + ApkUtils.checkAppUpdate(HomeActivity.this, appUpdateInfo); +// Toaster.show("有新的版本需要更新"); + } else { +// Toaster.show("已是最新版本"); + } + } + } + }); +// mViewModel.checkUpdateUiUiOS(BuildConfig.APPLICATION_ID); + mViewModel.checkUpdateUiUiOS("com.xwad.store"); + + mViewModel.mGetCodeData.observe(this, new Observer() { @Override public void onChanged(Boolean aBoolean) { @@ -248,13 +273,73 @@ 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(); initDatas(); } + private void getPermission() { + Log.e(TAG, "getPermission: "); + if (XXPermissions.isGranted(HomeActivity.this, PermissionUtils.PERMISSIONS)) { + 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 { + Log.e(TAG, "onGranted: " + "获取权限成功"); + } + } + + @Override + public void onDenied(List permissions, boolean never) { + if (never) { + Toaster.show("被永久拒绝授权,请手动授予权限"); + // 如果是被永久拒绝就跳转到应用权限系统设置页面 + XXPermissions.startPermissionActivity(HomeActivity.this, permissions); + } else { + Toaster.show("获取权限失败"); + } + } + }); + } + } + + + + + public void exit() { + finish(); + //调用系统API结束进程 + android.os.Process.killProcess(android.os.Process.myPid()); + + //结束整个虚拟机进程,注意如果在manifest里用android:process给app指定了不止一个进程,则只会结束当前进程 + System.exit(0); + } + @Subscribe(threadMode = ThreadMode.MAIN) public void onGkNoticeEvent(UpdateGradeEvent updateGradeEvent) { Log.e(TAG, "onGkNoticeEvent: "); @@ -359,11 +444,12 @@ public class HomeActivity extends BaseMvvmActivity>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -130,22 +132,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); @@ -165,6 +167,41 @@ public class HomeViewModel extends BaseViewModel mAppUpdateInfoUiUiOSData = new MutableLiveData<>(); + + public void checkUpdateUiUiOS(String pkg) { + NetInterfaceManager.getInstance().getCheckUpdateObservable(pkg) + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("checkUpdateUiUiOS", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { + Log.e("checkUpdateUiUiOS", "onNext: " + appUpdateInfoBaseResponse); + if (appUpdateInfoBaseResponse.code == 200) { + AppUpdateInfo appUpdateInfo = appUpdateInfoBaseResponse.data; + mAppUpdateInfoUiUiOSData.setValue(appUpdateInfo); + } else { + mAppUpdateInfoUiUiOSData.setValue(null); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("checkUpdateUiUiOS", "onError: "); + Toaster.show("网络连接失败"); + } + + @Override + public void onComplete() { + Log.e("checkUpdateUiUiOS", "onComplete: "); + } + }); + } + @Deprecated public void sendAPPUsage() { boolean activation = ActivationUtil.getInstance().isLogin(); @@ -313,6 +350,7 @@ public class HomeViewModel extends BaseViewModel() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -361,4 +399,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/LoginActivity.java b/app/src/main/java/com/xwad/os/activity/login/LoginActivity.java index e65ee18..a700c33 100644 --- a/app/src/main/java/com/xwad/os/activity/login/LoginActivity.java +++ b/app/src/main/java/com/xwad/os/activity/login/LoginActivity.java @@ -17,6 +17,7 @@ import com.xwad.os.base.mvvm.BaseMvvmActivity; import com.xwad.os.bean.LoginInfo; import com.xwad.os.databinding.ActivityLoginBinding; import com.xwad.os.service.SocketService; +import com.xwad.os.service.main.MainService; import java.util.concurrent.TimeUnit; @@ -56,6 +57,7 @@ public class LoginActivity extends BaseMvvmActivity { @@ -30,13 +33,18 @@ public class LoginSuccessfulActivity extends BaseMvvmActivity() { + @Override + public void onChanged(Boolean aBoolean) { + Utils.triggerRebirth(LoginSuccessfulActivity.this); + } + }); } @Override protected void onDestroy() { super.onDestroy(); - startHome(); +// startHome(); } private void startHome() { @@ -49,7 +57,7 @@ public class LoginSuccessfulActivity extends BaseMvvmActivity { @Override public void onDestroy() { } + + public MutableLiveData mBooleanMutableLiveData = new MutableLiveData<>(); + + public void getAppInfo() { + Observable.zip(NetInterfaceManager.getInstance().getAdminAppObservable(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME), + NetInterfaceManager.getInstance().getAdminAppObservable("com.jxw.download"), + NetInterfaceManager.getInstance().getAdminAppObservable("com.study.flashplayer"), + new Function3, BaseResponse, BaseResponse, List>() { + @Override + public List apply(BaseResponse baseResponse, BaseResponse baseResponse2, BaseResponse baseResponse3) throws Throwable { + List appInfos = new ArrayList<>(); + if (baseResponse.code == 200) { + if (!ApkUtils.isAvailable(getCtx(), JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME)) { + appInfos.add(baseResponse.data); + } + } + if (baseResponse2.code == 200) { + if (!ApkUtils.isAvailable(getCtx(), "com.jxw.download")) { + appInfos.add(baseResponse2.data); + } + } + if (baseResponse3.code == 200) { + if (!ApkUtils.isAvailable(getCtx(), "com.study.flashplayer")) { + appInfos.add(baseResponse3.data); + } + } + return appInfos; + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAppInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull List appInfos) { + Log.e("getAppInfo", "onNext: " + appInfos); + appInfos.forEach(new Consumer() { + @Override + public void accept(AppInfo appInfo) { + FileUtils.ariaDownload(getCtx(), appInfo.getApp_url(), appInfo); + } + }); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAppInfo", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAppInfo", "onComplete: "); + mBooleanMutableLiveData.setValue(true); + } + }); + + } + } diff --git a/app/src/main/java/com/xwad/os/activity/main/MainActivity.java b/app/src/main/java/com/xwad/os/activity/main/MainActivity.java index ded6427..8a440b3 100644 --- a/app/src/main/java/com/xwad/os/activity/main/MainActivity.java +++ b/app/src/main/java/com/xwad/os/activity/main/MainActivity.java @@ -205,6 +205,8 @@ public class MainActivity 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); diff --git a/app/src/main/java/com/xwad/os/activity/privacy/PrivacyActivity.java b/app/src/main/java/com/xwad/os/activity/privacy/PrivacyActivity.java index 4b49285..cf98d29 100644 --- a/app/src/main/java/com/xwad/os/activity/privacy/PrivacyActivity.java +++ b/app/src/main/java/com/xwad/os/activity/privacy/PrivacyActivity.java @@ -69,11 +69,11 @@ public class PrivacyActivity extends BaseMvvmActivity { - private AppUpdateInfo mAppInfoData; + private AppInfo mAppInfoData; @Override @@ -42,14 +41,14 @@ public class UpdateActivity extends BaseMvvmActivity= Build.VERSION_CODES.O) { - startForegroundService(intent); - } else { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { +// startForegroundService(intent); +// } else { startService(intent); - } +// } if (mAppInfoData != null) { DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(mAppInfoData.getApp_url()); if (null != entity) { if (entity.isComplete()) { - ApkUtils.installApkFile(UpdateActivity.this, entity.getFilePath()); + ApkUtils.installApp(UpdateActivity.this, entity.getFilePath()); } else { if (entity.getState() == STATE_RUNNING) { Toaster.show("文件正在下载中"); diff --git a/app/src/main/java/com/xwad/os/activity/user/UserActivity.java b/app/src/main/java/com/xwad/os/activity/user/UserActivity.java index 502bb71..35f5d85 100644 --- a/app/src/main/java/com/xwad/os/activity/user/UserActivity.java +++ b/app/src/main/java/com/xwad/os/activity/user/UserActivity.java @@ -2,9 +2,13 @@ package com.xwad.os.activity.user; import android.content.Intent; import android.net.Uri; +import android.os.SystemClock; import android.text.TextUtils; import android.util.Log; +import android.view.Gravity; import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; import android.widget.CompoundButton; import androidx.fragment.app.Fragment; @@ -20,35 +24,37 @@ import com.luck.picture.lib.interfaces.OnResultCallbackListener; import com.tencent.mmkv.MMKV; import com.xwad.os.BuildConfig; import com.xwad.os.R; -import com.xwad.os.activity.ExitActivity; +import com.xwad.os.activity.debug.DebugActivity; import com.xwad.os.activity.edit.EditActivity; 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.BaseAlertDialogBuilder; import com.xwad.os.base.mvvm.BaseMvvmActivity; -import com.xwad.os.bean.AppUpdateInfo; +import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.UserAvatarInfo; import com.xwad.os.config.CommonConfig; import com.xwad.os.custom.GlideEngine; import com.xwad.os.databinding.ActivityUserBinding; +import com.xwad.os.dialog.UserDebugDialog; import com.xwad.os.fragment.usercenter.account.AccountFragment; import com.xwad.os.fragment.usercenter.device.DeviceFragment; import com.xwad.os.fragment.usercenter.info.InfoFragment; import com.xwad.os.fragment.usercenter.parents.ParentsFragment; import com.xwad.os.manager.DeviceSNManager; -import com.xwad.os.manager.RemoteManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.utils.ActivationUtil; import com.xwad.os.utils.ApkUtils; -import com.xwad.os.utils.FileUtil; +import com.xwad.os.utils.FileUtils; import com.xwad.os.utils.GlideLoadUtils; -import com.xwad.os.utils.Utils; +import com.xwad.os.utils.ScreenUtils; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import me.jessyan.autosize.AutoSizeCompat; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; @@ -155,9 +161,9 @@ public class UserActivity 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 { @@ -181,11 +187,7 @@ 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); @@ -276,10 +346,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); diff --git a/app/src/main/java/com/xwad/os/adapter/AppAdapter.java b/app/src/main/java/com/xwad/os/adapter/AppAdapter.java index 72b7a92..aeba61a 100644 --- a/app/src/main/java/com/xwad/os/adapter/AppAdapter.java +++ b/app/src/main/java/com/xwad/os/adapter/AppAdapter.java @@ -23,12 +23,12 @@ import com.xwad.os.activity.ExitActivity; import com.xwad.os.activity.ManualActivity; import com.xwad.os.activity.PasswordActivity; import com.xwad.os.activity.activation.ActivationActivity; +import com.xwad.os.activity.homework.HomeworkActivity; import com.xwad.os.activity.login.LoginActivity; import com.xwad.os.activity.service.ServiceActivity; import com.xwad.os.bean.DesktopIcon; import com.xwad.os.config.CommonConfig; import com.xwad.os.manager.AppManager; -import com.xwad.os.manager.RemoteManager; import com.xwad.os.utils.ActivationUtil; import com.xwad.os.utils.ApkUtils; import com.xwad.os.utils.OpenApkUtils; @@ -64,7 +64,6 @@ public class AppAdapter extends RecyclerView.Adapter { 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) { @@ -93,12 +92,6 @@ public class AppAdapter extends RecyclerView.Adapter { @Override public void onClick(View view) { Log.e(TAG, "onClick: " + pkg); - - if (OpenApkUtils.getInstance().getDisallowedRunningAppSet().contains(pkg)) { - Toaster.show("应用已禁止打开"); - return; - } - if (TextUtils.isEmpty(pkg)) { Toaster.show("应用未安装"); OpenApkUtils.getInstance().showDownloadDialog(mContext, pkg, lable); @@ -110,6 +103,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; @@ -178,12 +176,12 @@ public class AppAdapter extends RecyclerView.Adapter { intent.setPackage("com.uiui.zy"); mContext.sendBroadcast(intent); - boolean is_activation = RemoteManager.getInstance().getSnIsActivation(); - if (is_activation) { - mContext.startActivity(new Intent(mContext, ExitActivity.class)); - } else { - Utils.exitDesktop(mContext); - } +// boolean is_activation = AdminManager.getInstance().getSnIsActivation(); +// if (is_activation) { +// mContext.startActivity(new Intent(mContext, ExitActivity.class)); +// } else { +// Utils.exitDesktop(mContext); +// } } @Override diff --git a/app/src/main/java/com/xwad/os/adapter/HomeworkDetailPicAdapter.java b/app/src/main/java/com/xwad/os/adapter/HomeworkDetailPicAdapter.java index d62668a..0eac56c 100644 --- a/app/src/main/java/com/xwad/os/adapter/HomeworkDetailPicAdapter.java +++ b/app/src/main/java/com/xwad/os/adapter/HomeworkDetailPicAdapter.java @@ -17,11 +17,11 @@ import com.bumptech.glide.load.DecodeFormat; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.Target; -import com.xwad.os.R; -import com.xwad.os.utils.FileUtil; -import com.xwad.os.utils.GlideLoadUtils; import com.wgw.photo.preview.PhotoPreview; import com.wgw.photo.preview.interfaces.ImageLoader; +import com.xwad.os.R; +import com.xwad.os.utils.FileUtils; +import com.xwad.os.utils.GlideLoadUtils; import java.io.File; import java.util.List; @@ -48,7 +48,7 @@ public class HomeworkDetailPicAdapter extends RecyclerView.Adapter urls = mHomeworkBean.getFile_url(); String url = urls.get(position); - File file = new File(FileUtil.getDownLoadPath(mContext) + FileUtil.getFileNamefromURL(url)); + File file = new File(FileUtils.getDownLoadPath(mContext) + FileUtils.getFileNamefromURL(url)); if (file.exists()) { GlideLoadUtils.getInstance().glideLoadSetSize(mContext, file, holder.nv_pic, R.mipmap.ic_launcher); holder.iv_download.setVisibility(View.GONE); @@ -95,11 +95,11 @@ public class HomeworkDetailPicAdapter2 extends RecyclerView.Adapter 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/SystemSettings.java b/app/src/main/java/com/xwad/os/bean/SystemSettings.java index 9b78770..10679ab 100644 --- a/app/src/main/java/com/xwad/os/bean/SystemSettings.java +++ b/app/src/main/java/com/xwad/os/bean/SystemSettings.java @@ -76,6 +76,8 @@ public class SystemSettings implements Serializable { int ai_teacher; int photo_search_questions; int ai_question_test; + int sys_voice_assistant; + int app_notify; public int getSetting_call() { return setting_call; @@ -573,6 +575,22 @@ public class SystemSettings implements Serializable { this.ai_question_test = ai_question_test; } + public int getSys_voice_assistant() { + return sys_voice_assistant; + } + + public void setSys_voice_assistant(int sys_voice_assistant) { + this.sys_voice_assistant = sys_voice_assistant; + } + + public int getApp_notify() { + return app_notify; + } + + public void setApp_notify(int app_notify) { + this.app_notify = app_notify; + } + @NotNull @Override public String toString() { 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/bean/uiuios/AppBase.java b/app/src/main/java/com/xwad/os/bean/uiuios/AppBase.java new file mode 100644 index 0000000..b431565 --- /dev/null +++ b/app/src/main/java/com/xwad/os/bean/uiuios/AppBase.java @@ -0,0 +1,58 @@ +package com.xwad.os.bean.uiuios; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; + +import java.io.Serializable; + +public class AppBase implements Serializable { + private static final long serialVersionUID = -1084612101570534997L; + + int id; + String app_name; + String app_package; +// @SerializedName(value = "icon", alternate = "app_icon") + String icon; + + 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; + } + + public String getApp_package() { + return app_package; + } + + public void setApp_package(String app_package) { + this.app_package = app_package; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + + @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/AppUpdateInfo.java b/app/src/main/java/com/xwad/os/bean/uiuios/AppUpdateInfo.java similarity index 98% rename from app/src/main/java/com/xwad/os/bean/AppUpdateInfo.java rename to app/src/main/java/com/xwad/os/bean/uiuios/AppUpdateInfo.java index 57e647a..c9ba6b3 100644 --- a/app/src/main/java/com/xwad/os/bean/AppUpdateInfo.java +++ b/app/src/main/java/com/xwad/os/bean/uiuios/AppUpdateInfo.java @@ -1,4 +1,4 @@ -package com.xwad.os.bean; +package com.xwad.os.bean.uiuios; import androidx.annotation.NonNull; 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 4f9c3b2..005ec52 100644 --- a/app/src/main/java/com/xwad/os/config/CommonConfig.java +++ b/app/src/main/java/com/xwad/os/config/CommonConfig.java @@ -12,7 +12,7 @@ public class CommonConfig { public static final String isLogined = "isLogined"; public static final String AES_KEY = "xqdep8exnafpef3d"; - public static final String LOCK_SCREEN_PASSWORD ="Iflytek_lockScreenPasswordKey"; + 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"; @@ -54,6 +54,13 @@ public class CommonConfig { /*是否显示返回Android按钮*/ public static final String UIUI_RETURN_ANDROID_KEY = "iflytek_uiui_is_return_android"; + public static final String APP_ICON_HIND_SET_KEY = "AppIconHindSet"; + + public static final String ShowStatusBarExpandPanel = "ShowStatusBarExpandPanel"; + + public static final String ShowNavigationBar = "ShowNavigationBar"; + + /*让桌面更新定位信息*/ public static final String IFLYTEK_UPDATE_ADDRESS_ACTION = "IFLYTEK_UPDATE_ADDRESS"; @@ -73,7 +80,6 @@ public class CommonConfig { 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"; /*默认地址北京*/ @@ -146,4 +152,5 @@ public class CommonConfig { 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/DeactivateDialog.java b/app/src/main/java/com/xwad/os/dialog/DeactivateDialog.java new file mode 100644 index 0000000..4153ab5 --- /dev/null +++ b/app/src/main/java/com/xwad/os/dialog/DeactivateDialog.java @@ -0,0 +1,239 @@ +package com.xwad.os.dialog; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.widget.TextView; + +import androidx.appcompat.app.AlertDialog; + +import com.xwad.os.R; + +/** + * description:自定义dialog + */ + +public class DeactivateDialog extends AlertDialog { + + /** + * 显示的标题 + */ + private TextView titleTv; + + /** + * 显示的消息 + */ + private TextView messageTv; + + /** + * 确认和取消按钮 + */ + private TextView negtiveBn, positiveBn, tvDeactivate; + + /** + * 按钮之间的分割线 + */ +// private View columnLineView; + + private Context mContext; + + public DeactivateDialog(Context context) { + super(context, R.style.CustomDialog); + this.mContext = context; + } + + /** + * 都是内容数据 + */ + private String message; + private String title; + private String positive, negtive; + + /** + * 底部是否只有一个按钮 + */ + private boolean isSingle = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_deactivate); + //按空白处不能取消动画 + 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(); + } + } + }); + tvDeactivate.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (onClickBottomListener != null) { + onClickBottomListener.onDeactivateClick(); + } + } + }); + } + + /** + * 初始化界面控件的显示数据 + */ + private void refreshView() { + //如果用户自定了title和message + if (!TextUtils.isEmpty(title)) { + titleTv.setText(title); + titleTv.setVisibility(View.VISIBLE); + } else { + titleTv.setVisibility(View.GONE); + } + if (!TextUtils.isEmpty(message)) { + messageTv.setText(message); + } + //如果设置按钮的文字 + if (!TextUtils.isEmpty(positive)) { + positiveBn.setText(positive); + } else { + positiveBn.setText("确定"); + } + if (!TextUtils.isEmpty(negtive)) { + negtiveBn.setText(negtive); + } else { + negtiveBn.setText("取消"); + } + /** + * 只显示一个按钮的时候隐藏取消按钮,回掉只执行确定的事件 + */ + if (isSingle) { +// columnLineView.setVisibility(View.GONE); + negtiveBn.setVisibility(View.GONE); + } else { + negtiveBn.setVisibility(View.VISIBLE); +// columnLineView.setVisibility(View.VISIBLE); + } + } + + @Override + public void show() { + super.show(); + refreshView(); + } + + /** + * 初始化界面控件 + */ + private void initView() { + negtiveBn = findViewById(R.id.negtive); + positiveBn = findViewById(R.id.positive); + tvDeactivate = findViewById(R.id.tv_deactivate); + titleTv = findViewById(R.id.title); + messageTv = findViewById(R.id.message); +// columnLineView = findViewById(R.id.column_line); + } + + /** + * 设置确定取消按钮的回调 + */ + private OnClickBottomListener onClickBottomListener; + + public void setOnClickBottomListener(OnClickBottomListener onClickBottomListener) { + this.onClickBottomListener = onClickBottomListener; + } + + public interface OnClickBottomListener { + /** + * 点击确定按钮事件 + */ + void onPositiveClick(); + + /** + * 点击取消按钮事件 + */ + void onNegtiveClick(); + + /** + * 点击取消激活按钮事件 + */ + void onDeactivateClick(); + } + + public String getMessage() { + return message; + } + + public DeactivateDialog setMessage(String message) { + this.message = message; + return this; + } + + public String getTitle() { + return title; + } + + public DeactivateDialog setTitle(String title) { + this.title = title; + return this; + } + + public String getPositive() { + return positive; + } + + public DeactivateDialog setPositive(String positive) { + this.positive = positive; + return this; + } + + public String getNegtive() { + return negtive; + } + + public DeactivateDialog setNegtive(String negtive) { + this.negtive = negtive; + return this; + } + + public DeactivateDialog setNegtiveText(String negtive) { + negtiveBn.setText(negtive); + return this; + } + + public boolean isSingle() { + return isSingle; + } + + public DeactivateDialog setSingle(boolean single) { + isSingle = single; + return this; + } + + @Override + public void dismiss() { + super.dismiss(); + } +} 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/complex/ComplexFragment.java b/app/src/main/java/com/xwad/os/fragment/complex/ComplexFragment.java index 7d12f82..a088ef7 100644 --- a/app/src/main/java/com/xwad/os/fragment/complex/ComplexFragment.java +++ b/app/src/main/java/com/xwad/os/fragment/complex/ComplexFragment.java @@ -147,9 +147,11 @@ public class ComplexFragment 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; @@ -194,13 +194,36 @@ public class MineFragment extends BaseMvvmFragment() { + @Override + public void onChanged(SnInfo snInfo) { + if (snInfo != null) { + if (!TextUtils.isEmpty(snInfo.getSn_name())) { + mViewDataBinding.tvName.setText(snInfo.getSn_name()); + } else { + mViewDataBinding.tvName.setText(getString(R.string.default_nickname)); + } + if (!TextUtils.isEmpty(snInfo.getGrade())) { + mViewDataBinding.tvGrade.setText(snInfo.getGrade()); + } else { + mViewDataBinding.tvGrade.setText(getString(R.string.default_grade)); + } + if (!TextUtils.isEmpty(snInfo.getClass_name())) { + mViewDataBinding.tvWlz.setText(snInfo.getClass_name()); + } else { + mViewDataBinding.tvWlz.setText(getString(R.string.default_class)); + } + } + + + } + }); mViewModel.getSnInfo(); } @Override public void fetchData() { Log.e(TAG, "fetchData: "); - setName(); } @Override @@ -213,6 +236,7 @@ public class MineFragment extends BaseMvvmFragment { + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + @Override public FragmentMineBinding getVDBinding() { return binding; @@ -75,6 +79,14 @@ public class MineViewModel extends BaseViewModel mLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() { @@ -115,15 +125,6 @@ public class AccountFragment extends BaseMvvmFragment>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getActivation", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + if (baseResponse.code == 200) { + CodeBean codeBean = baseResponse.data; + mMMKV.encode(CommonConfig.ACTIVATIONBEAN_CODE_KEY, codeBean.getCode()); + ActivationUtil.getInstance().setActivation(1); + ActivationUtil.getInstance().startJxwLauncher(); + } else { + ActivationUtil.getInstance().setActivation(0); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getActivation", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getActivation", "onComplete: "); + } + }); + } + public void getAppInfo(String pkg) { NetInterfaceManager.getInstance().getAdminAppObservable(pkg) .subscribe(new Observer>() { @@ -83,7 +118,7 @@ public class AccountViewModel extends BaseViewModel() { + mViewModel.mAppUpdateInfoData.observe(this, new Observer() { @Override - public void onChanged(AppUpdateInfo appUpdateInfo) { + public void onChanged(AppInfo appUpdateInfo) { if (appUpdateInfo == null) { Toaster.show("已是最新版本"); } else { @@ -68,7 +68,7 @@ public class DeviceFragment extends BaseMvvmFragment mAppUpdateInfoData = new MutableLiveData<>(); + public MutableLiveData mAppUpdateInfoData = new MutableLiveData<>(); - public void checkUpdate() { - NetInterfaceManager.getInstance().getCheckUpdateObservable(BuildConfig.APPLICATION_ID) + public void checkUpdate(String pkg) { + NetInterfaceManager.getInstance().getUpdateObservable(pkg) .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); @@ -65,4 +63,39 @@ public class DeviceViewModel extends BaseViewModel>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("checkStoreUpdate", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { + Log.e("checkStoreUpdate", "onNext: " + appUpdateInfoBaseResponse); + if (appUpdateInfoBaseResponse.code == 200) { + AppInfo appUpdateInfo = appUpdateInfoBaseResponse.data; + if (ApkUtils.isUpdate(getCtx(), appUpdateInfo)) { + ApkUtils.checkAppUpdate(getCtx(), appUpdateInfo); +// Toaster.show("有新的版本需要更新"); + } + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("checkStoreUpdate", "onError: " + e.getMessage()); +// Toaster.show("网络连接失败"); + } + + @Override + public void onComplete() { + Log.e("checkStoreUpdate", "onComplete: "); + } + }); + } + } diff --git a/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java b/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java index af4fe54..9b410f0 100644 --- a/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java +++ b/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java @@ -113,16 +113,6 @@ public class InfoFragment extends BaseMvvmFragment { + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); @Override public FragmentInfoBinding getVDBinding() { @@ -48,6 +50,14 @@ public class InfoViewModel extends BaseViewModel= 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 c3347b5..83257bc 100644 --- a/app/src/main/java/com/xwad/os/manager/AppManager.java +++ b/app/src/main/java/com/xwad/os/manager/AppManager.java @@ -28,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") @@ -61,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"); }}); @@ -97,7 +98,9 @@ public class AppManager { List resolveinfoList = pm.queryIntentActivities(resolveIntent, 0); Set allowPackages = resolveinfoList.stream().map(resolveInfo -> resolveInfo.activityInfo.packageName).collect(Collectors.toSet()); - List adminApp = RemoteManager.getInstance().getAdminApp(); + Log.e(TAG, "getFilterAppset: " + showPackages); + + List adminApp = getAdminApp(); Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); for (ResolveInfo resolveInfo : resolveinfoList) { String pkg = resolveInfo.activityInfo.packageName; @@ -147,9 +150,10 @@ 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 = RemoteManager.getInstance().getAdminApp(); - Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); +// List adminApp = getAdminApp(); +// Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); for (ResolveInfo resolveInfo : resolveinfoList) { String pkg = resolveInfo.activityInfo.packageName; if (ApkUtils.appIsDisable(mContext, pkg)) { @@ -166,9 +170,10 @@ 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); } } @@ -212,7 +217,6 @@ public class AppManager { } - for (ResolveInfo applicationInfo : resolveInfos) { if (!ApkUtils.excludeClassName.contains(applicationInfo.activityInfo.name)) { desktopIcons.add(DesktopIcon.creatDesktopIcon(mContext, applicationInfo)); @@ -233,9 +237,10 @@ 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 = RemoteManager.getInstance().getAdminApp(); - Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); +// List adminApp = AdminManager.getInstance().getAdminApp(); +// Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); for (ResolveInfo resolveInfo : resolveinfoList) { String pkg = resolveInfo.activityInfo.packageName; if (ApkUtils.appIsDisable(mContext, pkg)) { @@ -288,4 +293,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 index 3673f81..fe01c68 100644 --- a/app/src/main/java/com/xwad/os/manager/ControlManager.java +++ b/app/src/main/java/com/xwad/os/manager/ControlManager.java @@ -17,7 +17,7 @@ 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.utils.OpenApkUtils; +import com.xwad.os.utils.JgyUtils; import com.xwad.os.utils.TimeUtils; import java.util.Arrays; @@ -336,14 +336,19 @@ public class ControlManager { } } + @Deprecated private void setBar(SystemSettings settings) { - //系统导航条显示开关 - int setting_navigation = settings.getSetting_navigation(); - Log.e(TAG, "setBar: setting_navigation = " + setting_navigation); - - //状态栏显示开关 - int setting_statusbar = settings.getSetting_statusbar(); - Log.e(TAG, "setBar: setting_statusbar = " + setting_statusbar); +// //系统导航条显示开关 +// int setting_navigation = settings.getSetting_navigation(); +// Log.e(TAG, "setBar: setting_navigation = " + setting_navigation); +// mMMKV.encode(CommonConfig.ShowNavigationBar, setting_navigation); +// AdminManager.getInstance().setStatusBarExpandPanelDisabled(setting_navigation); +// +// //状态栏显示开关 +// int setting_statusbar = settings.getSetting_statusbar(); +// Log.e(TAG, "setBar: setting_statusbar = " + setting_statusbar); +// mMMKV.encode(CommonConfig.ShowStatusBarExpandPanel, setting_statusbar); +// AdminManager.getInstance().setNavigationBarDisabled(setting_statusbar); } @Deprecated @@ -712,6 +717,7 @@ public class ControlManager { 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, ""); } @@ -719,6 +725,7 @@ public class ControlManager { 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, ""); } @@ -726,6 +733,7 @@ public class ControlManager { 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, ""); } @@ -738,14 +746,17 @@ public class ControlManager { 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); } } @@ -817,6 +828,7 @@ public class ControlManager { setDeviceRecover((setting.getIs_device_recover())); setTopNotify(setting.getIs_top_notify()); setBottomBar(setting.getIs_bottom_bar()); + setAppNotify(setting.getApp_notify()); } public void setBluetoothShare(int status) { @@ -844,28 +856,46 @@ public class ControlManager { // AdminManager.getInstance().setNavigationBarDisabled(status); } - public void setDisallowedRunningApp(SystemSettings setting) { - if (setting.getAi_teacher() == 0) { - OpenApkUtils.getInstance().addDisallowedRunningApp("com.jxw.aijtjs"); + public void setAppNotify(int status) { + Log.e(TAG, "setAppNotify: " + status); + if (status == 0) { +// Log.e(TAG, "setAppNotify: setNotificationDisabled successful= " + AdminManager.getInstance().setDisallowAppNotification()); } else { - OpenApkUtils.getInstance().removeDisallowedRunningApp("com.jxw.aijtjs"); +// Log.e(TAG, "setAppNotify: setNotificationDisabled successful = " + AdminManager.getInstance().setAllowAppNotification()); + } + } + + public void setDisallowedRunningApp(SystemSettings setting) { + Log.e(TAG, "setDisallowedRunningApp: "); + if (setting.getAi_teacher() == 0) { +// AdminManager.getInstance().addDisallowedRunningApp("com.jxw.aijtjs"); + } else { +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.aijtjs"); } if (setting.getPhoto_search_questions() == 0) { - OpenApkUtils.getInstance().addDisallowedRunningApp("com.jxw.souti"); +// AdminManager.getInstance().addDisallowedRunningApp("com.jxw.souti"); } else { - OpenApkUtils.getInstance().removeDisallowedRunningApp("com.jxw.souti"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.souti"); } if (setting.getAi_question_test() == 0) { - OpenApkUtils.getInstance().addDisallowedRunningApp("com.jxw.aizndy"); +// AdminManager.getInstance().addDisallowedRunningApp("com.jxw.aizndy"); } else { - OpenApkUtils.getInstance().removeDisallowedRunningApp("com.jxw.aizndy"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.aizndy"); } + if (setting.getAi_question_test() == 0) { +// AdminManager.getInstance().addDisallowedRunningApp("com.hihonor.magicvoice"); + } else { +// AdminManager.getInstance().removeDisallowedRunningApp("com.hihonor.magicvoice"); + } } public void setDisallowedRunningApp() { - +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.aijtjs"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.souti"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.aizndy"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.hihonor.magicvoice"); } } 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/network/NetInterfaceManager.java b/app/src/main/java/com/xwad/os/network/NetInterfaceManager.java index 2520757..a00a885 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; @@ -13,8 +24,9 @@ import com.trello.rxlifecycle4.android.FragmentEvent; import com.xwad.os.BuildConfig; import com.xwad.os.alarm.AlarmUtils; import com.xwad.os.bean.AlarmClockData; +import com.xwad.os.bean.AppIcon; 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,55 @@ 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.bean.uiuios.AppUpdateInfo; import com.xwad.os.config.CommonConfig; import com.xwad.os.disklrucache.CacheHelper; import com.xwad.os.gson.GsonUtils; +import com.xwad.os.manager.ControlManager; import com.xwad.os.manager.DeviceSNManager; 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.GetAppIconApi; +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.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 +94,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 +109,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 +131,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 +217,9 @@ public class NetInterfaceManager { .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); } + + mUploadIconPkgs = mMMKV.decodeStringSet(uploadIconPkgsKey, new HashSet<>()); + Log.e("init", "NetInterfaceManager: mUploadIconPkgs = " + mUploadIconPkgs); } /** @@ -260,6 +300,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 @@ -267,14 +323,14 @@ public class NetInterfaceManager { * */ public Observable> getSnInfoControl() { - return mRetrofit.create(SnInfoApi.class) + return getSnInfoApi() .getSninfo(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable> getUserAvatarInfoControl() { - return mRetrofit.create(SnInfoApi.class) + return getSnInfoApi() .getUserAvatarInfo(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); @@ -283,21 +339,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()); @@ -340,14 +396,14 @@ public class NetInterfaceManager { } public Observable> getStudyStatObservable() { - return mRetrofit.create(SnInfoApi.class) + return getSnInfoApi() .getStudyStat(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getUpdateAddressObservable(String address, double longitude, double latitude) { - return mRetrofit.create(SnInfoApi.class) + return getSnInfoApi() .updateAddress(getToken(), DeviceSNManager.getDeviceSN(), address, longitude, latitude) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); @@ -396,12 +452,19 @@ public class NetInterfaceManager { } 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) @@ -418,7 +481,7 @@ public class NetInterfaceManager { public Observable> getNewCodeLoginObservable(String mobile, String code) { return mRetrofit.create(LoginApi.class) - .newCodeLogin(mobile, code, "", BuildConfig.APPLICATION_ID) + .newCodeLogin(mobile, code, DeviceSNManager.getDeviceSN(), BuildConfig.APPLICATION_ID) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -472,6 +535,34 @@ public class NetInterfaceManager { .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>> getAppIconObservable() { + return mRetrofit.create(GetAppIconApi.class) + .getAppIcon(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + public Observable getOauthTokenObservable() { Map params = new HashMap<>(); params.put("appId", JxwUtils.getAppId()); @@ -511,7 +602,7 @@ public class NetInterfaceManager { void onComplete(); } - public interface onCompleteCallback { + public interface OnCompleteCallback { void onComplete(); } @@ -647,12 +738,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); } @@ -660,7 +751,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); } @@ -669,17 +760,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)); } @@ -716,7 +807,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) { @@ -747,13 +838,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)); } @@ -763,7 +854,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) { @@ -789,13 +880,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)); } @@ -805,7 +896,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) { @@ -943,4 +1034,584 @@ 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"); + + this.add("com.hihonor.notepad"); + this.add("com.hihonor.devicefinder"); + this.add("com.hihonor.email"); + this.add("com.hihonor.kidsmode"); + this.add("com.hihonor.servicecenter"); + this.add("com.hihonor.parentcontrol"); + this.add("com.hihonor.baidu.browser"); + this.add("cn.honor.qinxuan"); + this.add("com.hihonor.vmall"); + this.add("com.hihonor.search"); + this.add("com.hihonor.hnofficelauncher"); + this.add("com.hihonor.youku.video"); + this.add("com.hihonor.quickgamecenter"); + this.add("com.hihonor.edulauncher"); + this.add("com.hihonor.cloudmusic"); + this.add("com.hihonor.appmarket"); + this.add("com.hihonor.gamecenter"); + this.add("com.hihonor.dz.reader"); + this.add("com.hihonor.magichome"); + }}; + + 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(CommonConfig.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: "); + } + }); + } + + public interface AppIconCallback { + void onComplete(); + } + + public void getAppIcon() { + getAppIconObservable() + .subscribe(getAppIconObserver(null)); + } + + public void getAppIcon(AppIconCallback callback) { + getAppIconObservable() + .subscribe(getAppIconObserver(callback)); + } + + public void getAppIcon(BehaviorSubject lifecycle, AppIconCallback callback) { + getAppIconObservable() + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(getAppIconObserver(callback)); + } + + + public Observer>> getAppIconObserver(AppIconCallback callback) { + return new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAppIcon", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> baseResponse) { + Log.e("getAppIcon", "onNext: " + baseResponse); + if (baseResponse.code == 200) { + List appIconList = baseResponse.data; + Set pkgList = appIconList.stream().map(new java.util.function.Function() { + @Override + public String apply(AppIcon appIcon) { + return appIcon.getApp_package(); + } + }).collect(Collectors.toSet()); + Set stringSet = mMMKV.decodeStringSet(CommonConfig.APP_ICON_HIND_SET_KEY, new HashSet<>()); +// AdminManager.getInstance().removeDisallowedRunningApp(new ArrayList<>(stringSet)); + mMMKV.encode(CommonConfig.APP_ICON_HIND_SET_KEY, pkgList); +// AdminManager.getInstance().addDisallowedRunningApp(new ArrayList<>(pkgList)); + } else { + Set stringSet = mMMKV.decodeStringSet(CommonConfig.APP_ICON_HIND_SET_KEY, new HashSet<>()); +// AdminManager.getInstance().removeDisallowedRunningApp(new ArrayList<>(stringSet)); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAppIcon", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAppIcon", "onComplete: "); + if (callback != null) + callback.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..0f52b22 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"; /*爱心提醒通知成功*/ @@ -82,8 +107,12 @@ public class UrlAddress { /*获取系统设置*/ public final static String GET_SETTINGS = "control/getSetting"; + /*获取禁用包名*/ + public static final String GET_APP_ICON = "getAppIcon"; + 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 +121,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/GetAppIconApi.java b/app/src/main/java/com/xwad/os/network/api/GetAppIconApi.java new file mode 100644 index 0000000..df28a9d --- /dev/null +++ b/app/src/main/java/com/xwad/os/network/api/GetAppIconApi.java @@ -0,0 +1,18 @@ +package com.xwad.os.network.api; + +import com.xwad.os.bean.AppIcon; +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.GET; +import retrofit2.http.Query; + +public interface GetAppIconApi { + @GET(UrlAddress.GET_APP_ICON) + Observable>> getAppIcon( + @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/network/api/uiuios/CheckUpdateApi.java b/app/src/main/java/com/xwad/os/network/api/uiuios/CheckUpdateApi.java index 11a387a..e2feae1 100644 --- a/app/src/main/java/com/xwad/os/network/api/uiuios/CheckUpdateApi.java +++ b/app/src/main/java/com/xwad/os/network/api/uiuios/CheckUpdateApi.java @@ -1,7 +1,7 @@ package com.xwad.os.network.api.uiuios; -import com.xwad.os.bean.AppUpdateInfo; import com.xwad.os.bean.BaseResponse; +import com.xwad.os.bean.uiuios.AppUpdateInfo; import com.xwad.os.network.UrlAddress; import io.reactivex.rxjava3.core.Observable; 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 1dc917a..beaf6a8 100644 --- a/app/src/main/java/com/xwad/os/push/PushManager.java +++ b/app/src/main/java/com/xwad/os/push/PushManager.java @@ -4,22 +4,67 @@ import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.os.PowerManager; +import android.text.TextUtils; import android.util.Log; +import com.arialyy.aria.core.Aria; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.hjq.toast.Toaster; +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.network.NetInterfaceManager; -import com.hjq.toast.Toaster; -import com.xwad.os.utils.OpenApkUtils; +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.FileUtils; +import com.xwad.os.utils.JgyUtils; +import com.xwad.os.utils.ServiceAliveUtils; +import com.xwad.os.utils.Utils; + +import java.io.File; +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") @@ -50,10 +95,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"; /*作业提醒*/ @@ -67,14 +288,75 @@ public class PushManager { private static final String PHOTO_SEARCH_QUESTIONS = "124"; /*AI答疑测试*/ private static final String AI_QA_TEST = "125"; - + /*语音助手*/ + private static final String VOICE_ASSISTANT = "126"; + /*APP应用通知管控*/ + private static final String APP_NOTIFY_SETTING = "127"; 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 FORCE_INSTALLAPK: + Toaster.debugShow("收到推送消息: 强制安装应用"); +// NetInterfaceManager.getInstance().getAllappPackage(); +// NetInterfaceManager.getInstance().getForceInstall(); + intallApk(extras); + break; + case FORCE_UNINSTALLAPK: + Toaster.debugShow("收到推送消息: 强制卸载应用"); + unintallApk(extras); + break; + case REBOOT_DEVICES: + Toaster.debugShow("收到推送消息: 重启"); +// AdminManager.getInstance().rebootDevice(); + break; + case FORCE_KILL: + Toaster.debugShow("收到推送消息: 强制停止应用"); + JsonObject killJSONObject = GsonUtils.getJsonObject(extras); + String app_package = killJSONObject.get("app_package").getAsString(); +// AdminManager.getInstance().killApplicationProcess(app_package); + Log.e(TAG, extras); + 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 CLEAN_APP_CACHE: + Toaster.debugShow("收到推送消息: 清除应用缓存"); + cleanAppCache(extras); + break; + case SHOW_THIRD_APP: + showThirdApp(extras); + break; + case ALARM_CLOCK: Toaster.debugShow("收到推送消息: 设置闹钟"); sendAlarmClock(extras); break; + case HIDE_APPICON: + new Handler(Looper.getMainLooper()).postDelayed(() -> NetInterfaceManager.getInstance().getAppIcon(() -> { + }), 2000); + break; + case KILL_APP: + Toaster.debugShow("收到推送消息: 内存优化"); + killBackgroundApp(); + break; case ONLINE_COURSE_MODE: Toaster.debugShow("收到推送消息: 网课模式"); NetInterfaceManager.getInstance().getCloudLessonSettings(); @@ -83,8 +365,42 @@ 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 UPGRADE_PASSWD: + NetInterfaceManager.getInstance().getLockScreenPwd(); + 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); @@ -98,10 +414,42 @@ public class PushManager { case AI_QA_TEST: setAiQuestionTest(extras); break; + case VOICE_ASSISTANT: + setVoiceAssistant(extras); + break; + case APP_NOTIFY_SETTING: + setAppNotify(extras); + break; default: } } + private void setAppNotify(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("app_notify"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setAppNotify: jsonElement is null"); + return; + } + int app_notify = jsonElement.getAsInt(); + ControlManager.getInstance().setAppNotify(app_notify); + } + + private void setVoiceAssistant(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + JsonElement jsonElement = jsonObject.get("sys_voice_assistant"); + if (jsonElement == null || jsonElement.isJsonNull()) { + Log.e(TAG, "setVoiceAssistant: jsonElement is null"); + return; + } + int sys_voice_assistant = jsonElement.getAsInt(); + if (sys_voice_assistant == 0) { +// AdminManager.getInstance().addDisallowedRunningApp("com.hihonor.magicvoice"); + } else { +// AdminManager.getInstance().removeDisallowedRunningApp("com.hihonor.magicvoice"); + } + } + private void setAiTeacher(String extras) { JsonObject jsonObject = GsonUtils.getJsonObject(extras); JsonElement jsonElement = jsonObject.get("ai_teacher"); @@ -111,9 +459,9 @@ public class PushManager { } int ai_teacher = jsonElement.getAsInt(); if (ai_teacher == 0) { - OpenApkUtils.getInstance().addDisallowedRunningApp("com.jxw.aijtjs"); +// AdminManager.getInstance().addDisallowedRunningApp("com.jxw.aijtjs"); } else { - OpenApkUtils.getInstance().removeDisallowedRunningApp("com.jxw.aijtjs"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.aijtjs"); } } @@ -126,9 +474,9 @@ public class PushManager { } int photo_search_questions = jsonElement.getAsInt(); if (photo_search_questions == 0) { - OpenApkUtils.getInstance().addDisallowedRunningApp("com.jxw.souti"); +// AdminManager.getInstance().addDisallowedRunningApp("com.jxw.souti"); } else { - OpenApkUtils.getInstance().removeDisallowedRunningApp("com.jxw.souti"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.souti"); } } @@ -141,9 +489,237 @@ public class PushManager { } int ai_question_test = jsonElement.getAsInt(); if (ai_question_test == 0) { - OpenApkUtils.getInstance().addDisallowedRunningApp("com.jxw.aizndy"); +// AdminManager.getInstance().addDisallowedRunningApp("com.jxw.aizndy"); } else { - OpenApkUtils.getInstance().removeDisallowedRunningApp("com.jxw.aizndy"); +// AdminManager.getInstance().removeDisallowedRunningApp("com.jxw.aizndy"); + } + } + + 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"); + } + } + + //静默安装应用,使用okgo,断网会出现问题,等待修改使用aria + private void intallApk(String jsonString) { + if (TextUtils.isEmpty(jsonString)) { + return; + } + JsonObject extra = GsonUtils.getJsonObject(jsonString); + String packages = extra.get("package").getAsString(); + long app_version_code = extra.get("app_version_code").getAsLong(); + Toaster.debugShow("收到应用安装消息:包名" + packages); + String url = extra.get("url").getAsString(); + if (TextUtils.isEmpty(url)) { + return; + } + PackageManager pm = mContext.getPackageManager(); + PackageInfo packageInfo = null; + try { + packageInfo = pm.getPackageInfo(packages, 0); + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo != null) { + long appVersionCode; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + appVersionCode = packageInfo.getLongVersionCode(); + } else { + appVersionCode = packageInfo.versionCode; + } + if (app_version_code > appVersionCode) { + FileUtils.ariaDownload(mContext, url, extra); + } else { + Log.e(TAG, "intallApk: " + packages + " is up to date"); + } + } else { + FileUtils.ariaDownload(mContext, url, extra); + } + Aria.download(this).resumeAllTask(); + } + + private void unintallApk(String jsonString) { + JsonObject object = GsonUtils.getJsonObject(jsonString); + String packageName = object.get("app_package").getAsString(); + // 台电设备不删除无法静默卸载 +// removeForceSettings(packageName); + Toaster.debugShow("收到应用卸载消息:包名" + packageName); + if (!"".equals(packageName) && !packageName.equals(mContext.getPackageName())) { + if (!ApkUtils.isAvailable(mContext, packageName)) { +// NetInterfaceManager.getInstance().setAppuninstallInfo(sn_id, packageName); + } else { +// AdminManager.getInstance().removeDisallowedRunningApp(packageName); +// AdminManager.getInstance().uninstallPackage(packageName); + } } } @@ -162,13 +738,142 @@ 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 cleanAppCache(String jsonString) { + JsonObject jsonObject = GsonUtils.getJsonObject(jsonString); + String pkg = jsonObject.get("package").getAsString(); + if (TextUtils.isEmpty(pkg)) { + Log.e(TAG, "cleanAppCache: pkg is null"); + return; + } + try { +// AdminManager.getInstance().clearPackageData(pkg); + } catch (Exception e) { + e.printStackTrace(); + Log.e(TAG, "cleanAppCache: " + e.getMessage()); + } + } + + private void showThirdApp(String extras) { + JsonObject jsonObject = JsonParser.parseString(extras).getAsJsonObject(); + int setting_admin_app = jsonObject.get("setting_other_appInstaller").getAsInt(); + mMMKV.encode(CommonConfig.APP_INSTALLATION, setting_admin_app); + Intent intent = new Intent(UserFragment.UPDATE_DESKTOP_ICON_ACTION); + mContext.sendBroadcast(intent); + + } + + 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/receiver/AoleDeviceAdminReceiver.java b/app/src/main/java/com/xwad/os/receiver/AoleDeviceAdminReceiver.java new file mode 100644 index 0000000..162721e --- /dev/null +++ b/app/src/main/java/com/xwad/os/receiver/AoleDeviceAdminReceiver.java @@ -0,0 +1,20 @@ +package com.xwad.os.receiver; + +import android.app.admin.DeviceAdminReceiver; +import android.content.Context; +import android.content.Intent; + +import com.xwad.os.R; + +public class AoleDeviceAdminReceiver extends DeviceAdminReceiver { + + @Override + public CharSequence onDisableRequested(Context context, Intent intent) { + return context.getString(R.string.disable_warning); + } + + @Override + public void onEnabled(Context context, Intent intent) { + super.onEnabled(context, intent); + } +} diff --git a/app/src/main/java/com/xwad/os/receiver/ApkInstallReceiver.java b/app/src/main/java/com/xwad/os/receiver/ApkInstallReceiver.java index c9f50e2..d7f9a5d 100644 --- a/app/src/main/java/com/xwad/os/receiver/ApkInstallReceiver.java +++ b/app/src/main/java/com/xwad/os/receiver/ApkInstallReceiver.java @@ -11,14 +11,28 @@ import com.xwad.os.BuildConfig; import com.xwad.os.config.CommonConfig; import com.xwad.os.fragment.user.UserFragment; import com.xwad.os.jxw.JxwPackageConfig; +import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.service.main.MainService; import com.xwad.os.utils.ActivationUtil; +import java.util.concurrent.TimeUnit; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableEmitter; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; + public class ApkInstallReceiver extends BroadcastReceiver { private static final String TAG = "APKinstallReceiver"; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + private static NewAppListener newAppListener; + + static { + sendAppInfo(); + } + @Override public void onReceive(final Context context, Intent intent) { // an Intent broadcast. @@ -57,4 +71,41 @@ public class ApkInstallReceiver extends BroadcastReceiver { } + public interface NewAppListener { + void setNewAppListener(String packageName); + } + + private static void sendAppInfo() { + MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + Observable.create((ObservableEmitter emitter) -> newAppListener = emitter::onNext) + .throttleLast(1, TimeUnit.MINUTES) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("sendAppInfo", "onSubscribe: "); + } + + @Override + public void onNext(String s) { + Log.e("sendAppInfo", "onNext: " + s); + int isLogined = mMMKV.decodeInt(CommonConfig.isLogined, 0); + if (isLogined != 1) return; + NetInterfaceManager.getInstance().updateAdminInfo(); + NetInterfaceManager.getInstance().SendAppInstallInfo(); +// NetInterfaceManager.getInstance().getForceInstall(); +// NetInterfaceManager.getInstance().getAllappPackage(null); + NetInterfaceManager.getInstance().getAppIcon(); + } + + @Override + public void onError(Throwable e) { + Log.e("sendAppInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("sendAppInfo", "onComplete: "); + } + }); + } } 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..9c93912 100644 --- a/app/src/main/java/com/xwad/os/service/DownloadService.java +++ b/app/src/main/java/com/xwad/os/service/DownloadService.java @@ -46,10 +46,10 @@ public class DownloadService extends Service { Aria.download(this).register(); - mNotificationManagerCompat = NotificationManagerCompat.from(this); - createNotificationChannel(); - createDownloadNotificationChannel(); - sendSimpleNotification(); +// mNotificationManagerCompat = NotificationManagerCompat.from(this); +// createNotificationChannel(); +// createDownloadNotificationChannel(); +// sendSimpleNotification(); } @Override @@ -197,20 +197,20 @@ public class DownloadService extends Service { AriaDownloadInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString); if (ariaDownloadInfo != null) { Toaster.show("正在下载: " + ariaDownloadInfo.getAppName() + "\t" + task.getPercent() + "%"); - sendDownloadRunning(ariaDownloadInfo, task.getPercent()); +// sendDownloadRunning(ariaDownloadInfo, task.getPercent()); } } @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); if (ariaDownloadInfo != null) { Toaster.show("下载完成: " + "\t" + ariaDownloadInfo.getAppName()); - sendDownloadComplete(ariaDownloadInfo, task.getFilePath()); +// sendDownloadComplete(ariaDownloadInfo, task.getFilePath()); } } @@ -222,7 +222,7 @@ public class DownloadService extends Service { AriaDownloadInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString); if (ariaDownloadInfo != null) { Toaster.show("下载失败: " + "\t" + ariaDownloadInfo.getAppName()); - sendDownloadFail(ariaDownloadInfo); +// sendDownloadFail(ariaDownloadInfo); } } 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..a3d08f3 --- /dev/null +++ b/app/src/main/java/com/xwad/os/service/ManagerService.java @@ -0,0 +1,807 @@ +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.xwad.os.BuildConfig; +import com.xwad.os.KeepAliveConnection; +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.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.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"; + + 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) { + Log.e(TAG, "showFloatingWindow: "); +// 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(CommonConfig.LOCK_SCREEN_PASSWORD, CommonConfig.DEFAULT_PASSWORD); + if (password.equals(content)) { + hide(); + } else if (CommonConfig.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() { + Log.e(TAG, "hideFloatingWindow: "); + int is_top_notify = mMMKV.decodeInt(CommonConfig.ShowStatusBarExpandPanel, 1); +// AdminManager.getInstance().setStatusBarExpandPanelDisabled(is_top_notify == 0); + int is_bottom_bar = mMMKV.decodeInt(CommonConfig.ShowNavigationBar, 1); +// AdminManager.getInstance().setNavigationBarDisabled(is_bottom_bar == 0); + + 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..c0dac01 100644 --- a/app/src/main/java/com/xwad/os/service/SocketService.java +++ b/app/src/main/java/com/xwad/os/service/SocketService.java @@ -18,7 +18,6 @@ import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory; import com.blankj.utilcode.util.NetworkUtils; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import com.hjq.toast.Toaster; import com.tencent.mmkv.MMKV; import com.xwad.os.BuildConfig; @@ -154,7 +153,9 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat initOnlineSocketClient(); initSsoSocketClient(); initPush(); + NetInterfaceManager.getInstance().getSystemSettings(); break; + default: } } } @@ -164,6 +165,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat @Override public void onDestroy() { super.onDestroy(); + Log.e(TAG, "onDestroy: "); NetworkUtils.unregisterNetworkStatusChangedListener(this); dispose(); closeOnlineConnect(); @@ -175,6 +177,7 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat } private void dispose() { + Log.e(TAG, "dispose: "); if (mOnlineDisposable != null && !mOnlineDisposable.isDisposed()) { mOnlineDisposable.dispose(); mOnlineDisposable = null; @@ -250,8 +253,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 +276,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: 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..1a4d020 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,37 @@ 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.hjq.toast.Toaster; 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.bean.UserInfo; import com.xwad.os.config.CommonConfig; +import com.xwad.os.gson.GsonUtils; +import com.xwad.os.jxw.JxwPackageConfig; import com.xwad.os.network.NetInterfaceManager; +import com.xwad.os.service.ManagerService; +import com.xwad.os.utils.ActivationUtil; +import com.xwad.os.utils.ApkUtils; +import com.xwad.os.utils.FileUtils; +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 +72,111 @@ 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() { + NetInterfaceManager.getInstance().getUserInfoControl() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getUserInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse userInfoBaseResponse) { + Log.e("getUserInfo", "onNext: " + userInfoBaseResponse); + if (userInfoBaseResponse.code == 200) { + UserInfo userInfo = userInfoBaseResponse.data; + int vip_level_id = userInfo.getVip_level_id(); + if (vip_level_id != 0) { + if (!ApkUtils.isAvailable(mContext, JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME)) { + getAppInfo(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME); + } + if (!ApkUtils.isAvailable(mContext, "com.jxw.download")) { + getAppInfo("com.jxw.download"); + } + if (!ApkUtils.isAvailable(mContext, "com.study.flashplayer")) { + getAppInfo("com.study.flashplayer"); + } + } + + } else if (userInfoBaseResponse.code == 401) { + ActivationUtil.getInstance().setActivation(0); + mMMKV.encode(CommonConfig.ACCOUNT_LOGIN_STATU, 0); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getUserInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getUserInfo", "onComplete: "); + } + }); + } + + public void getAppInfo(String pkg) { + NetInterfaceManager.getInstance().getAdminAppObservable(pkg) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAppInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("getAppInfo", "onNext: " + baseResponse); + if (baseResponse.code == 200) { + AppInfo appInfo = baseResponse.data; + FileUtils.ariaDownload(mContext, appInfo.getApp_url(), appInfo); + } else { + Toaster.showLong("没有找到应用信息,请联系客服"); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAppInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getAppInfo", "onComplete: "); + } + }); + } + @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 +184,165 @@ 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() { + NetInterfaceManager.getInstance().updateAdminInfo(); + NetInterfaceManager.getInstance().SendAppInstallInfo(); + } - @Override - public void setAlarmClockEmpty() { - Log.e(TAG, "setAlarmClock: setAlarmClockEmpty"); - } + @Override + public void getTimeControl() { + } + + @Override + public void getAllApp() { + + } + + @Override + public void getForceInstall() { + + } + + @Override + public void getAppIcon() { + NetInterfaceManager.getInstance().getAppIcon(getLifecycle(), new NetInterfaceManager.AppIconCallback() { @Override - public void onError() { - Log.e(TAG, "setAlarmClock: onError"); + public void onComplete() { + Log.e("getAppIcon", "onComplete: "); } }); } + + @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() { + NetInterfaceManager.getInstance().getLockScreenPwd(lifecycle, new NetInterfaceManager.OnCompleteCallback() { + @Override + public void onComplete() { + mView.setLockScreenPwd(); + } + }); + } + + } 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..6d6d856 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 @@ -19,15 +19,21 @@ import com.blankj.utilcode.util.NetworkUtils; import com.tencent.mmkv.MMKV; import com.xwad.os.R; import com.xwad.os.activity.NoticeActivity; -import com.xwad.os.activity.main.MainActivity; +import com.xwad.os.activity.home.HomeActivity; 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.network.NetInterfaceManager; 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,25 +69,55 @@ 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(); + registerReceivers(); NetworkUtils.registerNetworkStatusChangedListener(this); startJxwLauncher(); mNotificationManagerCompat = NotificationManagerCompat.from(this); createNotificationChannel(); -// showNotification(); sendSimpleNotification(); startService(new Intent(MainService.this, SocketService.class)); + + Log.e(TAG, "setDefault: startServices time = " + (System.currentTimeMillis() - time) + "ms"); + + getSystemSettings(); + + } + + private void getSystemSettings() { + mPresenter.getCloudLessonSettings(); + mPresenter.updateDeviceInfo(); + mPresenter.getAppIcon(); + mPresenter.getScreenLock(); + mPresenter.getAdminApp(); + mPresenter.getSystemSettings(); + mPresenter.getLockScreenPwd(); + } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand: "); + if (intent != null) { + String action = intent.getAction(); + if (!TextUtils.isEmpty(action)) { + Log.e(TAG, "onStartCommand: action = " + action); + switch (action) { + case SocketService.LOGIN_SUCCESSFUL: + getSystemSettings(); + NetInterfaceManager.getInstance().getSystemSettings(); + break; + default: + } + } + } return START_STICKY; } @@ -114,7 +150,7 @@ public class MainService extends BaseRxService implements MainSContact.MainSView private int NotificationID = 1; private void sendSimpleNotification() { - Intent intent = new Intent(this, MainActivity.class); + Intent intent = new Intent(this, HomeActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) @@ -218,11 +254,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 +278,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/ActivationUtil.java b/app/src/main/java/com/xwad/os/utils/ActivationUtil.java index 5ec7a6e..4f381a7 100644 --- a/app/src/main/java/com/xwad/os/utils/ActivationUtil.java +++ b/app/src/main/java/com/xwad/os/utils/ActivationUtil.java @@ -4,6 +4,7 @@ import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.text.TextUtils; import android.util.Log; import com.tencent.mmkv.MMKV; @@ -122,7 +123,12 @@ public class ActivationUtil { } public void startJxwLauncher() { + if (!ApkUtils.isAvailable(mContext, JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME)) { + Log.e(TAG, "startJxwLauncher: jxw app not install"); + return; + } String code = getActivationCode(); + Log.e(TAG, "startJxwLauncher: code is null = " + TextUtils.isEmpty(code)); boolean regist_success = mMMKV.decodeBool(MainService.JXW_REGISTER_SUCCESS, false); if (!regist_success) { Intent intent = new Intent("UIUI_ACTIVATION"); 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 1317003..173343d 100644 --- a/app/src/main/java/com/xwad/os/utils/ApkUtils.java +++ b/app/src/main/java/com/xwad/os/utils/ApkUtils.java @@ -20,14 +20,20 @@ import android.util.Log; import androidx.annotation.RequiresApi; 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.AppUpdateInfo; +import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.DesktopIcon; -import com.xwad.os.manager.RemoteManager; +import com.xwad.os.bean.uiuios.AppUpdateInfo; import com.xwad.os.receiver.InstallResultReceiver; +import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.Collator; @@ -127,6 +133,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"; @@ -216,8 +277,8 @@ public class ApkUtils { if (!TextUtils.isEmpty(appListString)) { packageList = new ArrayList<>(Arrays.asList(appListString.split(","))); } - List adminApp = RemoteManager.getInstance().getAdminApp(); - Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); +// List adminApp = AdminManager.getInstance().getAdminApp(); +// Log.i(TAG, "queryFilterAppInfo: adminapp = " + adminApp); for (ResolveInfo resolveInfo : resolveinfoList) { String pkg = resolveInfo.activityInfo.packageName; if (appIsDisable(context, pkg)) { @@ -239,11 +300,11 @@ public class ApkUtils { // } else { if (allowPackages.contains(pkg) && !excludePackageName.contains(pkg)) { - if (adminApp.contains(pkg)) { - resolveInfos.add(resolveInfo); - } else if (showPackageName.contains(pkg)) { - resolveInfos.add(resolveInfo); - } +// if (adminApp.contains(pkg)) { +// resolveInfos.add(resolveInfo); +// } else if (showPackageName.contains(pkg)) { + resolveInfos.add(resolveInfo); +// } } // } } @@ -464,6 +525,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 { @@ -512,6 +591,141 @@ public class ApkUtils { } } + /** + * 通过路径安装APK,兼容Android 9以上 + * + * @param context 上下文 + * @param filePath apk文件路径 + */ + public static void installApp(Context context, String filePath) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + installAppatPie(context, filePath); + } else { + installApps(filePath); + } + } + + public static boolean installApps(String apkPath) { + Toaster.showShort("正在安装应用"); + Process process = null; + BufferedReader successResult = null; + BufferedReader errorResult = null; + StringBuilder successMsg = new StringBuilder(); + StringBuilder errorMsg = new StringBuilder(); + try { + process = new ProcessBuilder("pm", "install", "-i", BuildConfig.APPLICATION_ID, "--user", "0", apkPath).start(); + successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String s; + while ((s = successResult.readLine()) != null) { + successMsg.append(s); + } + while ((s = errorResult.readLine()) != null) { + errorMsg.append(s); + } + } catch (Exception e) { + Log.e("installApps1", e.getMessage()); + } finally { + try { + if (successResult != null) { + successResult.close(); + } + if (errorResult != null) { + errorResult.close(); + } + } catch (Exception e) { + Log.e("installApps2", e.getMessage()); + } + if (process != null) { + process.destroy(); + } + } + Log.e("result", "" + errorMsg.toString()); + //如果含有“success”认为安装成功 + Log.e("installApp", successMsg.toString()); +// if (!successMsg.toString().equalsIgnoreCase("success")) { +// install(context, new File(apkPath)); +// } + return successMsg.toString().equalsIgnoreCase("success"); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public static void installAppatPie(Context context, String apkFilePath) { + File file = new File(apkFilePath); + PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); + PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller + .SessionParams.MODE_FULL_INSTALL); + sessionParams.setSize(file.length()); + int sessionId = createSession(packageInstaller, sessionParams); + if (sessionId != -1) { + boolean copySuccess = copyApkFile(packageInstaller, sessionId, apkFilePath); + if (copySuccess) { + install(packageInstaller, sessionId, context); + } + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static boolean copyApkFile(PackageInstaller pi, int sessionId, String apkFilePath) { + boolean success = false; + File apkFile = new File(apkFilePath); + PackageInstaller.Session session = null; + try { + session = pi.openSession(sessionId); + OutputStream out = session.openWrite("app.apk", 0, apkFile.length()); + FileInputStream input = new FileInputStream(apkFile); + int read = 0; + byte[] buffer = new byte[65536]; +// while (read != -1) { +// read = input.read(buffer); +// out.write(buffer, 0, read); +// } + while (true) { + read = input.read(buffer); + if (read == -1) { + session.fsync(out); + success = true; + out.close(); + input.close(); + break; + } + out.write(buffer, 0, read); + } + } catch (IOException e) { + e.printStackTrace(); + Log.e("fht", "copyApkFile" + e.getMessage()); + } + return success; + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static void install(PackageInstaller packageInstaller, int sessionId, Context context) { + try { + PackageInstaller.Session session = packageInstaller.openSession(sessionId); + Intent intent = new Intent(context, InstallResultReceiver.class); + PendingIntent pendingIntent = PendingIntent.getBroadcast( + context, + 1, intent, + PendingIntent.FLAG_UPDATE_CURRENT + ); + session.commit(pendingIntent.getIntentSender()); + } catch (IOException e) { + e.printStackTrace(); + Log.e(TAG, "install: " + e.getMessage()); + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static int createSession(PackageInstaller packageInstaller, PackageInstaller.SessionParams sessionParams) { + int sessionId = -1; + try { + sessionId = packageInstaller.createSession(sessionParams); + } catch (IOException e) { + e.printStackTrace(); + } + return sessionId; + } + /** * 静默卸载应用 * @@ -639,6 +853,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(); @@ -676,6 +895,33 @@ public class ApkUtils { installApkFile(context, apk); } + public static void checkAppUpdate(Context context, AppInfo appInfo) { + String packageName = appInfo.getApp_package(); + long versionCode = appInfo.getApp_version_code(); + String url = appInfo.getApp_url(); + PackageInfo packageInfo = null; + try { + packageInfo = context.getPackageManager().getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo == null) { + FileUtils.ariaDownload(context, url, appInfo); + } else { + long appVersionCode; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + appVersionCode = packageInfo.getLongVersionCode(); + } else { + appVersionCode = packageInfo.versionCode; + } + if (appVersionCode < versionCode) { + FileUtils.ariaDownload(context, url, appInfo); + } 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(); @@ -687,7 +933,7 @@ public class ApkUtils { e.printStackTrace(); } if (packageInfo == null) { - FileUtil.ariaDownload(context, url, appUpdateInfo); + FileUtils.ariaDownload(context, url, appUpdateInfo); } else { long appVersionCode; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { @@ -696,7 +942,7 @@ public class ApkUtils { appVersionCode = packageInfo.versionCode; } if (appVersionCode < versionCode) { - FileUtil.ariaDownload(context, url, appUpdateInfo); + FileUtils.ariaDownload(context, url, appUpdateInfo); } else { Log.e(TAG, "checkUpdate: " + packageName + "\t已经是最新版"); } 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..7d5471c 100644 --- a/app/src/main/java/com/xwad/os/utils/FileUtil.java +++ b/app/src/main/java/com/xwad/os/utils/FileUtil.java @@ -15,9 +15,9 @@ import androidx.core.content.ContextCompat; import com.arialyy.aria.core.Aria; import com.xwad.os.bean.AppInfo; -import com.xwad.os.bean.AppUpdateInfo; import com.xwad.os.bean.AriaDownloadInfo; import com.xwad.os.bean.HomeworkBean; +import com.xwad.os.bean.uiuios.AppUpdateInfo; import com.xwad.os.gson.GsonUtils; import java.io.File; diff --git a/app/src/main/java/com/xwad/os/utils/FileUtils.java b/app/src/main/java/com/xwad/os/utils/FileUtils.java new file mode 100644 index 0000000..c07e923 --- /dev/null +++ b/app/src/main/java/com/xwad/os/utils/FileUtils.java @@ -0,0 +1,326 @@ +package com.xwad.os.utils; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Environment; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.util.Log; + +import androidx.core.content.ContextCompat; + +import com.arialyy.aria.core.Aria; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.xwad.os.bean.AppInfo; +import com.xwad.os.bean.AriaDownloadInfo; +import com.xwad.os.bean.HomeworkBean; +import com.xwad.os.bean.uiuios.AppUpdateInfo; +import com.xwad.os.gson.GsonUtils; +import com.xwad.os.service.DownloadService; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.lang.reflect.Type; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.util.HashSet; + +public class FileUtils { + private static final String TAG = "FileUtil"; + + public static String getFileType(String url) { + if (url.indexOf("/") == -1) { + return url.substring(url.indexOf(".")); + } else { + String fileName = url.substring(url.lastIndexOf("/")); + return fileName.substring(fileName.indexOf(".")); + } + } + + public static boolean isLocalPath(String path) { + return path.startsWith(File.separator); + } + + private static HashSet videoFormat = new HashSet() {{ + this.add(".mp4"); + this.add(".avi"); + this.add(".nkv"); + this.add(".flv"); + }}; + private static HashSet pictureFormat = new HashSet() {{ + this.add(".png"); + this.add(".jpg"); + this.add(".jpeg"); + this.add(".bmp"); + }}; + + public static boolean isVideoFile(String fileName) { + if (TextUtils.isEmpty(fileName)) { + return false; + } else { + if (!fileName.startsWith(".")) { + return videoFormat.contains(getFileType(fileName)); + } else { + return videoFormat.contains(fileName); + } + } + } + + public static boolean isPictureFile(String fileName) { + if (TextUtils.isEmpty(fileName)) { + return false; + } else { + if (!fileName.startsWith(".")) { + return pictureFormat.contains(getFileType(fileName)); + } else { + return pictureFormat.contains(fileName); + } + } + } + + public static File uriToFile(Uri uri, Context context) { + String path = null; + if ("file".equals(uri.getScheme())) { + path = uri.getEncodedPath(); + if (path != null) { + path = Uri.decode(path); + ContentResolver cr = context.getContentResolver(); + StringBuffer buff = new StringBuffer(); + buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=").append("'" + path + "'").append(")"); + Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA}, buff.toString(), null, null); + int index = 0; + int dataIdx = 0; + for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) { + index = cur.getColumnIndex(MediaStore.Images.ImageColumns._ID); + index = cur.getInt(index); + dataIdx = cur.getColumnIndex(MediaStore.Images.ImageColumns.DATA); + path = cur.getString(dataIdx); + } + cur.close(); + if (index == 0) { + } else { + Uri u = Uri.parse("content://media/external/images/media/" + index); + System.out.println("temp uri is :" + u); + } + } + if (path != null) { + return new File(path); + } + } else if ("content".equals(uri.getScheme())) { + // 4.2.2以后 + String[] proj = {MediaStore.Images.Media.DATA}; + Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); + if (cursor.moveToFirst()) { + int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + path = cursor.getString(columnIndex); + } + cursor.close(); + + return new File(path); + } else { + //Log.i(TAG, "Uri Scheme:" + uri.getScheme()); + return new File(uri.toString()); + } + return null; + } + + /** + * drawable转为file + * + * @param drawableId drawable的ID + * @param fileName 转换后的文件名 + * @return + */ + public static File drawableToFile(Context context, int drawableId, String fileName) { +// InputStream is = view.getContext().getResources().openRawResource(R.drawable.logo); + Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableId); +// Bitmap bitmap = BitmapFactory.decodeStream(is); + String defaultPath = context.getFilesDir().getAbsolutePath() + "/defaultGoodInfo"; + File file = new File(defaultPath); + if (!file.exists()) { + file.mkdirs(); + } + String defaultImgPath = defaultPath + "/" + fileName; + file = new File(defaultImgPath); + try { + file.createNewFile(); + FileOutputStream fOut = new FileOutputStream(file); + bitmap.compress(Bitmap.CompressFormat.PNG, 20, fOut); +// is.close(); + fOut.flush(); + fOut.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return file; + } + + /** + * bitmap + * + * @param bitmap bitmap + * @param fileName 转换后的文件名 + * @return + */ + public static File bitmapToFile(Context context, Bitmap bitmap, String fileName) { + String defaultPath = context.getFilesDir().getAbsolutePath() + "/defaultGoodInfo"; + File file = new File(defaultPath); + if (!file.exists()) { + file.mkdirs(); + } + String defaultImgPath = defaultPath + "/" + fileName; + file = new File(defaultImgPath); + try { + file.createNewFile(); + FileOutputStream fOut = new FileOutputStream(file); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut); +// is.close(); + fOut.flush(); + fOut.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return file; + } + + + public static String getFileNamefromURL(String url) { + int position = url.lastIndexOf("/"); + return url.substring(position + 1); + } + + /** + * 获取单个文件的MD5值 + * + * @param file 文件 + * @return + */ + + public static String getFileMd5(File file) { + if (!file.isFile()) { + return ""; + } + MessageDigest digest = null; + FileInputStream in = null; + byte[] buffer = new byte[1024]; + int len; + try { + digest = MessageDigest.getInstance("MD5"); + in = new FileInputStream(file); + while ((len = in.read(buffer, 0, 1024)) != -1) { + digest.update(buffer, 0, len); + } + in.close(); + } catch (Exception e) { + e.printStackTrace(); + return ""; + } + BigInteger bigInt = new BigInteger(1, digest.digest()); + return bigInt.toString(32); + } + + public static String getDownLoadPath(Context context) { + String path = ContextCompat.getExternalFilesDirs(context, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath(); + return path + File.separator; + } + +// public static void ariaDownload(Context context, String url, AppDetails appDetails) { +// Log.e(TAG, "ariaDownload: " + appDetails); +// AriaDownloadInfo ariaDownloadInfo = AriaDownloadInfo.toAriaDownloadInfo(appDetails); +// ariaDownload(context, url, ariaDownloadInfo); +// } + + public static void ariaDownload(Context context, String url, AppInfo appInfo) { + Log.e(TAG, "ariaDownload: " + appInfo); + AriaDownloadInfo ariaDownloadInfo = AriaDownloadInfo.toAriaDownloadInfo(appInfo); + ariaDownload(context, url, ariaDownloadInfo); + } + + public static void ariaDownload(Context context, String url, AppUpdateInfo appUpdateInfo) { + Log.e(TAG, "ariaDownload: " + appUpdateInfo); + AriaDownloadInfo ariaDownloadInfo = AriaDownloadInfo.toAriaDownloadInfo(appUpdateInfo); + ariaDownload(context, url, ariaDownloadInfo); + } + + public static void ariaDownload(Context context, String url, JsonObject jsonObject) { + Log.e(TAG, "ariaDownload: " + jsonObject); + Gson gson = new Gson(); + Type type = new TypeToken() { + }.getType(); + AriaDownloadInfo ariaDownloadInfo = gson.fromJson(jsonObject, type); + ariaDownload(context, url, ariaDownloadInfo); + } + + public static void ariaDownload(Context context, String url, AriaDownloadInfo ariaDownloadInfo) { + Log.e(TAG, "ariaDownload: " + ariaDownloadInfo); + String fileName = getFileNamefromURL(url); + String app_md5 = ariaDownloadInfo.getAppMd5(); + Log.e("ariaDownload", "app_md5 = " + app_md5); + File file = new File(getDownLoadPath(context) + fileName); + if (file.exists() && !file.isDirectory()) { + String fileMd5 = com.blankj.utilcode.util.FileUtils.getFileMD5ToString(file); + Log.e("ariaDownload", "fileMD5 = " + fileMd5); + if (fileMd5.equalsIgnoreCase(app_md5)) { + ApkUtils.installApp(context, file.getAbsolutePath()); + } else { + file.delete(); + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(getDownLoadPath(context) + fileName) + .ignoreFilePathOccupy() + .setExtendField(GsonUtils.toJSONString(ariaDownloadInfo)) + .create(); //启动下载} + } + } else { + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(getDownLoadPath(context) + fileName) + .ignoreFilePathOccupy() + .setExtendField(GsonUtils.toJSONString(ariaDownloadInfo)) + .create(); //启动下载} + } + Intent intent = new Intent(context, DownloadService.class); +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { +// context.startForegroundService(intent); +// } else { + context.startService(intent); +// } + } + + public static void ariaDownloadTestPaper(Context context, String url, HomeworkBean homeworkBean) { + String fileName = getFileNamefromURL(url); + File file = new File(getDownLoadPath(context) + fileName); + if (file.exists() && !file.isDirectory()) { + Log.e(TAG, "ariaDownload: " + "file exists"); + } else { + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(getDownLoadPath(context) + fileName) + .ignoreFilePathOccupy() + .setExtendField(GsonUtils.toJSONString(homeworkBean)) + .create(); //启动下载} + } + } + + public static void ariaDownloadUrl(Context context, String url) { + String fileName = getFileNamefromURL(url); + File file = new File(getDownLoadPath(context) + fileName); + if (file.exists() && !file.isDirectory()) { + Log.e(TAG, "ariaDownload: " + "file exists"); + } else { + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(getDownLoadPath(context) + fileName) + .ignoreFilePathOccupy() + .create(); //启动下载} + } + } +} 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 new file mode 100644 index 0000000..aa402a1 --- /dev/null +++ b/app/src/main/java/com/xwad/os/utils/JgyUtils.java @@ -0,0 +1,1301 @@ +package com.xwad.os.utils; + +import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.ActivityTaskManager; +import android.app.role.RoleManager; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.UserInfo; +import android.content.res.Resources; +import android.media.AudioManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.os.PowerManager; +import android.os.Process; +import android.os.RemoteException; +import android.os.UserHandle; +import android.provider.Settings; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Log; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; + +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; + +import com.google.gson.JsonObject; +import com.hjq.toast.Toaster; +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.gson.GsonUtils; +import com.xwad.os.service.main.MainService; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +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 static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE; + + +public class JgyUtils { + private static final String TAG = "JgyUtils"; + + @SuppressLint("StaticFieldLeak") + private static JgyUtils sInstance; + private Context mContext; + private ContentResolver resolver; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + 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 HONOR_TAG = "HONOR"; + public static final String LENOVO_TAG = "lenovo"; + + + private HashSet ownApp = new HashSet() {{ + this.add("com.tt.ttutils"); + this.add(BuildConfig.APPLICATION_ID); + this.add("com.uiui.sn"); + this.add("com.appstore.uiui"); + this.add("com.alarmclock.uiui"); + this.add("com.android.uiuios"); + this.add("com.aoleyun.os"); + this.add("com.jiaoguanyi.appstore"); + this.add("com.jiaoguanyi.store"); + this.add("com.uiui.appstore"); + this.add("com.uiui.info"); + this.add("com.uiui.browser"); + this.add("com.uiui.health"); + this.add("com.uiui.videoplayer"); + this.add("com.uiui.os"); + this.add("com.aoleyunos.dop1"); + this.add("com.aoleyunos.dop2"); + this.add("com.uiui.aios"); + this.add("com.uiuios.jgy1"); + this.add("com.uiuios.jgy2"); + this.add("com.info.chat"); + this.add("com.info.learning"); + this.add("com.uiui.multios"); + this.add("com.uiui.city"); + }}; + + private HashSet fuxiaoyingApp = new HashSet() {{ + this.add(gkwxhd); + this.add(fuxiaoying); + this.add(moshujia); + this.add(english); + this.add(zhiduoke); + this.add(aobama); + this.add(growthspace); + }}; + + public static final String gkwxhd = "com.gankao.gkwxhd"; + public static final String fuxiaoying = "com.fuying.fuxiaoying"; + public static final String moshujia = "com.moshujiamm.moshujia"; + public static final String english = "com.fuying.english"; + public static final String zhiduoke = "com.zhiduoke.fxy"; + public static final String aobama = "com.fuying.aobama.pad"; + public static final String growthspace = "com.pengren.growthspace"; + + public static final String FUXIAOYING_KEY = "fuxiaoying_update_key"; + + + public HashSet getOwnApp() { + return ownApp; + } + + public HashSet getFXYApp() { + return fuxiaoyingApp; + } + + private JgyUtils(Context context) { + if (context == null) { + throw new RuntimeException("Context is NULL"); + } + this.mContext = context; + this.resolver = mContext.getContentResolver(); + } + + public static void init(Context context) { + if (sInstance == null) { + sInstance = new JgyUtils(context); + } + } + + public static JgyUtils getInstance() { + if (sInstance == null) { + throw new IllegalStateException("You must be init JgyUtils first"); + } + return sInstance; + } + + public static String getAuthorization() { + return "Basic ZWRmOWNlYzIyNzMxYjhiMmZlZDU2ZWU2OmIzYWRlZDRmODk5N2E0ODM5ZTI5MjRjYg=="; + } + + + public static boolean isOfficialVersion() { + String channelValue = JgyUtils.getInstance().getStringMetaData(); + return "official".equals(channelValue); + } + + public static boolean isNewlyVersion() { + String channelValue = JgyUtils.getInstance().getStringMetaData(); + return "beta".equals(channelValue); + } + + public static boolean isBetaVersion() { + String channelValue = JgyUtils.getInstance().getStringMetaData(); + return "beta".equals(channelValue); + } + + /** + * 从Manifest中获取meta-data值 + * https://blog.csdn.net/yue_233/article/details/91453451 + * + * @return MetaData + */ + public String getStringMetaData() { + ApplicationInfo appInfo = null; + try { + appInfo = mContext.getPackageManager().getApplicationInfo(mContext.getPackageName(), PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + String value = appInfo.metaData.getString("CHANNEL_VALUE"); + return value; + } + + private PowerManager.WakeLock wakeLock = null; + private static final String mWakeLockName = "BackupService"; + + /** + * 获取电源锁,保持该服务在屏幕熄灭时仍然获取CPU时,保持运行 + */ + @SuppressLint("InvalidWakeLockTag") + private synchronized void acquireWakeLock() { + if (null == wakeLock) { + PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK + | PowerManager.ON_AFTER_RELEASE, mWakeLockName); + if (null != wakeLock) { + Log.e("fht", "acquireWakeLock!"); + wakeLock.acquire(); + } + } + } + + /** + * 释放设备电源锁 + */ + private synchronized void releaseWakeLock() { + if (null != wakeLock) { + Log.e("fht", "releaseWakeLock!"); + wakeLock.release(); + wakeLock = null; + } + } + + /** + * 点亮屏幕 + * + * @param timeout The timeout after which to release the wake lock, in milliseconds. + */ + @Nullable + public static PowerManager.WakeLock acquireWakeLock(@androidx.annotation.NonNull Context context, long timeout) { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (pm == null) { + return null; + } + PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | + PowerManager.FULL_WAKE_LOCK | + PowerManager.ON_AFTER_RELEASE, + context.getClass().getName()); + wakeLock.acquire(timeout); + return wakeLock; + } + + public static void release(@Nullable PowerManager.WakeLock wakeLock) { + if (wakeLock != null && wakeLock.isHeld()) { + wakeLock.release(); + } + } + + public String getDownLoadPath() { + String path = ContextCompat.getExternalFilesDirs(mContext, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath(); + return path + File.separator; + } + + /** + * @param ids 需要管控的ID + * @param packages 应用程序包名 + */ + public void writeDeselectIDtoSystem(String ids, String packages) { + if (!TextUtils.isEmpty(ids) && !TextUtils.isEmpty(packages)) { + ArrayList idArrayList = new ArrayList<>(Arrays.asList(ids.split(","))); + ArrayList packageArrayList = new ArrayList<>(Arrays.asList(packages.split(","))); + LinkedHashSet idHashSet = new LinkedHashSet<>(idArrayList); + LinkedHashSet packageHashSet = new LinkedHashSet<>(packageArrayList); + ArrayList idList = new ArrayList<>(idHashSet); + ArrayList packageList = new ArrayList<>(packageHashSet); + StringBuilder idStringBuilder = new StringBuilder(); + for (String id : idList) { + if (idStringBuilder.length() > 0) { + idStringBuilder.append(","); + } + idStringBuilder.append(id); + } + StringBuilder packageStringBuilder = new StringBuilder(); + for (String pkg : packageList) { + if (packageStringBuilder.length() > 0) { + packageStringBuilder.append(","); + } + packageStringBuilder.append(pkg); + } + + } else { + + } + } + + + private void sendAllweb() { + Intent intent = new Intent("qch_app_website") + .setPackage("com.android.settings"); + intent.putExtra("package_name", ""); + mContext.sendBroadcast(intent); + } + + private void sendwebUrl() { + Intent intent = new Intent("qch_app_inside_website") + .setPackage("com.android.settings"); + intent.putExtra("websitelist", ""); + mContext.sendBroadcast(intent); + } + + /** + * 系统应用hook使用webview + */ + public static void hookWebView() { + int sdkInt = Build.VERSION.SDK_INT; + try { + Class factoryClass = Class.forName("android.webkit.WebViewFactory"); + Field field = factoryClass.getDeclaredField("sProviderInstance"); + field.setAccessible(true); + Object sProviderInstance = field.get(null); + if (sProviderInstance != null) { + Log.i(TAG, "sProviderInstance isn't null"); + return; + } + + Method getProviderClassMethod; + if (sdkInt > 22) { + getProviderClassMethod = factoryClass.getDeclaredMethod("getProviderClass"); + } else if (sdkInt == 22) { + getProviderClassMethod = factoryClass.getDeclaredMethod("getFactoryClass"); + } else { + Log.i(TAG, "Don't need to Hook WebView"); + return; + } + getProviderClassMethod.setAccessible(true); + Class factoryProviderClass = (Class) getProviderClassMethod.invoke(factoryClass); + Class delegateClass = Class.forName("android.webkit.WebViewDelegate"); + Constructor delegateConstructor = delegateClass.getDeclaredConstructor(); + delegateConstructor.setAccessible(true); + if (sdkInt < 26) {//低于Android O版本 + Constructor providerConstructor = factoryProviderClass.getConstructor(delegateClass); + if (providerConstructor != null) { + providerConstructor.setAccessible(true); + sProviderInstance = providerConstructor.newInstance(delegateConstructor.newInstance()); + } + } else { + Field chromiumMethodName = factoryClass.getDeclaredField("CHROMIUM_WEBVIEW_FACTORY_METHOD"); + chromiumMethodName.setAccessible(true); + String chromiumMethodNameStr = (String) chromiumMethodName.get(null); + if (chromiumMethodNameStr == null) { + chromiumMethodNameStr = "create"; + } + Method staticFactory = factoryProviderClass.getMethod(chromiumMethodNameStr, delegateClass); + if (staticFactory != null) { + sProviderInstance = staticFactory.invoke(null, delegateConstructor.newInstance()); + } + } + + if (sProviderInstance != null) { + field.set("sProviderInstance", sProviderInstance); + Log.i(TAG, "Hook success!"); + } else { + Log.i(TAG, "Hook failed!"); + } + } catch (Throwable e) { + Log.w(TAG, e); + } + } + + + /** + * 忽略电池优化 + */ + private void ignoreBatteryOptimization() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + + PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + + boolean hasIgnored = powerManager.isIgnoringBatteryOptimizations(mContext.getPackageName()); + // 判断当前APP是否有加入电池优化的白名单,如果没有,弹出加入电池优化的白名单的设置对话框。 + if (!hasIgnored) { + Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); + intent.setData(Uri.parse("package:" + mContext.getPackageName())); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mContext.startActivity(intent); + } + } + } + + public void KillOTA() { + ActivityManager manager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + manager.killBackgroundProcesses("com.adups.fota"); + CmdUtil.execute("am force-stop " + "com.adups.fota"); + } + + private static final String COlORFLY_OTA_PACKAGE_NAME = "com.adups.fota"; + private static final String COlORFLY_OTA_CLASS_NAME = "com.adups.fota.GoogleOtaClient"; + + private static final String CUBE_UNISOC_OTA_PACKAGE_NAME = "com.cube.update"; + private static final String CUBE_UNISOC_OTA_CLASS_NAME = "com.cube.update.GoogleOtaClient"; + + private static final String CUBE_MTK_OTA_PACKAGE_NAME = "com.droi.ota"; + private static final String CUBE_MTK_OTA_CLASS_NAME = "com.droi.ota.GoogleOtaClient"; + + private static final String CUBE_ABF_OTA_PACKAGE_NAME = "com.abfota.systemUpdate"; + private static final String CUBE_ABF_OTA_CLASS_NAME = "com.redstone.ota.ui.activity.RsMainActivity"; + + public void openJgyOta() { + openComponentNameApp(COlORFLY_OTA_PACKAGE_NAME, COlORFLY_OTA_CLASS_NAME); + } + + public void openCubeOta() { + if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONOR_PLATFORM + ) { + openCubeUnisocOta(); +// } else if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.MTKPlatform) { +// openCubeMtkOta(); +// } else if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.iPlay50miniProPlatform) { +// openCubeAbfOta(); + } + } + + public void openCubeUnisocOta() { + openComponentNameApp(CUBE_UNISOC_OTA_PACKAGE_NAME, CUBE_UNISOC_OTA_CLASS_NAME); + } + + public void openCubeMtkOta() { + openComponentNameApp(CUBE_MTK_OTA_PACKAGE_NAME, CUBE_MTK_OTA_CLASS_NAME); + } + + public void openCubeAbfOta() { + openComponentNameApp(CUBE_ABF_OTA_PACKAGE_NAME, CUBE_ABF_OTA_CLASS_NAME); + } + + private void openComponentNameApp(String pkgName, String className) { + Intent intent = new Intent(Intent.ACTION_MAIN); + ComponentName componentName = new ComponentName(pkgName, className); + intent.setComponent(componentName); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + mContext.startActivity(intent); + } catch (Exception e) { + Log.e(TAG, "openComponentNameApp: " + e.getMessage()); + Toaster.show("打开失败"); + } + } + + public void openLauncher() { + Log.e(TAG, "openLauncher: "); +// AdminManager.getInstance().killApplicationProcess("com.android.launcher3"); + Intent intent = new Intent(); + // 为Intent设置Action、Category属性 + intent.setAction(Intent.ACTION_MAIN);// "android.intent.action.MAIN" + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addCategory(Intent.CATEGORY_HOME); //"android.intent.category.HOME" + mContext.startActivity(intent); + } + + public void cleanLauncherCache() { + Log.e(TAG, "cleanLauncherCache: Start"); + int cleaned = mMMKV.decodeInt("fristcleanLauncherCache", 0); + if (cleaned == 0) { +// AdminManager.getInstance().clearPackageData("com.android.launcher3"); + mMMKV.encode("fristcleanLauncherCache", 1); + Log.e(TAG, "cleanLauncherCache: end"); + } + } + + public int checkAppPlatform() { + String platform = BuildConfig.platform; + if (HONOR_TAG.equalsIgnoreCase(platform)) { + Log.i(TAG, "checkAppPlatform: " + "honer"); + return HONOR_PLATFORM; + } else if (LENOVO_TAG.equalsIgnoreCase(platform)) { + Log.i(TAG, "checkAppPlatform: " + "6gen1s"); + return LENOVO_PLATFORM; + } else { + Log.i(TAG, "checkAppPlatform: " + "没有数据"); + return UNKNOW_PLATFORM; + } + } + + public interface GetAppPlatformCallback { + void AppPlatform(int platform); + } + + public void getAppPlatform(GetAppPlatformCallback getAppPlatformCallback) { + String platform = BuildConfig.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.HONOR_PLATFORM + ) { + return getProperty("ro.build.display.id", "获取失败"); + } else { + return getProperty("ro.custom.build.version", "获取失败"); + } + } + + public static String getRomVersion() { + if (JgyUtils.getInstance().checkAppPlatform() == JgyUtils.HONOR_PLATFORM + ) { + return getProperty("ro.build.id", "获取失败"); + } else { + return getProperty("ro.build.display.id", "获取失败"); + } + } + + /** + * 获取系统配置信息 + * + * @param key + * @param defaultValue + * @return + */ + public static String getProperty(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, "unknown")); + } catch (Exception e) { + e.printStackTrace(); + } finally { + return value; + } + } + + public void killBackgroundApp(Context context) { + List pkgList = ApkUtils.queryFilterAppList(context); + for (String pkg : pkgList) { + if (runningAppWhitelist.contains(pkg)) continue; +// AdminManager.getInstance().killApplicationProcess(pkg); +// killBackgroundProcesses(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"); + }}; + + public void killBackgroundProcesses2(String packageName) { + ActivityManager activityManager; + try { + activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + activityManager.killBackgroundProcesses(packageName); + Method forceStopPackage = activityManager.getClass() + .getDeclaredMethod("forceStopPackage", String.class); +// Log.e(TAG, "killBackgroundProcesses: " + packageName); + forceStopPackage.setAccessible(true); + forceStopPackage.invoke(activityManager, packageName); + } catch (Exception e) { + Log.e(TAG, "killBackgroundProcesses: " + e.getMessage()); + e.printStackTrace(); + } + } + + @Deprecated + public void killBackgroundProcesses(String processName) { +// gotoLauncher(); + // mIsScanning = true; + removeTask(processName); + ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + String packageName = null; + try { + if (processName.indexOf(":") == -1) { + packageName = processName; + } else { + packageName = processName.split(":")[0]; + } + activityManager.killBackgroundProcesses(packageName); + // + Method forceStopPackage = activityManager.getClass() + .getDeclaredMethod("forceStopPackage", String.class); + forceStopPackage.setAccessible(true); + forceStopPackage.invoke(activityManager, packageName); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 清除所有最近记录 + */ + public void removeAllTask() { + List list = getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), getCurrentUserId()); + + for (ActivityManager.RecentTaskInfo info : list) { + if (info.realActivity != null) { + Log.e(TAG, "removeAllTask: " + info.realActivity.getPackageName()); + //排除自身 + if (BuildConfig.APPLICATION_ID.equals(info.realActivity.getPackageName())) { + continue; + } + } + try { + ActivityManagerNative.getDefault().removeTask(info.id); + } catch (RemoteException e) { + e.printStackTrace(); + Log.e(TAG, "removeAllTask: " + e.getMessage()); + } + } + } + + public void removeTask(String packageName) { + List list = getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), getCurrentUserId()); + HashMap taskMap = new HashMap<>(); + for (ActivityManager.RecentTaskInfo info : list) { + taskMap.put(info.realActivity.getPackageName(), info.id); + } + try { + ActivityManagerNative.getDefault().removeTask(taskMap.get(packageName)); + } catch (RemoteException e) { + e.printStackTrace(); + Log.e(TAG, "removeTask: " + e.getMessage()); + } catch (NullPointerException e) { + Log.e(TAG, "removeTask: " + e.getMessage()); + } + } + + /** + * 如果界面正在最近任务列表,有些app可能不会被清理 + */ + public void gotoLauncher() { + Intent i = new Intent(Intent.ACTION_MAIN); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //android123提示如果是服务里调用,必须加入new task标识 + i.addCategory(Intent.CATEGORY_HOME); + mContext.startActivity(i); + } + + + /** + * @return a list of the recents tasks. + * 获取近期任务列表 + */ + public List getRecentTasks(int numTasks, int userId) { + try { + return ActivityTaskManager.getService().getRecentTasks(numTasks, + RECENT_IGNORE_UNAVAILABLE, userId).getList(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to get recent tasks", e); + return new ArrayList<>(); + } + } + + /** + * @return the current user's id. + * 获取userId + */ + public int getCurrentUserId() { + UserInfo ui; + try { + ui = ActivityManager.getService().getCurrentUser(); + return ui != null ? ui.id : 0; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + public int isWifiConnect() { + // 网络管理对象 + ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + // 获取所有类型的链接管理对象 + NetworkInfo info = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI); + NetworkInfo.State state = info.getState(); + if (NetworkInfo.State.CONNECTED == state) { + return 1; + } + return 0; + } + +// synchronized public static int getInt(ContentResolver cr, String name, int def) { +// Log.i(TAG, "getInt: " + name); +// return Settings.System.getInt(cr, name, def); +// } +// +// synchronized public static int getInt(ContentResolver cr, String name) throws Settings.SettingNotFoundException { +// Log.i(TAG, "getInt: " + name); +// return Settings.System.getInt(cr, name); +// } +// +// synchronized public static String getString(ContentResolver cr, String name) { +// Log.i(TAG, "getString: " + name); +// return Settings.System.getString(cr, name); +// } +// +// synchronized public static boolean putInt(ContentResolver cr, String name, int value) { +// Log.i(TAG, "putInt: " + "name = " + name + ", value = " + value); +// return Settings.System.putInt(cr, name, value); +// } +// +// synchronized public static boolean putString(ContentResolver cr, String name, String value) { +// Log.i(TAG, "putString: " + "name = " + name + ", value = " + value); +// return Settings.System.putString(cr, name, value); +// } + + /** + * 获取当前进程名 + */ + public String getCurrentProcessName() { + int pid = Process.myPid(); + String processName = ""; + ActivityManager manager = (ActivityManager) mContext.getSystemService + (Context.ACTIVITY_SERVICE); + for (ActivityManager.RunningAppProcessInfo process : manager.getRunningAppProcesses()) { + if (process.pid == pid) { + processName = process.processName; + } + } + return processName; + } + + private String Launcher3 = "com.android.launcher3"; + private String Launcher3Class = "com.android.launcher3.Launcher"; + + public void setDefaultLauncher(Context context, String defPackageName, String defClassName) { + try { + if (!TextUtils.isEmpty(defPackageName) && !TextUtils.isEmpty(defClassName)) { + IntentFilter filter = new IntentFilter(); + filter.addAction("android.intent.action.MAIN"); + filter.addCategory("android.intent.category.HOME"); + filter.addCategory("android.intent.category.DEFAULT"); + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + // 返回给定条件的所有ResolveInfo对象(本质上是Activity) + List list = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); + int bestMatch = 0; + final int size = list.size(); + ComponentName[] set = new ComponentName[size]; + for (int i = 0; i < size; i++) { + ResolveInfo ri = list.get(i); + set[i] = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name); + if (ri.match > bestMatch) { + bestMatch = ri.match; + } + } + ComponentName preActivity = new ComponentName(defPackageName, defClassName); + context.getPackageManager().addPreferredActivity(filter, bestMatch, set, preActivity); + } + } catch (SecurityException e) { + e.printStackTrace(); + Log.e(TAG, "setDefaultLauncher: " + e.getMessage()); + } + } + + public void setRoleHolderAsUser(Context context, String packageName) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + String roleName = "android.app.role.HOME"; + boolean add = true; + int flags = 0; + UserHandle user = Process.myUserHandle(); + Log.i("settingssssssstemf", (add ? "Adding" : "Removing") + " package as role holder, role: " + + roleName + ", package: " + packageName); +// if (JgyUtils.getInstance().checkAppPlatform() != JgyUtils.MTKPlatform) { + RoleManager roleManager = context.getSystemService(RoleManager.class); + Executor executor = context.getMainExecutor(); + Consumer callback = successful -> { + if (successful) { + Log.d("settingssssssstemf", "Package " + (add ? "added" : "removed") + + " as role holder, role: " + roleName + ", package: " + packageName); + } else { + Log.d("settingssssssstemf", "Failed to " + (add ? "add" : "remove") + + " package as role holder, role: " + roleName + ", package: " + + packageName); + } + }; + roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback); + Log.i("settingssssssstemf", "addRoleHolderAsUser done"); +// } + } + } + + public void checkDefaultDesktop(String pkg) { + String desktopPkg = mMMKV.decodeString("default_launcher", ""); + Log.e(TAG, "checkDefaultDesktop: " + desktopPkg); + if (desktopPkg.equalsIgnoreCase(pkg)) { + setDefaultDesktop(pkg); + } + } + + //设置默认桌面 + public void setDefaultDesktop(String pkg) { + Log.e(TAG, "setDefaultDesktop: " + pkg); + if (TextUtils.isEmpty(pkg)) { + openLauncher3(); + } else { + String className = getStartClassName(pkg); + if (TextUtils.isEmpty(className)) { + openLauncher3(); + } else { +// AdminManager.getInstance().setDefaultLauncher(pkg, className); + } + } + } + + private void openLauncher3() { +// AdminManager.getInstance().setDefaultLauncher(Launcher3, Launcher3Class); +// ApkUtils.openPackage(mContext, Launcher3); + } + + public String getStartClassName(String pkg) { + PackageInfo packageInfo = null; + try { + packageInfo = mContext.getPackageManager().getPackageInfo(pkg, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo == null) { + return ""; + } else { + // 创建一个类别为CATEGORY_LAUNCHER的该包名的Intent + Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); + resolveIntent.addCategory(Intent.CATEGORY_HOME); + resolveIntent.setPackage(packageInfo.packageName); + + // 通过getPackageManager()的queryIntentActivities方法遍历 + List resolveinfoList = mContext.getPackageManager() + .queryIntentActivities(resolveIntent, 0); + if (resolveinfoList == null || resolveinfoList.size() == 0) { + return ""; + } + + ResolveInfo resolveinfo = resolveinfoList.iterator().next(); + if (resolveinfo != null) { + // packagename = 参数packname + String packageName = resolveinfo.activityInfo.packageName; + // 这个就是我们要找的该APP的LAUNCHER的Activity[组织形式:packagename.mainActivityname] + String className = resolveinfo.activityInfo.name; + return className; + } else { + return ""; + } + } + } + + public boolean isDefaultLauncher(String pkg, String className) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(intent, 0); + if (resolveInfo != null && resolveInfo.activityInfo != null) { + Log.e(TAG, "isDefaultLauncher: pkg = " + resolveInfo.activityInfo.packageName); + Log.e(TAG, "isDefaultLauncher: class = " + resolveInfo.activityInfo.name); + return pkg.equals(resolveInfo.activityInfo.packageName) && className.equals(resolveInfo.activityInfo.name); + } + return false; + } + + public void setDefaultDesktop(String pkg, String className) { +// if (!isDefaultLauncher(pkg, className)) { +// AdminManager.getInstance().setDefaultLauncher(pkg, className); +// } else { +// Log.e(TAG, "setDefaultDesktop: pkg = already set default luancher"); +// } +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { +// setRoleHolderAsUser(mContext, pkg); +// Log.e(TAG, "setDefaultDesktop: setRoleHolderAsUser"); +// } else { +// //爱华设置,暂时屏蔽 +//// setDefaultLauncher(mContext, pkg, className); +// Log.e(TAG, "setDefaultDesktop: setDefaultLauncher"); +// } +//// String oldDesktop = (String) mMMKV.get(mContext, "default_launcher", ""); +//// if (Objects.equals(oldDesktop, pkg)) { +//// Log.e(TAG, "setDefaultDesktop: " + "数据一致"); +//// return; +//// } +// Intent intent = new Intent("setDefaultLauncher"); +// intent.putExtra("package", pkg); +// intent.putExtra("className", className); +// +//// if (JgyUtils.getInstance().checkAppPlatform() == MTKPlatform) { +//// Log.e(TAG, "setDefaultDesktop: MTK"); +//// //爱华定制 +//// intent.setComponent(new ComponentName("com.android.settings", "com.android.settings.AoleReceiver")); +//// // TODO: 2022/7/6 有问题 +//// setDefaultLauncher(mContext, "com.android.transfer", "com.android.transfer.MainActivity"); +//// SystemProperties.set("persist.sys.launcher.pkgname", pkg); +//// SystemProperties.set("persist.sys.launcher.classname", className); +//// } +// +// intent.setPackage("com.android.settings"); +// mContext.sendBroadcast(intent); +//// ApkUtils.openPackage(mContext, pkg); +// Log.e(TAG, "setDefaultDesktop: " + pkg + ":" + className); +// Log.e(TAG, "setDefaultDesktop: " + "persist.sys.launcher.pkgname = " + SystemProperties.get("persist.sys.launcher.pkgname")); +// Log.e(TAG, "setDefaultDesktop: " + "persist.sys.launcher.classname = " + SystemProperties.get("persist.sys.launcher.classname")); + } + +// public void setDefaultDesktop(String pkg, String className) { +// Intent intent = new Intent("setDefaultLauncher"); +// intent.putExtra("package", pkg); +// intent.putExtra("className", className); +// intent.setPackage("com.android.settings"); +// mContext.sendBroadcast(intent); +// } + + public ArrayList getForbidList() { + ArrayList disableApp = new ArrayList<>(); + int search_topic = mMMKV.decodeInt("search_topic", 0); + Log.e(TAG, "getForbidList: search_topic = " + search_topic); + Log.e(TAG, "getForbidList: " + GsonUtils.toJSONString(mMMKV.allKeys())); + + return disableApp; + } + + private static final String UPDATE_FORBID_APP = "UPDATE_FORBID_APP"; + + public void updateForbidList() { + Intent intent = new Intent(UPDATE_FORBID_APP); + intent.putStringArrayListExtra("forbid_app_list", getForbidList()); + Log.e(TAG, "updateForbidList: " + getForbidList()); +// intent.setComponent(new ComponentName("com.jiaoguanyi.os","com.jiaoguanyi.os.view.MainActivity")); + intent.setPackage("com.jiaoguanyi.os"); +// intent.setPackage("com.tt.ttutils"); + mContext.sendBroadcast(intent); + } + + public ArrayList getHideList() { + String appString = mMMKV.decodeString("Hide_APP_List", ""); + Log.e(TAG, "Hide_APP_List: " + appString); + if (TextUtils.isEmpty(appString)) { + return new ArrayList<>(); + } else { + return new ArrayList<>(Arrays.asList(appString.split(","))); + } + } + + private static final String UPDATE_HIDE_APP = "UPDATE_HIDE_APP"; + + public void updateHideList() { + Intent intent = new Intent(UPDATE_HIDE_APP); + intent.putStringArrayListExtra("hide_app_list", getHideList()); +// intent.setComponent(new ComponentName("com.jiaoguanyi.os","com.jiaoguanyi.os.view.MainActivity")); + intent.setPackage("com.jiaoguanyi.os"); +// intent.setPackage("com.tt.ttutils"); + mContext.sendBroadcast(intent); + } + + + @SuppressLint("NewApi") + synchronized public void setAppNetwork(HashSet blackList) { + + } + + @SuppressLint("NewApi") + synchronized public void onBootSendNetwork() { + String oldBlackListString = mMMKV.decodeString(CommonConfig.AOLE_ACTION_NETWORK_DISALLOW, ""); + HashSet oldBlackListSet = new HashSet<>(Arrays.asList(oldBlackListString.split(","))); + Log.e(TAG, "setAppNetwork: oldBlackListSet: " + oldBlackListSet); + oldBlackListSet.removeIf(s -> TextUtils.isEmpty(s.trim())); + for (String pkg : oldBlackListSet) { + if (TextUtils.isEmpty(pkg)) continue; + if (!ApkUtils.isAvailable(mContext, pkg)) { + Log.e(TAG, "setAppNetwork: skip: " + pkg); + continue; + } + Intent netControlNotIntent = new Intent(CommonConfig.AOLE_ACTION_NETWORK_DISALLOW); + netControlNotIntent.putExtra("package_name", pkg); + netControlNotIntent.setPackage("com.android.settings"); + mContext.sendBroadcast(netControlNotIntent); + } + } + + //删除用户除了在应用市场的其他应用 + @Deprecated + public void deleteOtherApp() { + + } + + public boolean isScreenOn() { + PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + //true为打开,false为关闭 + return powerManager.isInteractive(); + } + +// private int zenModOn = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; +// private int zenModOff = Settings.Global.ZEN_MODE_OFF; +// private String ZENNODETAG = "ZenModeSettingsBackend"; +// +// public void setZenMode(String extras) { +// JsonObject jsonObject = GsonUtils.getJsonObject(extras); +// int setting_disturbance = jsonObject.get("setting_disturbance").getAsInt(); +// NotificationManager.from(mContext).setZenMode(setting_disturbance, null, ZENNODETAG); +// } +// +// public void setRotationLock(String extras) { +// JsonObject jsonObject = GsonUtils.getJsonObject(extras); +// int setting_rotation = jsonObject.get("setting_rotation").getAsInt(); +// RotationPolicy.setRotationLock(mContext, setting_rotation == 0); +// } + + public void setScreenBrightness(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + int setting_luminance = jsonObject.get("setting_luminance").getAsInt(); + Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); + int Scrern_brightness = (int) ((1.0 * 255 / 100) * setting_luminance); + Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS, Scrern_brightness); + } + + private float[] mValues; + /** + * Index of the entry corresponding to current value of the settings. + */ + protected int mCurrentIndex; + /** + * List of entries corresponding the settings being set. + */ + protected List mEntries; + + public void setFontSize(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + String setting_typeface = jsonObject.get("setting_typeface").getAsString(); + final Resources res = mContext.getResources(); + mEntries = Arrays.asList(res.getStringArray(R.array.entries_font_size)); + final String[] strEntryValues = res.getStringArray(R.array.entryvalues_font_size); + mValues = new float[strEntryValues.length]; + for (int i = 0; i < strEntryValues.length; ++i) { + mValues[i] = Float.parseFloat(strEntryValues[i]); + } + mCurrentIndex = mEntries.indexOf(setting_typeface); + if (mCurrentIndex == -1) { + return; + } + Settings.System.putFloat(resolver, Settings.System.FONT_SCALE, mValues[mCurrentIndex]); + } + + public void setVolume(String extras) { + JsonObject jsonObject = GsonUtils.getJsonObject(extras); + int setting_volume = jsonObject.get("setting_volume").getAsInt(); + //获取系统的Audio管理者 + AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + //最大音量 + int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + //当前音量 +// int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); + int currentVolume = (int) ((1.0f * maxVolume / 100) * setting_volume); + mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, 0); + } + + public void setDefaultLauncher(String pkg) { + Intent intent = new Intent("setDefaultLauncher"); + intent.putExtra("package", "com.uiui.os"); + intent.putExtra("className", "com.uiui.os.Launcher"); + intent.setPackage("com.android.settings"); + mContext.sendBroadcast(intent); + } + + public void getLauncherClassName(String pkg) { + + } + + public String getInputMethodId(String pkg) { + InputMethodManager imeManager = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE); + List InputMethods = imeManager.getInputMethodList(); + Map inputMap = new HashMap<>(); + for (InputMethodInfo inputMethodInfo : InputMethods) { + inputMap.put(inputMethodInfo.getPackageName(), inputMethodInfo.getId()); + } + String id = inputMap.get(pkg); + Log.e(TAG, "getInputMethodId: " + id); + return id; + } + + public void setDefaultInputMethod(String pkg) { + String id = getInputMethodId(pkg); + if (TextUtils.isEmpty(id)) { + Log.e(TAG, "setDefaultInputMethod: id is empty"); + return; + } + Intent intent = new Intent("setDefaultInputMethod"); + intent.putExtra("package", id); + intent.setPackage("com.android.settings"); + mContext.sendBroadcast(intent); + } + + public void setDefaultBrowser(String pkg) { + Intent intent = new Intent("setDefaultBrowser"); + intent.putExtra("package", pkg); + intent.setPackage("com.android.settings"); + mContext.sendBroadcast(intent); + } + + + /*AI健康*/ + public static final String AIHealth = "com.uiui.health"; + /*同城服务*/ + public static final String CityService = "com.uiui.city"; + /*消息通知*/ + public static final String Notifications = "com.uiui.info"; + + public static final String PACKAGE_BROWSER = "com.uiui.browser"; + public static final String PACKAGE_VIDEOPLAYER = "com.uiui.videoplayer"; + public static final String PACKAGE_OS = "com.uiui.aios"; + public static final String PACKAGE_CALENDAR = "com.uiui.calendar"; + + public static final String CUBE_ZY_LAUNCHER = "com.uiui.zyos"; + public static final String CubeZYSN = "com.uiui.zy"; + + public static final String PACKAGE_DEVICEINFO = "com.uiui.sn"; + public static final String PACKAGE_APPSTORE = "com.uiui.appstore"; + public static final String PACKAGE_UPDATETOOLS = "com.uiui.updatetools"; + + public static final String CLASS_DEVICEINFO = "com.uiui.sn.receiver.BootReceiver"; + public static final String CLASS_APPSTORE = "com.uiui.appstore.receiver.BootReceiver"; + public static final String CLASS_UPDATETOOLS = "com.uiui.updatetools.receiver.BootReceiver"; + + public void wakeUpDeviceInfo() { + //启动设备信息 +// Intent bootIntent = new Intent(BootReceiver.BOOT_COMPLETED); +// bootIntent.setComponent(new ComponentName(PACKAGE_DEVICEINFO, CLASS_DEVICEINFO)); +// mContext.sendBroadcast(bootIntent); + } + + public void wakeUpAppstore() { + //启动应用市场 +// Intent bootIntent = new Intent(BootReceiver.BOOT_COMPLETED); +// bootIntent.setComponent(new ComponentName(PACKAGE_APPSTORE, CLASS_APPSTORE)); +// mContext.sendBroadcast(bootIntent); + } + + public void wakeUpUpdateTools() { + //启动升级组件 +// Intent bootIntent = new Intent(BootReceiver.BOOT_COMPLETED); +// bootIntent.setComponent(new ComponentName(PACKAGE_UPDATETOOLS, CLASS_UPDATETOOLS)); +// mContext.sendBroadcast(bootIntent); + } + + /** + * 判断网络连接状态 + * + * @return true:网络已链接, false:网络已断开连接 + */ + public boolean isNetworkConnected() { + if (mContext != null) { + ConnectivityManager mConnectivityManager = (ConnectivityManager) mContext + .getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo mNetworkInfo = mConnectivityManager + .getActiveNetworkInfo(); + if (mNetworkInfo != null) { + return mNetworkInfo.isAvailable(); + } + } + return false; + } + + + public String getIMEI() { + String IMEI = "unknown"; + String IMEI1, IMEI2, IMEI3; + //获取手机设备号 + TelephonyManager TelephonyMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + //8.0及以后版本获取 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + IMEI = TelephonyMgr.getDeviceId(); + } 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(mContext.getContentResolver(), Settings.Secure.ANDROID_ID); + } +// Log.e("IMEI:", "IMEI: " + IMEI); + if (null == IMEI) { + return "-"; + } else { + return IMEI.toUpperCase(); + } + } + + public String getPushMac() { + String macaddr = Utils.getAndroid10MAC(mContext); + return macaddr.replace(":", "").toUpperCase(); + } + + private static final String AOLE_DIR = "uiuiapp"; + + public void checkLocalExternalFiles() { + int install = mMMKV.decodeInt(CommonConfig.INSTALL_SD_APKS, 0); + Log.e(TAG, "checkLocalExternalFiles: installed = " + install); + if (install == 1) { + Log.e(TAG, "checkLocalExternalFiles: install"); +// return; + } + File[] externalFiles = mContext.getExternalFilesDirs(null); + Log.e(TAG, "checkLocalAppInstall: externalFiles = " + Arrays.toString(externalFiles)); + + String SdPath = Environment.getExternalStorageDirectory().getAbsolutePath(); + Log.e(TAG, "checkLocalAppInstall: SdPath = " + SdPath); + String aolePath = SdPath + File.separator + AOLE_DIR; + File file = new File(aolePath); + String[] apkName = file.list(); + if (apkName == null || apkName.length == 0) { + Log.e(TAG, "checkLocalAppInstall: apkName is empty"); + } else { + Observable.create(new ObservableOnSubscribe>() { + @Override + public void subscribe(@NonNull ObservableEmitter> emitter) throws Throwable { + HashMap packageListMap = new HashMap<>(); + for (String fileName : apkName) { + String apkPath = aolePath + File.separator + fileName; + Log.e(TAG, "subscribe: " + apkPath); + String pkg = ApkUtils.getPackageName(mContext, apkPath); + if (mJxwApps.contains(pkg)) { + packageListMap.put(pkg, apkPath); + } else { + Log.e(TAG, "checkLocalAppInstall: skip: " + pkg + " fileName: " + fileName); + } + } + emitter.onNext(packageListMap); + emitter.onComplete(); + } + }).subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("checkLocalAppInstall", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull HashMap stringStringHashMap) { + Log.e("checkLocalAppInstall", "onNext: " + stringStringHashMap); + stringStringHashMap.forEach(new BiConsumer() { + @Override + public void accept(String key, String value) { + if (ApkUtils.isAvailable(mContext, key)) { + Log.e("checkLocalAppInstall", "accept: installed: " + key); + } else { + ApkUtils.installApp(mContext, value); + } + } + }); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("checkLocalAppInstall", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("checkLocalAppInstall", "onComplete: "); + mMMKV.encode(CommonConfig.INSTALL_SD_APKS, 1); + } + }); + } + } + + public void startServices() { + Log.e(TAG, "startServices: "); + boolean noti = mMMKV.decodeBool(CommonConfig.ALLOW_NOTIFICATION, true); + 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)); +// } +// } + } + + private Set mJxwApps = new HashSet() {{ + this.add("com.uiui.sn"); + this.add("com.uiui.appstore"); + this.add("com.uiui.browser"); + this.add("com.uiui.videoplayer"); + }}; +} 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/OpenApkUtils.java b/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java index 1521fa8..ee45cd2 100644 --- a/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java +++ b/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java @@ -804,6 +804,7 @@ public class OpenApkUtils { // 4. 启动Activity(处理异常) try { activity.startActivity(intent); + sendRuningApp(packageName); } catch (Exception e) { if (e instanceof android.content.ActivityNotFoundException) { Log.e(TAG, "未找到目标Activity:" + packageName + "/" + className); @@ -917,7 +918,7 @@ public class OpenApkUtils { Log.e("getAppInfo", "onNext: " + baseResponse); if (baseResponse.code == 200) { AppInfo appInfo = baseResponse.data; - FileUtil.ariaDownload(mContext, appInfo.getApp_url(), appInfo); + FileUtils.ariaDownload(mContext, appInfo.getApp_url(), appInfo); } else { Toaster.showLong("没有找到应用信息,请联系客服"); } 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 9ba673d..d610e49 100644 --- a/app/src/main/java/com/xwad/os/utils/TimeUtils.java +++ b/app/src/main/java/com/xwad/os/utils/TimeUtils.java @@ -15,6 +15,7 @@ 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; @@ -541,10 +542,9 @@ public class TimeUtils { 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); + Intent intent = new Intent(); + intent.setAction(ManagerService.ACTION_UPDATE); + context.sendBroadcast(intent); } /** 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 2835af7..3a071b9 100644 --- a/app/src/main/java/com/xwad/os/utils/Utils.java +++ b/app/src/main/java/com/xwad/os/utils/Utils.java @@ -1,6 +1,9 @@ package com.xwad.os.utils; -import android.app.Activity; +import android.Manifest; +import android.app.ActivityManager; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.content.ComponentName; import android.content.Context; import android.content.ContextWrapper; @@ -13,37 +16,59 @@ 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; +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.xwad.os.BuildConfig; +import com.tencent.mmkv.MMKV; import com.xwad.os.R; -import com.xwad.os.manager.RemoteManager; +import com.xwad.os.config.CommonConfig; +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; 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"; @@ -102,33 +127,235 @@ public class Utils { return width + "×" + height; } - public static String getDeviceSN() { - String serial = null; + /** + * @return 序列号 + */ + public static String getSerial(Context context) { + String serialNumber = "unknow"; try { - Class c = Class.forName("android.os.SystemProperties"); - Method get = c.getMethod("get", String.class); - serial = (String) get.invoke(c, "persist.sys.hrSerial"); + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+ + serialNumber = Build.getSerial(); + } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+ + serialNumber = Build.SERIAL; + } else {//8.0- + Class c = Class.forName("android.os.SystemProperties"); + Method get = c.getMethod("get", String.class); + serialNumber = (String) get.invoke(c, "ro.serialno"); + } + } } catch (Exception e) { e.printStackTrace(); + Log.e("getSerial", "读取设备序列号异常:" + e.toString()); } - return serial; + return serialNumber; + } + + public static String getSerial() { + String serialNumber = "unknow"; + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+ + serialNumber = Build.getSerial(); + } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+ + serialNumber = Build.SERIAL; + } else {//8.0- + Class c = Class.forName("android.os.SystemProperties"); + Method get = c.getMethod("get", String.class); + serialNumber = (String) get.invoke(c, "ro.serialno"); + } + } catch (Exception e) { + e.printStackTrace(); + Log.e("getSerial", "读取设备序列号异常:" + e.toString()); + } + return serialNumber; } /** - * 获取电量 - * - * @param mContext + * @param context 获取真实的MAC地址 * @return */ - synchronized public static int getBatteryLevel(Context mContext) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - return ((BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE)).getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); + public static String getAndroid10MAC(Context context) { +// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) { +// return getMacAddress(context); +// } else { +// return getAndroid7MAC(); +// } + return getAllMacAddress(context); + } + + /** + * 获取MAC地址 + * + * @param context + * @return + */ + public static String getAllMacAddress(Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return getMacDefault(context); + } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + return getMacAddressM(); } else { - Intent intent = (new ContextWrapper(mContext)).registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - return intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100); + return getMacFromHardware(); } } + /** + * Android 6.0 之前(不包括6.0) + * + * @param context + * @return + */ + private static String getMacDefault(Context context) { + String mac = "未获取到设备Mac地址"; + if (context == null) { + return mac; + } + WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + WifiInfo info = null; + try { + info = wifi.getConnectionInfo(); + } catch (Exception e) { + e.printStackTrace(); + } + if (info == null) { + return mac; + } + mac = info.getMacAddress(); + if (!TextUtils.isEmpty(mac)) { + mac = mac.toUpperCase(Locale.ENGLISH); + } + + return mac; + } + + /** + * Android 6.0(包括) - Android 7.0(不包括) + * + * @return + */ + private static String getMacAddressM() { + String mac = "未获取到设备Mac地址"; + + try { + mac = new BufferedReader(new FileReader("/sys/class/net/wlan0/address")).readLine(); + } catch (IOException e) { + e.printStackTrace(); + } + return mac; + } + + /** + * 兼容7.0获取不到的问题 + * + * @return + */ + public static String getAndroid7MAC() { + try { + List all = Collections.list(NetworkInterface.getNetworkInterfaces()); + for (NetworkInterface nif : all) { + if (!nif.getName().equalsIgnoreCase("wlan0")) + continue; + byte[] macBytes = nif.getHardwareAddress(); + if (macBytes == null) { + return ""; + } + StringBuilder res1 = new StringBuilder(); + for (byte b : macBytes) { + res1.append(String.format("%02X:", b)); + } + if (res1.length() > 0) { + res1.deleteCharAt(res1.length() - 1); + } + return res1.toString(); + } + } catch (Exception ex) { + } + return ""; + } + + /** + * 遍历循环所有的网络接口,找到接口是 wlan0 + * + * @return + */ + private static String getMacFromHardware() { + try { + List all = Collections.list(NetworkInterface.getNetworkInterfaces()); + + for (NetworkInterface nif : all) { + if (!nif.getName().equalsIgnoreCase("wlan0")) { + continue; + } + byte[] macBytes = nif.getHardwareAddress(); + StringBuilder res1 = new StringBuilder(); + for (byte b : macBytes) { + res1.append(String.format("%02X:", b)); + } + if (res1 != null) { + res1.deleteCharAt(res1.length() - 1); + } + return res1.toString(); + } + } catch (Exception e) { + e.printStackTrace(); + } + 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; + } + public static String getDownLoadPath(Context context) { String path = ContextCompat.getExternalFilesDirs(context, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath(); return path + File.separator; @@ -247,39 +474,39 @@ public class Utils { return powerManager.isInteractive(); } - public static void exitDesktop(Activity context) { - if ("HONOR".equalsIgnoreCase(Build.BRAND)) { - RemoteManager.getInstance().exitDesktop(); -// RemoteManager.getInstance().setDefaultDesktop("com.hihonor.android.launcher"); - } else { - if ("U807".equals(BuildConfig.platform) && ApkUtils.isAvailable(context, "com.uiuipad.os")) { - RemoteManager.getInstance().setDefaultDesktop("com.uiuipad.os"); - } else { - RemoteManager.getInstance().setDefaultDesktop(ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME); - } - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { - if ("U807".equals(BuildConfig.platform) && ApkUtils.isAvailable(context, "com.uiuipad.os")) { - - if (!ApkUtils.openPackage(context, "com.uiuipad.os", "com.uiuipad.os.Launcher")) { - ApkUtils.gotoLauncher(context); - } - } else { - - if (!ApkUtils.openPackage(context, ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME, ApkUtils.ANDROID_LAUNCHER3_Quickstep_CLASS_NAME)) { - ApkUtils.gotoLauncher(context); - } - } - } else { - - if (!ApkUtils.openPackage(context, ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME, ApkUtils.ANDROID_LAUNCHER3_CLASS_NAME)) { - ApkUtils.gotoLauncher(context); - } - } - } - context.finish(); - System.exit(0); - } +// public static void exitDesktop(Activity context) { +// if ("HONOR".equalsIgnoreCase(Build.BRAND)) { +//// AdminManager.getInstance().exitDesktop(); +//// AdminManager.getInstance().setDefaultDesktop("com.hihonor.android.launcher"); +// } else { +// if ("U807".equals(BuildConfig.platform) && ApkUtils.isAvailable(context, "com.uiuipad.os")) { +// AdminManager.getInstance().setDefaultLauncher("com.uiuipad.os"); +// } else { +// AdminManager.getInstance().setDefaultLauncher(ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME); +// } +// +// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { +// if ("U807".equals(BuildConfig.platform) && ApkUtils.isAvailable(context, "com.uiuipad.os")) { +// +// if (!ApkUtils.openPackage(context, "com.uiuipad.os", "com.uiuipad.os.Launcher")) { +// ApkUtils.gotoLauncher(context); +// } +// } else { +// +// if (!ApkUtils.openPackage(context, ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME, ApkUtils.ANDROID_LAUNCHER3_Quickstep_CLASS_NAME)) { +// ApkUtils.gotoLauncher(context); +// } +// } +// } else { +// +// if (!ApkUtils.openPackage(context, ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME, ApkUtils.ANDROID_LAUNCHER3_CLASS_NAME)) { +// ApkUtils.gotoLauncher(context); +// } +// } +// } +// context.finish(); +// System.exit(0); +// } public static void triggerRebirth(Context context) { PackageManager packageManager = context.getPackageManager(); @@ -352,34 +579,26 @@ public class Utils { return macSerial; } - /** - * 兼容7.0获取不到的问题 - * - * @return - */ - public static String getAndroid7MAC() { - try { - List all = Collections.list(NetworkInterface.getNetworkInterfaces()); - for (NetworkInterface nif : all) { - if (!"wlan0".equalsIgnoreCase(nif.getName())) - continue; - byte[] macBytes = nif.getHardwareAddress(); - if (macBytes == null) { - return ""; + // 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 = ""; } - StringBuilder res1 = new StringBuilder(); - for (byte b : macBytes) { - res1.append(String.format("%02X:", b)); - } - if (res1.length() > 0) { - res1.deleteCharAt(res1.length() - 1); - } - return res1.toString(); + return mac; + } catch (Exception e) { + e.printStackTrace(); + return ""; } - } catch (Exception ex) { - Log.e(TAG, "getAndroid7MAC: " + ex.getMessage()); } - return ""; } public static String loadFileAsString(String fileName) throws Exception { @@ -416,4 +635,288 @@ 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) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + BatteryManager batteryManager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE); + return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); + } else { + Intent intent = new ContextWrapper(context).registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + return (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) / + intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); + } + } + + 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/java/com/xwad/os/view/ImageViewAdapter.java b/app/src/main/java/com/xwad/os/view/ImageViewAdapter.java index 1031d01..130ceba 100644 --- a/app/src/main/java/com/xwad/os/view/ImageViewAdapter.java +++ b/app/src/main/java/com/xwad/os/view/ImageViewAdapter.java @@ -40,6 +40,7 @@ public class ImageViewAdapter { Glide.with(imageView.getContext()) .load(url) .error(error) + .placeholder(imageView.getDrawable()) .into(imageView); } 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-nodpi/icon_read_syhbg.png b/app/src/main/res/drawable-nodpi/icon_read_syhbg.png new file mode 100644 index 0000000..37054c6 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icon_read_syhbg.png differ diff --git a/app/src/main/res/drawable-nodpi/icon_read_zhtsg.png b/app/src/main/res/drawable-nodpi/icon_read_zhtsg.png new file mode 100644 index 0000000..9806a04 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icon_read_zhtsg.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..ece7284 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -39,6 +39,25 @@ 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/dialog_userdebug.xml b/app/src/main/res/layout/dialog_userdebug.xml new file mode 100644 index 0000000..eafc20d --- /dev/null +++ b/app/src/main/res/layout/dialog_userdebug.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml index 889b3ea..57b416d 100644 --- a/app/src/main/res/layout/fragment_mine.xml +++ b/app/src/main/res/layout/fragment_mine.xml @@ -137,13 +137,14 @@ diff --git a/app/src/main/res/layout/fragment_read.xml b/app/src/main/res/layout/fragment_read.xml index 232ddc4..df1c9c9 100644 --- a/app/src/main/res/layout/fragment_read.xml +++ b/app/src/main/res/layout/fragment_read.xml @@ -148,6 +148,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="12dp" + android:visibility="gone" android:orientation="horizontal"> + + + + + + + + + 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 @@ + + + + + + + + + + + +