diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..518f773 --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,44 @@ +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html + +# Sets the minimum version of CMake required to build the native library. + +cmake_minimum_required(VERSION 3.4.1) + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. + +add_library( # Sets the name of the library. + xuewang + + # Sets the library as a shared library. + SHARED + + # Provides a relative path to your source file(s). + src/main/jni/xuewang.cpp) + +# Searches for a specified prebuilt library and stores the path as a +# variable. Because CMake includes system libraries in the search path by +# default, you only need to specify the name of the public NDK library +# you want to add. CMake verifies that the library exists before +# completing its build. + +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + log) + +# Specifies libraries CMake should link to your target library. You +# can link multiple libraries, such as libraries you define in this +# build script, prebuilt third-party libraries, or system libraries. + +target_link_libraries( # Specifies the target library. + xuewang + + # Links the target library to the log library + # included in the NDK. + ${log-lib}) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 5452259..d886167 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { minSdkVersion 24 targetSdkVersion 29 - versionCode 14 - versionName "1.1.3" + versionCode 21 + versionName "1.2.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -32,12 +32,10 @@ android { ndk { //根据需要 自行选择添加的对应cpu类型的.so库。 - abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a' - // 还可以添加 'x86', 'x86_64', 'mips', 'mips64' + abiFilters 'armeabi-v7a', 'arm64-v8a' + // 还可以添加 'armeabi', 'x86', 'x86_64', 'mips', 'mips64' } - buildConfigField "String", "WEBSOCKET_URL", '"wss://led.aolelearn.com/wss/device"' - dataBinding { enabled true } @@ -63,6 +61,11 @@ android { } } + externalNativeBuild { + cmake { + path file('CMakeLists.txt') + } + } signingConfigs { tuixin { @@ -123,6 +126,7 @@ android { } } } + } dependencies { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7eef5c4..86bdb75 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -262,6 +262,19 @@ + + + + + + + + + + + @@ -286,18 +300,7 @@ - - - - - - - - - - - @@ -313,7 +316,7 @@ android:exported="true" /> diff --git a/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java b/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java index 8f1ba55..4b9883c 100644 --- a/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java +++ b/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java @@ -1,5 +1,6 @@ package com.xwad.os.activity.activation; +import android.content.Intent; import android.graphics.Bitmap; import android.text.Editable; import android.text.InputFilter; @@ -11,6 +12,8 @@ import androidx.lifecycle.Observer; import com.hjq.toast.Toaster; import com.xwad.os.R; +import com.xwad.os.activity.home.HomeActivity; +import com.xwad.os.activity.login.result.LoginSuccessfulActivity; import com.xwad.os.base.mvvm.BaseMvvmActivity; import com.xwad.os.bean.OrderInfo; import com.xwad.os.bean.PayInfo; @@ -21,9 +24,16 @@ import com.xwad.os.utils.BitmapUtils; import java.util.List; import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; public class ActivationActivity extends BaseMvvmActivity { + private Disposable pollingDisposable; @Override protected int getLayoutId() { @@ -100,6 +110,12 @@ public class ActivationActivity extends BaseMvvmActivity() { + @Override + public void onChanged(Boolean aBoolean) { + finish(); + } + }); mViewModel.mPayInfoData.observe(this, new Observer() { @Override @@ -129,10 +145,42 @@ public class ActivationActivity extends BaseMvvmActivity { + // 此处执行轮询任务,例如网络请求 + mViewModel.getActivation(); + }, throwable -> { + // 处理错误 + throwable.printStackTrace(); + }); + } + + private void startHome() { + Intent intent = new Intent(ActivationActivity.this, HomeActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.setAction("show_activation_dialog"); + startActivity(intent); } public class BtnClick { diff --git a/app/src/main/java/com/xwad/os/activity/activation/ActivationViewModel.java b/app/src/main/java/com/xwad/os/activity/activation/ActivationViewModel.java index e8bb9bb..463b990 100644 --- a/app/src/main/java/com/xwad/os/activity/activation/ActivationViewModel.java +++ b/app/src/main/java/com/xwad/os/activity/activation/ActivationViewModel.java @@ -74,6 +74,7 @@ public class ActivationViewModel extends BaseViewModel mOrderInfoData = new MutableLiveData<>(); + public MutableLiveData mAlreadyActivatedData = new MutableLiveData<>(); public void getPayInfo(String vipId) { NetInterfaceManager.getInstance().getBuyVipControl(vipId) @@ -90,6 +91,10 @@ public class ActivationViewModel extends BaseViewModel= Build.VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + setWallpaper(); // ComponentName componentName = new ComponentName("com.jxw.hdhb", "com.jxw.hdhb.ui.activity.MainActivity"); // startActivity(new Intent().setComponent(componentName)); // startActivity(new Intent(HomeActivity.this, LoginActivity.class)); +// ComponentName componentName = new ComponentName(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME, JxwPackageConfig.JXW_LAUNCHER_CLASS_NAME); +// startService(new Intent().setComponent(componentName)); RemoteManager.setListener(this); Utils.getAndroiodScreenProperty(this); @@ -223,7 +233,9 @@ public class HomeActivity extends BaseMvvmActivity() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getOauthToken", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("getOauthToken", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getOauthToken", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getOauthToken", "onComplete: "); + } + }); + } + + public void getAnswerControlStatus() { + NetInterfaceManager.getInstance().getAnswerControlStatusControl() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAnswerControlStatus", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("getAnswerControlStatus", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAnswerControlStatus", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getAnswerControlStatus", "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 ede7b85..e65ee18 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 @@ -4,18 +4,33 @@ import android.app.Activity; import android.content.Intent; import android.text.Editable; import android.text.TextUtils; +import android.util.Log; import android.view.View; import androidx.lifecycle.Observer; import com.hjq.toast.Toaster; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; import com.xwad.os.R; 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 java.util.concurrent.TimeUnit; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.observers.DisposableObserver; +import io.reactivex.rxjava3.schedulers.Schedulers; public class LoginActivity extends BaseMvvmActivity { + + private Disposable mDisposable; + @Override protected int getLayoutId() { return R.layout.activity_login; @@ -40,24 +55,88 @@ public class LoginActivity extends BaseMvvmActivity() { + @Override + public void onChanged(Boolean aBoolean) { + if (aBoolean) { + Toaster.show("验证码发送成功"); + startCountdown(); + } else { + setCodeTextEnable(); + } + } + }); } + @Override + protected void onDestroy() { + super.onDestroy(); + if (mDisposable != null && !mDisposable.isDisposed()) { + mDisposable.dispose(); + mDisposable = null; + } + } + + private void startCountdown() { + int countdownTime = 60; // 倒计时总时长 + + mDisposable = Observable.interval(0, 1, TimeUnit.SECONDS) // 立即执行,间隔1秒 + .take(countdownTime + 1) // 总共发射的次数(从0开始,所以+1) + .map(aLong -> countdownTime - aLong) // 将递增序列转换为递减的剩余时间 + .subscribeOn(Schedulers.computation()) // 计时任务在计算线程执行 + .observeOn(AndroidSchedulers.mainThread()) // 结果回调到主线程更新UI + .compose(RxLifecycle.bindUntilEvent(getLifecycleSubject(), ActivityEvent.DESTROY)) + .subscribeWith(new DisposableObserver() { + @Override + public void onNext(Long remainingTime) { + Log.e("startCountdown", "onNext: " + remainingTime); + // 每秒更新UI,显示剩余时间 + mViewDataBinding.tvGetCode.setText(remainingTime + "秒"); + mViewDataBinding.tvGetCode.setEnabled(true);// 倒计时期间禁用按钮 + } + + @Override + public void onError(Throwable e) { + // 错误处理(通常很少发生) + Log.e("startCountdown", "Error: ", e); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("startCountdown", "onComplete: "); + setCodeTextEnable(); + } + }); + } + + private void setCodeTextEnable() { + mViewDataBinding.tvGetCode.setText("获取"); + mViewDataBinding.tvGetCode.setEnabled(true); + } + public class BtnClick { public void getCode(View view) { + mViewDataBinding.tvGetCode.setText("发送中"); + mViewDataBinding.tvGetCode.setEnabled(false); Editable editable = mViewDataBinding.etMobile.getText(); if (editable == null) { Toaster.show("请输入手机号"); + setCodeTextEnable(); return; } String mobile = editable.toString(); if (TextUtils.isEmpty(mobile)) { Toaster.show("请输入手机号"); + setCodeTextEnable(); return; } mViewModel.getPhoneCode(mobile); diff --git a/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java b/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java index e83362e..b8e220f 100644 --- a/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java +++ b/app/src/main/java/com/xwad/os/activity/login/LoginViewModel.java @@ -56,6 +56,7 @@ public class LoginViewModel extends BaseViewModel { @@ -30,8 +33,24 @@ public class LoginSuccessfulActivity extends BaseMvvmActivity= Build.VERSION_CODES.O) { - startForegroundService(intent); - } else { - startService(intent); - } - // 全屏展示 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 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 5627ed7..2eae186 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 @@ -178,6 +178,7 @@ public class UserActivity extends BaseMvvmActivity params = new HashMap<>(); params.put("sn", NetInterfaceManager.convertToJsonRequestBody(DeviceSNManager.getDeviceSN())); - mViewModel.updateInfo(params, body); + mViewModel.updateAvatar(params, body); } else { mMMKV.encode(CommonConfig.UIUI_USER_AVATAR_KEY, avatarFilePath); } diff --git a/app/src/main/java/com/xwad/os/activity/user/UserViewModel.java b/app/src/main/java/com/xwad/os/activity/user/UserViewModel.java index 36f5b8b..abcfc28 100644 --- a/app/src/main/java/com/xwad/os/activity/user/UserViewModel.java +++ b/app/src/main/java/com/xwad/os/activity/user/UserViewModel.java @@ -139,5 +139,44 @@ public class UserViewModel extends BaseViewModel params, MultipartBody.Part multipartBody) { + if (!ActivationUtil.getInstance().isLogin()) { + return; + } + NetInterfaceManager.getInstance().getupdateAvatarObservable(params, multipartBody) + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("updateInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("updateInfo", "onNext: " + baseResponse); + if (baseResponse.code == 200) { + mSuccessfulData.setValue(true); + } else { + Toaster.show(baseResponse.msg); + mSuccessfulData.setValue(false); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("updateInfo", "onError: " + e.getMessage()); + mSuccessfulData.setValue(false); + } + + @Override + public void onComplete() { + Log.e("updateInfo", "onComplete: "); + } + }); + + } + } 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 e8fa798..5e8fe7c 100644 --- a/app/src/main/java/com/xwad/os/adapter/AppAdapter.java +++ b/app/src/main/java/com/xwad/os/adapter/AppAdapter.java @@ -1,9 +1,8 @@ package com.xwad.os.adapter; -import android.app.Activity; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; +import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -13,21 +12,25 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; import com.hjq.toast.Toaster; +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.ManualActivity; import com.xwad.os.activity.PasswordActivity; +import com.xwad.os.activity.activation.ActivationActivity; +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.BitmapUtils; -import com.xwad.os.utils.IconUtils; import com.xwad.os.utils.OpenApkUtils; import com.xwad.os.utils.Utils; @@ -38,14 +41,16 @@ import me.jessyan.autosize.AutoSizeCompat; public class AppAdapter extends RecyclerView.Adapter { private static final String TAG = "AppAdapter"; - private Context mContext; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + private FragmentActivity mContext; private List desktopIcons; @NonNull @Override public AppHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - mContext = parent.getContext(); + mContext = (FragmentActivity) parent.getContext(); AutoSizeCompat.autoConvertDensityOfGlobal(mContext.getResources()); return new AppHolder(LayoutInflater.from(mContext).inflate(R.layout.item_app, parent, false)); } @@ -87,6 +92,32 @@ public class AppAdapter extends RecyclerView.Adapter { holder.root.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + Log.e(TAG, "onClick: " + pkg); + if (TextUtils.isEmpty(pkg)) { + Toaster.show("应用未安装"); + OpenApkUtils.getInstance().showDownloadDialog(mContext, pkg, lable); + return; + } + + if (!ApkUtils.isAvailable(mContext, pkg)) { + OpenApkUtils.getInstance().showDownloadDialog(mContext, pkg, lable); + return; + } + + if (!BuildConfig.DEBUG) { + if (!ActivationUtil.getInstance().isLogin()) { + Toaster.show("请先登录"); + mContext.startActivity(new Intent(mContext, LoginActivity.class)); + return; + } + + if (!ActivationUtil.getInstance().isActivation()) { + Toaster.show("请先激活后使用"); + mContext.startActivity(new Intent(mContext, ActivationActivity.class)); + return; + } + } + switch (pkg) { case AppManager.ADD_NAME: mContext.startActivity(new Intent(mContext, PasswordActivity.class)); @@ -121,7 +152,7 @@ public class AppAdapter extends RecyclerView.Adapter { exitDesktop(); break; default: - boolean settingOtherAppInstaller = RemoteManager.getInstance().showThirdApp(); + boolean settingOtherAppInstaller = mMMKV.decodeInt(CommonConfig.APP_INSTALLATION, 1) == 1; if (!settingOtherAppInstaller && !ApkUtils.isSystemApp(mContext, desktopIcon.getPackageName())) { Toaster.show("已禁止应用打开"); } else { @@ -143,7 +174,7 @@ public class AppAdapter extends RecyclerView.Adapter { if (is_activation) { mContext.startActivity(new Intent(mContext, ExitActivity.class)); } else { - Utils.exitDesktop((Activity) mContext); + Utils.exitDesktop(mContext); } } diff --git a/app/src/main/java/com/xwad/os/adapter/FileAdapter.java b/app/src/main/java/com/xwad/os/adapter/FileAdapter.java index d1efbb6..f93c270 100644 --- a/app/src/main/java/com/xwad/os/adapter/FileAdapter.java +++ b/app/src/main/java/com/xwad/os/adapter/FileAdapter.java @@ -15,14 +15,15 @@ import androidx.constraintlayout.widget.ConstraintLayout; import androidx.recyclerview.widget.RecyclerView; import com.hjq.toast.Toaster; +import com.tencent.mmkv.MMKV; import com.xwad.os.BuildConfig; import com.xwad.os.R; import com.xwad.os.activity.ManualActivity; import com.xwad.os.activity.PasswordActivity; 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.ApkUtils; import com.xwad.os.utils.BitmapUtils; import com.xwad.os.utils.IconUtils; @@ -33,8 +34,9 @@ import java.util.List; public class FileAdapter extends RecyclerView.Adapter { private static final String TAG = "FileAdapter"; - private Context mContext; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + private Context mContext; private List desktopIcons; @NonNull @@ -98,7 +100,7 @@ public class FileAdapter extends RecyclerView.Adapter { OpenApkUtils.getInstance().openApp(desktopIcon.getPackageName(), desktopIcon.getClassName()); break; default: - boolean settingOtherAppInstaller = RemoteManager.getInstance().showThirdApp(); + boolean settingOtherAppInstaller = mMMKV.decodeInt(CommonConfig.APP_INSTALLATION, 1) == 1; if (!settingOtherAppInstaller && !ApkUtils.isSystemApp(mContext, desktopIcon.getPackageName())) { Toaster.show("已禁止应用打开"); } else { diff --git a/app/src/main/java/com/xwad/os/base/BaseApplication.java b/app/src/main/java/com/xwad/os/base/BaseApplication.java index 5521696..10fd000 100644 --- a/app/src/main/java/com/xwad/os/base/BaseApplication.java +++ b/app/src/main/java/com/xwad/os/base/BaseApplication.java @@ -27,7 +27,7 @@ import com.xwad.os.manager.DeviceSNManager; import com.xwad.os.manager.RemoteManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.push.PushManager; -import com.xwad.os.receiver.APKinstallReceiver; +import com.xwad.os.receiver.ApkInstallReceiver; import com.xwad.os.utils.ActivationUtil; import com.xwad.os.utils.AppUsedTimeUtils; import com.xwad.os.utils.LenovoCsdkUtil; @@ -129,11 +129,11 @@ public class BaseApplication extends Application { }); } - private APKinstallReceiver apKinstallReceiver; + private ApkInstallReceiver apKinstallReceiver; private void registAppReceive() { if (null == apKinstallReceiver) { - apKinstallReceiver = new APKinstallReceiver(); + apKinstallReceiver = new ApkInstallReceiver(); } IntentFilter filter = new IntentFilter(); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); diff --git a/app/src/main/java/com/xwad/os/bean/OrderInfo.java b/app/src/main/java/com/xwad/os/bean/OrderInfo.java index fad8a8b..d0de43f 100644 --- a/app/src/main/java/com/xwad/os/bean/OrderInfo.java +++ b/app/src/main/java/com/xwad/os/bean/OrderInfo.java @@ -14,6 +14,7 @@ public class OrderInfo implements Serializable { String order_sn; String sn; String vip_level_id; + int is_old; public int getOrder_id() { return order_id; @@ -47,6 +48,14 @@ public class OrderInfo implements Serializable { this.vip_level_id = vip_level_id; } + public int getIs_old() { + return is_old; + } + + public void setIs_old(int is_old) { + this.is_old = is_old; + } + @NonNull @Override public String toString() { diff --git a/app/src/main/java/com/xwad/os/config/CommonConfig.java b/app/src/main/java/com/xwad/os/config/CommonConfig.java index ca9f0b4..1e76ce0 100644 --- a/app/src/main/java/com/xwad/os/config/CommonConfig.java +++ b/app/src/main/java/com/xwad/os/config/CommonConfig.java @@ -72,4 +72,12 @@ public class CommonConfig { public static final String ACCOUNT_DEVICE_ID = "account_device_id_key"; public static final String ACCOUNT_DEVICE_SN = "account_device_sn_key"; + + /*应用市场是否禁止下载*/ + public static final String APP_STORE_INSTALL = "iflytek_setting_is_storeinstall"; + /*是否禁止应用打开*/ + public static final String APP_INSTALLATION = "iflytek_setting_other_appInstaller"; + /*是否为管理员app*/ + public static final String APP_ADMIN = "iflytek_setting_admin_app"; + } diff --git a/app/src/main/java/com/xwad/os/dialog/PermissionsDialog.java b/app/src/main/java/com/xwad/os/dialog/PermissionsDialog.java index ed668fd..e7405b3 100644 --- a/app/src/main/java/com/xwad/os/dialog/PermissionsDialog.java +++ b/app/src/main/java/com/xwad/os/dialog/PermissionsDialog.java @@ -3,13 +3,17 @@ package com.xwad.os.dialog; import android.content.Context; import android.os.Bundle; import android.text.TextUtils; +import android.view.Gravity; import android.view.View; +import android.view.Window; +import android.view.WindowManager; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import com.blankj.utilcode.util.ScreenUtils; import com.xwad.os.R; public class PermissionsDialog extends AlertDialog { @@ -101,6 +105,16 @@ public class PermissionsDialog extends AlertDialog { @Override public void show() { super.show(); + // 获取对话框的 Window 对象 + Window dialogWindow = getWindow(); + if (dialogWindow != null) { + WindowManager.LayoutParams params = dialogWindow.getAttributes(); + // 设置宽度为屏幕宽度的95%,这能有效解决在Android 9.0+上的偏移问题 + params.width = (int) (ScreenUtils.getScreenWidth() * 0.95); + // 确保重力设置为居中 + params.gravity = Gravity.CENTER; + dialogWindow.setAttributes(params); + } setText(); } diff --git a/app/src/main/java/com/xwad/os/dialog/PrivacyPolicyDialog.java b/app/src/main/java/com/xwad/os/dialog/PrivacyPolicyDialog.java index a014c69..dbc1e24 100644 --- a/app/src/main/java/com/xwad/os/dialog/PrivacyPolicyDialog.java +++ b/app/src/main/java/com/xwad/os/dialog/PrivacyPolicyDialog.java @@ -10,13 +10,17 @@ import android.text.Spanned; import android.text.method.LinkMovementMethod; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; +import android.view.Gravity; import android.view.View; +import android.view.Window; +import android.view.WindowManager; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; +import com.blankj.utilcode.util.ScreenUtils; import com.xwad.os.R; import com.xwad.os.activity.privacy.PrivacyActivity; @@ -107,4 +111,19 @@ public class PrivacyPolicyDialog extends AlertDialog { } }); } + + @Override + public void show() { + super.show(); + // 获取对话框的 Window 对象 + Window dialogWindow = getWindow(); + if (dialogWindow != null) { + WindowManager.LayoutParams params = dialogWindow.getAttributes(); + // 设置宽度为屏幕宽度的95%,这能有效解决在Android 9.0+上的偏移问题 + params.width = (int) (ScreenUtils.getScreenWidth() * 0.95); + // 确保重力设置为居中 + params.gravity = Gravity.CENTER; + dialogWindow.setAttributes(params); + } + } } diff --git a/app/src/main/java/com/xwad/os/fragment/app/AppViewModel.java b/app/src/main/java/com/xwad/os/fragment/app/AppViewModel.java index 4b65793..efac11f 100644 --- a/app/src/main/java/com/xwad/os/fragment/app/AppViewModel.java +++ b/app/src/main/java/com/xwad/os/fragment/app/AppViewModel.java @@ -104,27 +104,34 @@ public class AppViewModel extends BaseViewModel() { + @Override + public void onChanged(UserAvatarInfo userAvatarInfo) { + mViewDataBinding.setUserAvatarInfo(userAvatarInfo); + } + }); + mViewModel.getSnInfo(); } @Override @@ -222,6 +209,12 @@ public class MineFragment extends BaseMvvmFragment { @Override @@ -15,4 +29,64 @@ public class MineViewModel extends BaseViewModel mUserAvatarInfoData = new MutableLiveData<>(); + + public void getUserAvatarInfo() { + NetInterfaceManager.getInstance() + .getUserAvatarInfoControl() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getUserAvatarInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse userAvatarInfoBaseResponse) { + Log.e("getUserAvatarInfo", "onNext: " + userAvatarInfoBaseResponse); + mUserAvatarInfoData.setValue(userAvatarInfoBaseResponse.data); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getUserAvatarInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getUserAvatarInfo", "onComplete: "); + } + }); + } + + public MutableLiveData mSnInfoData = new MutableLiveData<>(); + + public void getSnInfo() { + NetInterfaceManager.getInstance().getSnInfoControl() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getSnInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse snInfoBaseResponse) { + Log.e("getSnInfo", "onNext: " + snInfoBaseResponse); + if (snInfoBaseResponse.code == 200) { + mSnInfoData.setValue(snInfoBaseResponse.data); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getSnInfo", "onError: "); + } + + @Override + public void onComplete() { + Log.e("getSnInfo", "onComplete: "); + } + }); + } } diff --git a/app/src/main/java/com/xwad/os/fragment/safe/SafeFragment.java b/app/src/main/java/com/xwad/os/fragment/safe/SafeFragment.java index 68a044b..d5c81ba 100644 --- a/app/src/main/java/com/xwad/os/fragment/safe/SafeFragment.java +++ b/app/src/main/java/com/xwad/os/fragment/safe/SafeFragment.java @@ -17,12 +17,10 @@ import androidx.recyclerview.widget.GridLayoutManager; import com.chad.library.adapter.base.BaseQuickAdapter; import com.tencent.mmkv.MMKV; import com.xwad.os.R; -import com.xwad.os.adapter.AppAdapter; import com.xwad.os.base.mvvm.fragment.BaseMvvmFragment; import com.xwad.os.bean.jxw.AppInfo; import com.xwad.os.config.CommonConfig; import com.xwad.os.databinding.FragmentSafeBinding; -import com.xwad.os.jxw.AssertUtils; import com.xwad.os.jxw.StudyRecordMng; import com.xwad.os.jxw.ToastUtil; import com.xwad.os.jxw.adapter.ZhMenuAdapter; @@ -164,7 +162,7 @@ public class SafeFragment extends BaseMvvmFragment { @@ -112,6 +115,31 @@ public class AccountFragment extends BaseMvvmFragment mActivationLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() { + @Override + public void onActivityResult(ActivityResult result) { + Log.e(TAG, "onActivityResult: " + result); + if (result != null) { + Intent intent = result.getData(); + if (intent != null && result.getResultCode() == Activity.RESULT_OK) { + mViewModel.getUserInfo(); + + DefaultAppsDialog appsDialog = new DefaultAppsDialog(getActivity()); + appsDialog.show(); } } } @@ -190,7 +218,14 @@ public class AccountFragment extends BaseMvvmFragment>() { + @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; + FileUtil.ariaDownload(getCtx(), 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: "); + } + }); + } } diff --git a/app/src/main/java/com/xwad/os/jxw/JxwPackageConfig.java b/app/src/main/java/com/xwad/os/jxw/JxwPackageConfig.java index 64057a1..9d4f934 100644 --- a/app/src/main/java/com/xwad/os/jxw/JxwPackageConfig.java +++ b/app/src/main/java/com/xwad/os/jxw/JxwPackageConfig.java @@ -3,6 +3,9 @@ package com.xwad.os.jxw; public class JxwPackageConfig { /*注册桌面*/ public static final String JXW_LAUNCHER_PACKAGE_NAME = "com.jxw.launcher"; + public static final String JXW_LAUNCHER_REGISTER_CLASS_NAME = "com.jxw.engine.platsign.MainActivity"; + public static final String JXW_LAUNCHER_DUMMY_ACTIVITY = "com.jxw.launcher.DummyActivity"; + public static final String JXW_LAUNCHER_CLASS_NAME = "com.jht.engine.platsign.PlatformService"; public static final String JXW_LAUNCHER_UPDATE_CLASS_NAME = "com.jxw.engine.platsign.UpdateActivity"; /*同步视频*/ diff --git a/app/src/main/java/com/xwad/os/jxw/fragment/HxFragment.java b/app/src/main/java/com/xwad/os/jxw/fragment/HxFragment.java index fb0183f..3f43da7 100644 --- a/app/src/main/java/com/xwad/os/jxw/fragment/HxFragment.java +++ b/app/src/main/java/com/xwad/os/jxw/fragment/HxFragment.java @@ -216,7 +216,7 @@ public class HxFragment extends BaseNewFragment { contentAdapter.notifyDataSetChanged(); // MyApp.getInstance().mBottomBtnOnClickListener.setContext(getActivity()); // MyApp.getInstance().mBottomBtnOnClickListener.onClick(obj); - OpenApkUtils.getInstance().openJxwApp(getActivity(), obj); + OpenApkUtils.getInstance().openJxwAppWithParam(getActivity(), obj, true); } private void saveTag(ItemsBean itemsBean) { diff --git a/app/src/main/java/com/xwad/os/jxw/fragment/SwFragment.java b/app/src/main/java/com/xwad/os/jxw/fragment/SwFragment.java index 749e512..84dae03 100644 --- a/app/src/main/java/com/xwad/os/jxw/fragment/SwFragment.java +++ b/app/src/main/java/com/xwad/os/jxw/fragment/SwFragment.java @@ -223,7 +223,7 @@ public class SwFragment extends BaseNewFragment { contentAdapter.notifyDataSetChanged(); // MyApp.getInstance().mBottomBtnOnClickListener.setContext(getActivity()); // MyApp.getInstance().mBottomBtnOnClickListener.onClick(obj); - OpenApkUtils.getInstance().openJxwApp(getActivity(), obj); + OpenApkUtils.getInstance().openJxwAppWithParam(getActivity(), obj, true); } private void saveTag(ItemsBean itemsBean) { diff --git a/app/src/main/java/com/xwad/os/jxw/fragment/WlFragment.java b/app/src/main/java/com/xwad/os/jxw/fragment/WlFragment.java index d20f6ae..766cce3 100644 --- a/app/src/main/java/com/xwad/os/jxw/fragment/WlFragment.java +++ b/app/src/main/java/com/xwad/os/jxw/fragment/WlFragment.java @@ -222,7 +222,7 @@ public class WlFragment extends BaseNewFragment { contentAdapter.notifyDataSetChanged(); // MyApp.getInstance().mBottomBtnOnClickListener.setContext(getActivity()); // MyApp.getInstance().mBottomBtnOnClickListener.onClick(obj); - OpenApkUtils.getInstance().openJxwApp(getActivity(), obj); + OpenApkUtils.getInstance().openJxwAppWithParam(getActivity(), obj, true); } private void saveTag(ItemsBean itemsBean) { diff --git a/app/src/main/java/com/xwad/os/jxw/util/Util.java b/app/src/main/java/com/xwad/os/jxw/util/Util.java index 30e86d7..88f3b53 100644 --- a/app/src/main/java/com/xwad/os/jxw/util/Util.java +++ b/app/src/main/java/com/xwad/os/jxw/util/Util.java @@ -56,7 +56,8 @@ public class Util { } public static void downloadClickListener(Activity activity, String str, String str2, String str3, String str4) { - OpenApkUtils.getInstance().openJxwApp(activity, "" + str + "," + str2 + "," + str3 + "," + str.substring(str.lastIndexOf(".") + 1) + "," + str4); + String tag = "" + str + "," + str2 + "," + str3 + "," + str.substring(str.lastIndexOf(".") + 1) + "," + str4; + OpenApkUtils.getInstance().openJxwAppWithParam(activity, tag, true); } public static String checkGrade(String str) { 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 c966458..a0fb998 100644 --- a/app/src/main/java/com/xwad/os/network/NetInterfaceManager.java +++ b/app/src/main/java/com/xwad/os/network/NetInterfaceManager.java @@ -36,7 +36,6 @@ import com.xwad.os.config.CommonConfig; import com.xwad.os.disklrucache.CacheHelper; import com.xwad.os.gson.GsonUtils; import com.xwad.os.manager.DeviceSNManager; -import com.xwad.os.manager.RemoteManager; import com.xwad.os.network.api.AlarmClockApi; import com.xwad.os.network.api.AppApi; import com.xwad.os.network.api.AppUsageRecordApi; @@ -44,18 +43,21 @@ import com.xwad.os.network.api.FilesApi; 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.SnInfoApi; import com.xwad.os.network.api.SettingApi; +import com.xwad.os.network.api.SnInfoApi; 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.LenovoCsdkUtil; +import com.xwad.os.utils.ActivationUtil; +import com.xwad.os.utils.JxwUtils; import com.xwad.os.utils.OpenApkUtils; import com.xwad.os.utils.Utils; import java.io.File; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -92,6 +94,8 @@ public class NetInterfaceManager { private OkHttpClient mOkHttpClient; private Retrofit mUiuiosRetrofit; private OkHttpClient mUiuiosOkHttpClient; + private Retrofit mJxwRetrofit; + private OkHttpClient mJxwOkHttpClient; private final ConcurrentHashMap requestIdsMap = new ConcurrentHashMap<>(); //超时时间 @@ -106,7 +110,6 @@ public class NetInterfaceManager { this.mContext = context; this.mCacheHelper = new CacheHelper(context); if (mOkHttpClient == null) { - //如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了 OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(TIME_OUT, TimeUnit.SECONDS); // 设置连接超时时间 @@ -131,7 +134,6 @@ public class NetInterfaceManager { } if (mUiuiosOkHttpClient == null) { - //如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了 OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(TIME_OUT, TimeUnit.SECONDS); // 设置连接超时时间 @@ -154,6 +156,30 @@ public class NetInterfaceManager { .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); } + + if (mJxwOkHttpClient == null) { + //如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了 + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.connectTimeout(TIME_OUT, TimeUnit.SECONDS); // 设置连接超时时间 + builder.writeTimeout(TIME_OUT, TimeUnit.SECONDS);// 设置写入超时时间 + builder.readTimeout(TIME_OUT, TimeUnit.SECONDS);// 设置读取数据超时时间 + builder.retryOnConnectionFailure(true);// 设置进行连接失败重试 + builder.addInterceptor(new RepeatRequestInterceptor()); + + // 设置缓存文件路径 + Cache cache = new Cache(new File(Utils.getCacheDir(mContext) + "/OkHttpCache"), CACHE_SIZE); + builder.cache(cache);// 设置缓存 + mJxwOkHttpClient = builder.build(); + } + + if (mJxwRetrofit == null) { + mJxwRetrofit = new Retrofit.Builder() + .client(mJxwOkHttpClient) + .baseUrl(UrlAddress.JXW_BASE_URL) + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) + .build(); + } } /** @@ -206,7 +232,7 @@ public class NetInterfaceManager { } - private String getToken() { + public String getToken() { String token = mMMKV.decodeString(CommonConfig.ACCOUNT_LOGIN_TOKEN, ""); return token; } @@ -257,14 +283,21 @@ public class NetInterfaceManager { String json = GsonUtils.toJSONString(params); RequestBody body = convertToJsonRequestBody(json); return mRetrofit.create(SnInfoApi.class) - .updateUserInfo(body) + .updateUserInfo(getToken(), body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getUpdateInfoObservable(Map params, MultipartBody.Part multipartBody) { return mRetrofit.create(SnInfoApi.class) - .updateUserInfo(params, multipartBody) + .updateUserInfo(getToken(), params, multipartBody) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable getupdateAvatarObservable(Map params, MultipartBody.Part multipartBody) { + return mRetrofit.create(SnInfoApi.class) + .updateAvatar(getToken(), params, multipartBody) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -314,7 +347,7 @@ public class NetInterfaceManager { public Observable getUpdateAddressObservable(String address, double longitude, double latitude) { return mRetrofit.create(SnInfoApi.class) - .updateAddress(DeviceSNManager.getDeviceSN(), address, longitude, latitude) + .updateAddress(getToken(), DeviceSNManager.getDeviceSN(), address, longitude, latitude) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -384,7 +417,7 @@ public class NetInterfaceManager { public Observable> getNewCodeLoginObservable(String mobile, String code) { return mRetrofit.create(LoginApi.class) - .newCodeLogin(mobile, code) + .newCodeLogin(mobile, code, "", BuildConfig.APPLICATION_ID) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -438,6 +471,28 @@ public class NetInterfaceManager { .observeOn(AndroidSchedulers.mainThread()); } + public Observable getOauthTokenObservable() { + Map params = new HashMap<>(); + params.put("appId", JxwUtils.getAppId()); + params.put("signature", JxwUtils.getAppSecret()); + params.put("timestamp", String.valueOf(System.currentTimeMillis())); + params.put("nonce", "zylcpxlj"); + return mJxwRetrofit.create(JxwApi.class) + .getOauthToken(params) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable getAnswerControlStatusControl() { + Map params = new HashMap<>(); + params.put("deviceSeries", ActivationUtil.getInstance().getActivationCode()); + params.put("registerIsbn", "zylcpxlj"); + return mJxwRetrofit.create(JxwApi.class) + .getAnswerControlStatus(JxwUtils.getSignature(params), params) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + /* * 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 6be1cd2..75bdd63 100644 --- a/app/src/main/java/com/xwad/os/network/UrlAddress.java +++ b/app/src/main/java/com/xwad/os/network/UrlAddress.java @@ -3,6 +3,9 @@ package com.xwad.os.network; public class UrlAddress { public static final String ROOT_URL = "https://365api.uiuipad.com/android/"; + public static final String WEBSOCKET_URL_ONLINE = "wss://365api.uiuipad.com/wss/device"; + public static final String WEBSOCKET_URL_SSO = "wss://365api.uiuipad.com/wss/sso"; + /*发送登录验证码*/ public final static String LOGIN_GET_CODE = "login/get-code"; @@ -36,13 +39,14 @@ public class UrlAddress { public final static String APP_FORCE_INSTALL = "app/force-install"; - /*设备信息接口*/ public static final String SNINFO = "sn/getSnInfo"; /*获取用户头像和信息*/ public static final String GET_USER_AVATAR_INFO = "sn/getUserAvatarInfo"; /*修改设备个人信息*/ public static final String UPDATE_INFO = "sn/update-info"; + /*更新头像*/ + public static final String UPDATE_avatar = "sn/avatar"; /*获取统计*/ public static final String GET_STUDY_STAT = "Sn/getStudyStat"; @@ -81,4 +85,12 @@ public class UrlAddress { public static final String UIUIOS_ROOT_URL = "https://map.uiuios.com/android/"; /*获取应用更新*/ public static final String CHECK_UPDATE = "app/check-update"; + + public static final String JXW_BASE_URL = "https://openapi.jxwxxkj.com/"; + /*第三方登录-获取openToken*/ + public static final String get_oauth_token = "auth2/api/oauth/token"; + /*控制/设备端-查看答疑管控状态*/ + public static final String answer_Control_status = "api/jxwdevice/answerControl/status"; + + } diff --git a/app/src/main/java/com/xwad/os/network/api/LoginApi.java b/app/src/main/java/com/xwad/os/network/api/LoginApi.java index ce758c3..f26b7d0 100644 --- a/app/src/main/java/com/xwad/os/network/api/LoginApi.java +++ b/app/src/main/java/com/xwad/os/network/api/LoginApi.java @@ -37,6 +37,8 @@ public interface LoginApi { @POST(UrlAddress.NEW_CODE_LOGIN) Observable> newCodeLogin( @Field("mobile") String mobile, - @Field("code") String code + @Field("code") String code, + @Field("sn") String sn, + @Field("desktop_package") String desktop_package ); } 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 09e3760..77e48fe 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 @@ -15,6 +15,7 @@ import retrofit2.http.Body; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; +import retrofit2.http.Header; import retrofit2.http.Multipart; import retrofit2.http.POST; import retrofit2.http.Part; @@ -34,13 +35,26 @@ public interface SnInfoApi { ); @POST(UrlAddress.UPDATE_INFO) - Observable updateUserInfo(@Body RequestBody requestBody); + Observable updateUserInfo( + @Header("token") String token, + @Body RequestBody requestBody + ); @Multipart @POST(UrlAddress.UPDATE_INFO) Observable updateUserInfo( + @Header("token") String token, @PartMap Map params, - @Part MultipartBody.Part body); + @Part MultipartBody.Part body + ); + + @Multipart + @POST(UrlAddress.UPDATE_avatar) + Observable updateAvatar( + @Header("token") String token, + @PartMap Map params, + @Part MultipartBody.Part body + ); @GET(UrlAddress.GET_STUDY_STAT) Observable> getStudyStat( @@ -50,6 +64,7 @@ public interface SnInfoApi { @FormUrlEncoded @POST(UrlAddress.UPDATE_ADDRESS) Observable updateAddress( + @Header("token") String token, @Field("sn") String sn, @Field("address") String address, @Field("longitude") double longitude, diff --git a/app/src/main/java/com/xwad/os/network/api/jxw/JxwApi.java b/app/src/main/java/com/xwad/os/network/api/jxw/JxwApi.java new file mode 100644 index 0000000..a9b7c33 --- /dev/null +++ b/app/src/main/java/com/xwad/os/network/api/jxw/JxwApi.java @@ -0,0 +1,24 @@ +package com.xwad.os.network.api.jxw; + +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.network.UrlAddress; + +import java.util.Map; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.QueryMap; + +public interface JxwApi { + @GET(UrlAddress.get_oauth_token) + Observable getOauthToken( + @QueryMap Map params + ); + + @GET(UrlAddress.answer_Control_status) + Observable getAnswerControlStatus( + @Header("token") String token, + @QueryMap Map params + ); +} 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 3f1d0a2..be2a6ee 100644 --- a/app/src/main/java/com/xwad/os/push/PushManager.java +++ b/app/src/main/java/com/xwad/os/push/PushManager.java @@ -5,6 +5,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import com.xwad.os.activity.home.HomeActivity; import com.xwad.os.disklrucache.CacheHelper; import com.xwad.os.fragment.user.UserFragment; import com.xwad.os.network.NetInterfaceManager; @@ -48,6 +49,8 @@ public class PushManager { private static final String JIGUANG_ALARM_CLOCK = "57"; /*网课模式*/ private static final String ONLINE_COURSE_MODE = "71"; + /*付款成功*/ + private static final String WECHAT_PAY_COMPLETE = "97"; /*作业提醒*/ private static final String HOMEWORK_REMINDERS = "115"; /*爱的鼓励*/ @@ -64,6 +67,9 @@ public class PushManager { Toaster.debugShow("收到推送消息: 网课模式"); NetInterfaceManager.getInstance().getCloudLessonSettings(); break; + case WECHAT_PAY_COMPLETE: + startHome(); + break; case HOMEWORK_REMINDERS: sendHomework(extras); break; @@ -74,6 +80,14 @@ public class PushManager { } } + private void startHome() { + Intent intent = new Intent(mContext, HomeActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.setAction("show_activation_dialog"); + mContext.startActivity(intent); + } + private void sendAlarmClock(String extras) { NetInterfaceManager.getInstance().getAlarmClock(); Intent intent = new Intent(SET_ALARMCLOCK); diff --git a/app/src/main/java/com/xwad/os/receiver/APKinstallReceiver.java b/app/src/main/java/com/xwad/os/receiver/APKinstallReceiver.java deleted file mode 100644 index 3e0cd47..0000000 --- a/app/src/main/java/com/xwad/os/receiver/APKinstallReceiver.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.xwad.os.receiver; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import com.xwad.os.BuildConfig; -import com.xwad.os.fragment.user.UserFragment; - -public class APKinstallReceiver extends BroadcastReceiver { - - private static final String TAG = "APKinstallReceiver"; - - @Override - public void onReceive(final Context context, Intent intent) { - // an Intent broadcast. - String packageName = intent.getDataString().replace("package:", ""); - Log.e(TAG, "onReceive: " + packageName + ": " + intent.getAction()); - Intent updateIntent = new Intent(UserFragment.UPDATE_DESKTOP_ICON_ACTION); - intent.setPackage(BuildConfig.APPLICATION_ID); - context.sendBroadcast(updateIntent); - } -} diff --git a/app/src/main/java/com/xwad/os/receiver/ApkInstallReceiver.java b/app/src/main/java/com/xwad/os/receiver/ApkInstallReceiver.java new file mode 100644 index 0000000..c9f50e2 --- /dev/null +++ b/app/src/main/java/com/xwad/os/receiver/ApkInstallReceiver.java @@ -0,0 +1,60 @@ +package com.xwad.os.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.util.Log; + +import com.tencent.mmkv.MMKV; +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.service.main.MainService; +import com.xwad.os.utils.ActivationUtil; + +public class ApkInstallReceiver extends BroadcastReceiver { + + private static final String TAG = "APKinstallReceiver"; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + @Override + public void onReceive(final Context context, Intent intent) { + // an Intent broadcast. + String action = intent.getAction(); + + String packageName = intent.getDataString().replace("package:", ""); + Log.e(TAG, "onReceive: " + packageName + ": " + intent.getAction()); + + Intent updateIntent = new Intent(UserFragment.UPDATE_DESKTOP_ICON_ACTION); + intent.setPackage(BuildConfig.APPLICATION_ID); + context.sendBroadcast(updateIntent); + + switch (action) { + case Intent.ACTION_PACKAGE_ADDED: + case Intent.ACTION_PACKAGE_REPLACED: + case Intent.ACTION_PACKAGE_CHANGED: + if (JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME.equals(packageName)) { + //刚刚安装完打开会失败 + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + ActivationUtil.getInstance().startJxwLauncher(); + } + }, 2345); + } + break; + case Intent.ACTION_PACKAGE_REMOVED: + if (JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME.equals(packageName)) { + mMMKV.encode(MainService.JXW_REGISTER_SUCCESS, false); + } + break; + default: + break; + } + + + } + +} 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 2382dbf..5e152ba 100644 --- a/app/src/main/java/com/xwad/os/service/DownloadService.java +++ b/app/src/main/java/com/xwad/os/service/DownloadService.java @@ -49,6 +49,7 @@ public class DownloadService extends Service { mNotificationManagerCompat = NotificationManagerCompat.from(this); createNotificationChannel(); createDownloadNotificationChannel(); + sendSimpleNotification(); } @Override @@ -92,7 +93,7 @@ public class DownloadService extends Service { PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) - .setContentTitle("关怀系统正在运行") + .setContentTitle("学王365正在运行") // .setContentText("测试内容") .setAutoCancel(false) .setShowWhen(false) @@ -131,8 +132,8 @@ public class DownloadService extends Service { .setProgress(100, progress, false) .setPriority(NotificationCompat.PRIORITY_HIGH); // notificationId is a unique int for each notification that you must define -// mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build()); - startForeground(ariaDownloadInfo.getAppId(), builder.build()); + mNotificationManagerCompat.notify(ariaDownloadInfo.getAppId(), builder.build()); +// startForeground(ariaDownloadInfo.getAppId(), builder.build()); } private void sendDownloadComplete(AriaDownloadInfo ariaDownloadInfo, String path) { 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 7641212..da0d70c 100644 --- a/app/src/main/java/com/xwad/os/service/SocketService.java +++ b/app/src/main/java/com/xwad/os/service/SocketService.java @@ -1,34 +1,34 @@ package com.xwad.os.service; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Binder; -import android.os.Build; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; +import com.alibaba.sdk.android.push.CloudPushService; +import com.alibaba.sdk.android.push.CommonCallback; +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; -import com.xwad.os.R; -import com.xwad.os.activity.main.MainActivity; +import com.xwad.os.activity.login.LoginActivity; import com.xwad.os.config.CommonConfig; +import com.xwad.os.gson.GsonUtils; import com.xwad.os.manager.DeviceSNManager; -import com.xwad.os.manager.RemoteManager; +import com.xwad.os.network.NetInterfaceManager; +import com.xwad.os.network.UrlAddress; import com.xwad.os.utils.ActivationUtil; -import com.xwad.os.utils.LenovoCsdkUtil; import com.xwad.os.utils.Utils; import com.xwad.os.websocket.JWebSocketClient; @@ -62,7 +62,10 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); - public JWebSocketClient mJWebSocketClient; + private CloudPushService mCloudPushService; + + public JWebSocketClient mOnlineJWebSocketClient; + public JWebSocketClient mSsoJWebSocketClient; // private SocketServiceBinder mBinder = new SocketServiceBinder(); @Override @@ -116,16 +119,18 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat NetworkUtils.registerNetworkStatusChangedListener(this); registerScreenLockReceiver(); - registerJxwRegisterRefreshReceiver(); + mCloudPushService = PushServiceFactory.getCloudPushService(); if (ActivationUtil.getInstance().isLogin()) { //初始化websocket - initSocketClient(); - startLoop(); + initOnlineSocketClient(); + initSsoSocketClient(); + initPush(); } else { Log.e(TAG, "onCreate: 未激活不连接"); } + // boolean isServiceRunning = ServiceAliveUtils.isServiceAlive(this, MainService.class.getName()); // Log.e(TAG, "onCreate: isServiceRunning = " + isServiceRunning); // if (!isServiceRunning) { @@ -133,15 +138,26 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat // } // bindService(new Intent(this, ManagerService.class), mServiceConnection, Context.BIND_IMPORTANT); - mNotificationManagerCompat = NotificationManagerCompat.from(this); - createNotificationChannel(); -// showNotification(); - sendSimpleNotification(); } + public static final String LOGIN_SUCCESSFUL = "login_successful"; + @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 LOGIN_SUCCESSFUL: + initOnlineSocketClient(); + initSsoSocketClient(); + initPush(); + break; + } + } + } return START_STICKY; } @@ -150,56 +166,75 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat super.onDestroy(); NetworkUtils.unregisterNetworkStatusChangedListener(this); dispose(); - closeConnect(); + closeOnlineConnect(); + closeSsoConnect(); if (mScreenLockReceiver != null) { unregisterReceiver(mScreenLockReceiver); } - if (mJxwRegisterReceiver != null) { - unregisterReceiver(mJxwRegisterReceiver); - } // unbindService(mServiceConnection); } - private static final String CHANNEL_ID = "CHANNEL_ID"; - private static final String CHANNEL_NAME = "系统通知"; - private static final String CHANNEL_DESCRIPTION = "学习课堂通知"; - - private void createNotificationChannel() { - // Create the NotificationChannel, but only on API 26+ because - // the NotificationChannel class is new and not in the support library - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - CharSequence name = CHANNEL_NAME; - String description = CHANNEL_DESCRIPTION; - int importance = NotificationManager.IMPORTANCE_DEFAULT; - NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); - channel.setDescription(description); - // Register the channel with the system; you can't change the importance - // or other notification behaviors after this - NotificationManager notificationManager = getSystemService(NotificationManager.class); - notificationManager.createNotificationChannel(channel); + private void dispose() { + if (mOnlineDisposable != null && !mOnlineDisposable.isDisposed()) { + mOnlineDisposable.dispose(); + mOnlineDisposable = null; + } + if (mSsoDisposable != null && !mSsoDisposable.isDisposed()) { + mSsoDisposable.dispose(); + mSsoDisposable = null; } } - private NotificationManagerCompat mNotificationManagerCompat; - private int NotificationID = 1; + public void initPush() { + mCloudPushService.register(this, new CommonCallback() { + @Override + public void onSuccess(String response) { + Log.e("AliyunPush", "init cloudchannel success"); + Log.e("AliyunPush", "init cloudchannel success " + mCloudPushService.getDeviceId()); +// mMMKV.encode(CommonConfig.ALIYUN_PUSH_ID, mCloudPushService.getDeviceId()); + bindSn(); + } - private void sendSimpleNotification() { - Intent intent = new Intent(this, MainActivity.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") - .setSmallIcon(R.mipmap.ic_launcher) - .setContentTitle("学习课堂正在运行") -// .setContentText("测试内容") - .setAutoCancel(false) - .setShowWhen(false) - .setContentIntent(pendingIntent) - .setOngoing(true) - .setOnlyAlertOnce(true) - .setPriority(NotificationCompat.PRIORITY_MAX); - // notificationId is a unique int for each notification that you must define -// mNotificationManagerCompat.notify(NotificationID, builder.build()); - startForeground(NotificationID, builder.build()); + @Override + public void onFailed(String errorCode, String errorMessage) { + Log.e("AliyunPush", "init cloudchannel failed -- errorcode:" + errorCode + " -- errorMessage:" + errorMessage); +// mMMKV.encode(CommonConfig.ALIYUN_PUSH_ID, errorCode + errorMessage); + if ("PUSH_20110".equals(errorCode)) { + bindSn(); + } + } + }); + } + + private void bindSn() { + String sn = DeviceSNManager.getDeviceSN(); + if (TextUtils.isEmpty(sn)) { + return; + } + mCloudPushService.bindAccount(sn, new CommonCallback() { + @Override + public void onSuccess(String s) { + Log.e("AliyunPush", "bind account " + sn + " success\n"); + } + + @Override + public void onFailed(String errorCode, String errorMsg) { + Log.e("AliyunPush", "bind account " + sn + " failed." + + "errorCode: " + errorCode + ", errorMsg:" + errorMsg); + } + }); + mCloudPushService.addAlias(sn, new CommonCallback() { + @Override + public void onSuccess(String s) { + Log.e("AliyunPush", "add alias " + sn + " success\n"); + } + + @Override + public void onFailed(String errorCode, String errorMsg) { + Log.e("AliyunPush", "add alias " + sn + " failed." + + "errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n"); + } + }); } private ScreenLockReceiver mScreenLockReceiver; @@ -234,13 +269,13 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat case Intent.ACTION_USER_PRESENT: case Intent.ACTION_SCREEN_ON: - sendMsgScreen(); + sendOnlineMsgScreen(); break; case Intent.ACTION_SCREEN_OFF: case Intent.ACTION_SHUTDOWN: case Intent.ACTION_FACTORY_RESET: case Intent.ACTION_MASTER_CLEAR: - sendMsgScreen(); + sendOnlineMsgScreen(); break; default: break; @@ -248,72 +283,38 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat } } - public static final String JXW_REGISTER_SUCCESS = "com.zzj.regist_success"; + private Disposable mOnlineDisposable; - private JxwRegisterReceiver mJxwRegisterReceiver; - - private void registerJxwRegisterRefreshReceiver() { - if (mJxwRegisterReceiver == null) { - mJxwRegisterReceiver = new JxwRegisterReceiver(); + private void startOnlineLoop() { + if (mOnlineDisposable != null && !mOnlineDisposable.isDisposed()) { + mOnlineDisposable.dispose(); + mOnlineDisposable = null; } - IntentFilter filter = new IntentFilter(); - filter.addAction(JXW_REGISTER_SUCCESS); - registerReceiver(mJxwRegisterReceiver, filter); - } - - public class JxwRegisterReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Log.e("JxwRegisterReceiver", "onReceive: " + action); - if (JXW_REGISTER_SUCCESS.equals(action)) { - mMMKV.encode(JXW_REGISTER_SUCCESS, true); - mMMKV.encode(CommonConfig.UIUI_ACTIVATION_KEY, ActivationUtil.getInstance().ACTIVATED_KEY); - initSocketClient(); - startLoop(); - } - } - } - - private Disposable mDisposable; - - private void dispose() { - if (mDisposable != null && !mDisposable.isDisposed()) { - mDisposable.dispose(); - mDisposable = null; - } - } - - private void startLoop() { - if (mDisposable != null && !mDisposable.isDisposed()) { - mDisposable.dispose(); - mDisposable = null; - } - mDisposable = Observable.interval(30, TimeUnit.SECONDS) + mOnlineDisposable = Observable.interval(30, TimeUnit.SECONDS) .subscribe(new Consumer() { @Override public void accept(Long s) throws Exception { - Log.d(TAG, "startLoop accept: " + s); + Log.d(TAG, "startOnlineLoop accept: " + s); Log.i(TAG, "心跳包检测websocket连接状态"); if (!ActivationUtil.getInstance().isLogin()) { dispose(); } //每隔一定的时间,对长连接进行一次心跳检测 if (Utils.isScreenOn(SocketService.this)) { - if (mJWebSocketClient != null) { - if (mJWebSocketClient.isOpen()) { - Log.i(TAG, "websocket已连接"); - sendPingMsg(); - } else if (mJWebSocketClient.isClosed()) { - Log.i(TAG, "websocket重连中"); - reconnectWs(); + if (mOnlineJWebSocketClient != null) { + if (mOnlineJWebSocketClient.isOpen()) { + Log.i(TAG, "startOnlineLoop websocket已连接"); + sendOnlinePingMsg(); + } else if (mOnlineJWebSocketClient.isClosed()) { + Log.i(TAG, "startOnlineLoop websocket重连中"); + reconnectOnlineWs(); } } else { //如果client已为空,重新初始化连接 - initSocketClient(); + initOnlineSocketClient(); } } else { - Log.i(TAG, "websocket息屏不重连"); + Log.i(TAG, "startOnlineLoop websocket息屏不重连"); } } }); @@ -322,59 +323,60 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat /** * 初始化websocket连接 */ - private void initSocketClient() { - URI uri = URI.create(BuildConfig.WEBSOCKET_URL + "?sn=" + DeviceSNManager.getDeviceSN()); - mJWebSocketClient = new JWebSocketClient(uri) { + private void initOnlineSocketClient() { + URI uri = URI.create(UrlAddress.WEBSOCKET_URL_ONLINE + "?sn=" + DeviceSNManager.getDeviceSN()); + mOnlineJWebSocketClient = new JWebSocketClient(uri) { @Override public void onMessage(String message) { - Log.i(TAG, "onMessage: 收到服务器发来的消息:" + message); + Log.i(TAG, "Online onMessage: 收到服务器发来的消息:" + message); } @Override public void onOpen(ServerHandshake handshakedata) { super.onOpen(handshakedata); - Log.i(TAG, "onOpen: websocket连接成功"); - sendPingMsg(); + Log.i(TAG, "Online onOpen: websocket连接成功"); + sendOnlinePingMsg(); } @Override public void onClose(int code, String reason, boolean remote) { super.onClose(code, reason, remote); - Log.e(TAG, "onClose: websocket连接关闭:" + reason); - mJWebSocketClient = null; + Log.e(TAG, "Online onClose: websocket连接关闭:" + reason); + mOnlineJWebSocketClient = null; } @Override public void onError(Exception ex) { super.onError(ex); - Log.e(TAG, "onError: websocket连接错误:" + ex.getMessage()); - mJWebSocketClient = null; + Log.e(TAG, "Online onError: websocket连接错误:" + ex.getMessage()); + mOnlineJWebSocketClient = null; } }; - connect(); + connectOnlineWs(); + startOnlineLoop(); } /** * 连接websocket */ - private void connect() { + private void connectOnlineWs() { try { //connectBlocking多出一个等待操作,会先连接再发送,否则未连接发送会报错 - Log.i(TAG, "connect: websocket连接中"); - mJWebSocketClient.connectBlocking(); + Log.i(TAG, "connectOnlineWs: websocket连接中"); + mOnlineJWebSocketClient.connectBlocking(); } catch (Exception e) { - Log.i(TAG, "connect: " + e.getMessage()); + Log.i(TAG, "connectOnlineWs: " + e.getMessage()); } } /** * 开启重连 */ - private void reconnectWs() { - Log.e(TAG, "reconnectWs: "); + private void reconnectOnlineWs() { + Log.e(TAG, "reconnectOnlineWs: "); try { - Log.i(TAG, "reconnectWs: 开启重连"); - mJWebSocketClient.reconnectBlocking(); + Log.i(TAG, "reconnectOnlineWs: 开启重连"); + mOnlineJWebSocketClient.reconnectBlocking(); } catch (InterruptedException e) { e.printStackTrace(); } @@ -383,33 +385,33 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat /** * 断开连接 */ - private void closeConnect() { - Log.e(TAG, "closeConnect: "); + private void closeOnlineConnect() { + Log.e(TAG, "closeOnlineConnect: "); try { - if (null != mJWebSocketClient) { - mJWebSocketClient.close(); + if (null != mOnlineJWebSocketClient) { + mOnlineJWebSocketClient.close(); } } catch (Exception e) { e.printStackTrace(); } finally { - mJWebSocketClient = null; + mOnlineJWebSocketClient = null; } } /** * 发送消息 */ - public void sendPingMsg() { + public void sendOnlinePingMsg() { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("sn", DeviceSNManager.getDeviceSN()); jsonObject.addProperty("type", "ping"); - if (null != mJWebSocketClient) { - Log.i(TAG, "sendPingMsg: 发送的消息:" + jsonObject.toString()); - mJWebSocketClient.send(jsonObject.toString()); + if (null != mOnlineJWebSocketClient) { + Log.i(TAG, "sendOnlinePingMsg: 发送的消息:" + jsonObject.toString()); + mOnlineJWebSocketClient.send(jsonObject.toString()); } } - public void sendMsgScreen() { + public void sendOnlineMsgScreen() { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("sn", DeviceSNManager.getDeviceSN()); if (Utils.isScreenOn(SocketService.this)) { @@ -418,18 +420,170 @@ public class SocketService extends Service implements NetworkUtils.OnNetworkStat jsonObject.addProperty("type", "device_close_screen"); //熄屏状态 } - if (null != mJWebSocketClient) { - Log.i(TAG, "sendMsgScreen: 发送的消息" + jsonObject.toString()); + if (null != mOnlineJWebSocketClient) { + Log.i(TAG, "sendOnlineMsgScreen: 发送的消息" + jsonObject.toString()); try { - mJWebSocketClient.send(jsonObject.toString()); + mOnlineJWebSocketClient.send(jsonObject.toString()); } catch (Exception e) { - Log.i(TAG, "sendMsgScreen: sendMsg Exception: " + e.getLocalizedMessage()); + Log.i(TAG, "sendOnlineMsgScreen: sendMsg Exception: " + e.getLocalizedMessage()); } } else { - Log.i(TAG, "sendMsgScreen: 未连接"); - initSocketClient(); + Log.i(TAG, "sendOnlineMsgScreen: 未连接"); + initOnlineSocketClient(); } } + private Disposable mSsoDisposable; + + private void startSsoLoop() { + if (mSsoDisposable != null && !mSsoDisposable.isDisposed()) { + mSsoDisposable.dispose(); + mSsoDisposable = null; + } + mSsoDisposable = Observable.interval(30, TimeUnit.SECONDS) + .subscribe(new Consumer() { + @Override + public void accept(Long s) throws Exception { + Log.d(TAG, "startSsoLoop accept: " + s); + Log.i(TAG, "startSsoLoop 心跳包检测websocket连接状态"); + if (!ActivationUtil.getInstance().isLogin()) { + dispose(); + } + //每隔一定的时间,对长连接进行一次心跳检测 + if (Utils.isScreenOn(SocketService.this)) { + if (mSsoJWebSocketClient != null) { + if (mSsoJWebSocketClient.isOpen()) { + Log.i(TAG, "startSsoLoop websocket已连接"); + sendSsoPingMsg(); + } else if (mSsoJWebSocketClient.isClosed()) { + Log.i(TAG, "startSsoLoop websocket重连中"); + reconnectSsoWs(); + } + } else { + //如果client已为空,重新初始化连接 + initSsoSocketClient(); + } + } else { + Log.i(TAG, "startSsoLoop websocket息屏不重连"); + } + } + }); + } + + /** + * 初始化websocket连接 + */ + private void initSsoSocketClient() { + URI uri = URI.create(UrlAddress.WEBSOCKET_URL_SSO + "?sn=" + DeviceSNManager.getDeviceSN() + "&token=" + NetInterfaceManager.getInstance().getToken()); + mSsoJWebSocketClient = new JWebSocketClient(uri) { + @Override + public void onMessage(String message) { + if (BuildConfig.DEBUG) { + Log.i(TAG, "sso onMessage: 收到服务器发来的消息:" + message); + } + checkOffLine(message); + } + + @Override + public void onOpen(ServerHandshake handshakedata) { + super.onOpen(handshakedata); + Log.i(TAG, "sso onOpen: websocket连接成功"); + sendSsoPingMsg(); + } + + @Override + public void onClose(int code, String reason, boolean remote) { + super.onClose(code, reason, remote); + Log.e(TAG, "sso onClose: websocket连接关闭:" + reason); + mSsoJWebSocketClient = null; + } + + @Override + public void onError(Exception ex) { + super.onError(ex); + Log.e(TAG, "sso onError: websocket连接错误:" + ex.getMessage()); + mSsoJWebSocketClient = null; + } + }; + connectSsoWs(); + startSsoLoop(); + } + + /** + * 连接websocket + */ + private void connectSsoWs() { + try { + //connectBlocking多出一个等待操作,会先连接再发送,否则未连接发送会报错 + Log.i(TAG, "connectSsoWs: websocket连接中"); + mSsoJWebSocketClient.connectBlocking(); + } catch (Exception e) { + Log.i(TAG, "connectSsoWs: " + e.getMessage()); + } + } + + /** + * 开启重连 + */ + private void reconnectSsoWs() { + Log.e(TAG, "reconnectSsoWs: "); + try { + Log.i(TAG, "reconnectSsoWs: 开启重连"); + mSsoJWebSocketClient.reconnectBlocking(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + /** + * 断开连接 + */ + private void closeSsoConnect() { + Log.e(TAG, "closeSsoConnect: "); + try { + if (null != mSsoJWebSocketClient) { + mSsoJWebSocketClient.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + mSsoJWebSocketClient = null; + } + } + + /** + * 发送消息 + */ + public void sendSsoPingMsg() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("type", "ping"); + jsonObject.addProperty("sn", DeviceSNManager.getDeviceSN()); + jsonObject.addProperty("token", NetInterfaceManager.getInstance().getToken()); + if (null != mSsoJWebSocketClient) { + Log.i(TAG, "sendPingMsg: 发送的消息:" + jsonObject.toString()); + mSsoJWebSocketClient.send(jsonObject.toString()); + } + } + + private void checkOffLine(String jsonString) { + if (TextUtils.isEmpty(jsonString)) return; + JsonObject jsonObject = GsonUtils.getJsonObject(jsonString); + JsonElement jsonElement = jsonObject.get("type"); + if (jsonElement != null) { + String type = jsonElement.getAsString(); + if ("kick_out".equals(type)) { + ActivationUtil.getInstance().setActivation(0); + mMMKV.encode(CommonConfig.ACCOUNT_LOGIN_STATU, 0); + mMMKV.encode(CommonConfig.ACCOUNT_LOGIN_TOKEN, ""); + Toaster.showLong("请重新登录"); + Intent intent = new Intent(SocketService.this, LoginActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); +// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(intent); + dispose(); + } + } + } + } 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 e212ee0..f723398 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 @@ -1,20 +1,30 @@ package com.xwad.os.service.main; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.os.Build; import android.os.IBinder; import android.text.TextUtils; import android.util.Log; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + 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.alarm.AlarmUtils; import com.xwad.os.base.rx.BaseRxService; import com.xwad.os.bean.AlarmClockData; import com.xwad.os.config.CommonConfig; +import com.xwad.os.service.SocketService; import java.util.Calendar; import java.util.HashMap; @@ -60,6 +70,13 @@ public class MainService extends BaseRxService implements MainSContact.MainSView registerReceivers(); NetworkUtils.registerNetworkStatusChangedListener(this); startJxwLauncher(); + + mNotificationManagerCompat = NotificationManagerCompat.from(this); + createNotificationChannel(); +// showNotification(); + sendSimpleNotification(); + + startService(new Intent(MainService.this, SocketService.class)); } @Override @@ -76,6 +93,45 @@ public class MainService extends BaseRxService implements MainSContact.MainSView unregisterReceiver(); } + private static final String CHANNEL_ID = "CHANNEL_ID"; + private static final String CHANNEL_NAME = "系统通知"; + private static final String CHANNEL_DESCRIPTION = "学王365通知"; + + private void createNotificationChannel() { + // Create the NotificationChannel, but only on API 26+ because + // the NotificationChannel class is new and not in the support library + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); + channel.setDescription(CHANNEL_DESCRIPTION); + // Register the channel with the system; you can't change the importance + // or other notification behaviors after this + NotificationManager notificationManager = getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(channel); + } + } + + private NotificationManagerCompat mNotificationManagerCompat; + private int NotificationID = 1; + + private void sendSimpleNotification() { + Intent intent = new Intent(this, MainActivity.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) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("学王365正在运行") +// .setContentText("测试内容") + .setAutoCancel(false) + .setShowWhen(false) + .setContentIntent(pendingIntent) + .setOngoing(true) + .setOnlyAlertOnce(true) + .setPriority(NotificationCompat.PRIORITY_MAX); + // notificationId is a unique int for each notification that you must define +// mNotificationManagerCompat.notify(NotificationID, builder.build()); + startForeground(NotificationID, builder.build()); + } + private void startJxwLauncher() { // ComponentName cn = new ComponentName(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME, JxwPackageConfig.JXW_LAUNCHER_CLASS_NAME); // Intent intent = new Intent(); 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 9f90fa3..5ec7a6e 100644 --- a/app/src/main/java/com/xwad/os/utils/ActivationUtil.java +++ b/app/src/main/java/com/xwad/os/utils/ActivationUtil.java @@ -8,6 +8,7 @@ import android.util.Log; import com.tencent.mmkv.MMKV; import com.xwad.os.config.CommonConfig; +import com.xwad.os.jxw.JxwPackageConfig; import com.xwad.os.service.main.MainService; public class ActivationUtil { @@ -112,18 +113,23 @@ public class ActivationUtil { return mMMKV.decodeLong(CommonConfig.UIUI_EXPIRE_TIME_KEY, DEFAULT_EXPIRE_TIME); } + public String getActivationCode() { + return mMMKV.decodeString(CommonConfig.ACTIVATIONBEAN_CODE_KEY, ""); + } + public boolean isLogin() { return mMMKV.decodeInt(CommonConfig.ACCOUNT_LOGIN_STATU, 0) == 1; } public void startJxwLauncher() { - String code = mMMKV.decodeString(CommonConfig.ACTIVATIONBEAN_CODE_KEY, ""); + String code = getActivationCode(); boolean regist_success = mMMKV.decodeBool(MainService.JXW_REGISTER_SUCCESS, false); if (!regist_success) { Intent intent = new Intent("UIUI_ACTIVATION"); - ComponentName componentName = new ComponentName("com.jxw.launcher", "com.jxw.engine.platsign.MainActivity"); + ComponentName componentName = new ComponentName(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME, JxwPackageConfig.JXW_LAUNCHER_DUMMY_ACTIVITY); intent.setComponent(componentName); - intent.putExtra("uiui_activation_code", code); +// intent.putExtra("uiui_activation_code", code); + intent.putExtra("series", code); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { mContext.startActivity(intent); diff --git a/app/src/main/java/com/xwad/os/utils/JxwUtils.java b/app/src/main/java/com/xwad/os/utils/JxwUtils.java new file mode 100644 index 0000000..20eea57 --- /dev/null +++ b/app/src/main/java/com/xwad/os/utils/JxwUtils.java @@ -0,0 +1,87 @@ +package com.xwad.os.utils; + +import android.util.Log; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +public class JxwUtils { + private static final String TAG = "JxwUtils"; + + static { + System.loadLibrary("xuewang"); // 加载 libjniutils.so + } + + // 声明为Native方法 + public static native String getAppId(); + + public static native String getAppSecret(); + + public static String getSignature(Map paramMap) { + long timeStamp = System.currentTimeMillis(); + //用于获取signature + SortedMap items = new TreeMap<>(); + items.put("nonce", "X6SH3YeRTs"); + items.put("appId", JxwUtils.getAppId()); + items.put("appsecret", JxwUtils.getAppSecret()); + items.put("timestamp", String.valueOf(timeStamp)); +// items.putAll(paramMap); + +// items.put("其它参数", "其它参数的值"); + String signature = signature(items); + Log.e(TAG, "userScore: " + signature); + + +// //请求参数设置 +// Map paramMap = new HashMap<>(); +// paramMap.put("nonce", "X6SH3YeRTs"); +// paramMap.put("appId", JxwUtils.getAppId()); +// paramMap.put("signature", signature); +// paramMap.put("timestamp", String.valueOf(timeStamp)); +//// paramMap.put("其它参数", "其它参数的值"); + + return signature; + } + + public static String signature(SortedMap items) { + StringBuilder forSign = new StringBuilder(); + + for (String key : items.keySet()) { + forSign.append(key).append("=").append(items.get(key)).append("&"); + } + + forSign.setLength(forSign.length() - 1); + + return encryptSHA1(forSign.toString()); + } + + public static String encryptSHA1(String content) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + digest.update(content.getBytes(StandardCharsets.UTF_8)); + byte[] messageDigest = digest.digest(); + StringBuilder hexString = new StringBuilder(); + + for (byte b : messageDigest) { + String shaHex = Integer.toHexString(b & 0xFF); + + if (shaHex.length() < 2) { + hexString.append(0); + } + + hexString.append(shaHex); + } + + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + return null; + } + +} 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 e62dbb4..cf16262 100644 --- a/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java +++ b/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java @@ -15,7 +15,6 @@ import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.TextView; @@ -24,7 +23,10 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.hjq.toast.Toaster; import com.tencent.mmkv.MMKV; +import com.xwad.os.BuildConfig; import com.xwad.os.R; +import com.xwad.os.activity.activation.ActivationActivity; +import com.xwad.os.activity.login.LoginActivity; import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.BaseResponse; import com.xwad.os.bean.LessonJson; @@ -34,6 +36,7 @@ import com.xwad.os.jxw.SPUtils; import com.xwad.os.manager.RemoteManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.service.DownloadService; +import com.xwad.os.view.jxw.widget.DefaultAppsDialog; import java.lang.reflect.Type; import java.math.BigDecimal; @@ -658,17 +661,44 @@ public class OpenApkUtils { return false; } + public void openJxwAppWithParam(Activity activity, String paramStr, boolean checkInstall) { + if (checkInstall) { + if (!ApkUtils.isAvailable(activity, "com.jxw.launcher") || !ApkUtils.isAvailable(activity, "com.jxw.download")) { + DefaultAppsDialog appsDialog = new DefaultAppsDialog(activity); + appsDialog.show(); + Toaster.show("请先安装必备组件"); + return; + } + } + +// if (!BuildConfig.DEBUG){ + if (!ActivationUtil.getInstance().isLogin()) { + Toaster.show("请先登录"); + activity.startActivity(new Intent(activity, LoginActivity.class)); + return; + } + + if (!ActivationUtil.getInstance().isActivation()) { + Toaster.show("请先激活后使用"); + activity.startActivity(new Intent(activity, ActivationActivity.class)); + return; + } + + if (TextUtils.isEmpty(paramStr)) { + Log.e(TAG, "context为空或参数字符串为空"); + return; + } +// } + + openJxwApp(activity, paramStr); + } + /** * 根据参数字符串打开对应页面 * * @param paramStr 参数字符串(格式:包名,类名,extra参数,第四项,第五项) */ public void openJxwApp(Activity activity, String paramStr) { - if (TextUtils.isEmpty(paramStr)) { - Log.e(TAG, "context为空或参数字符串为空"); - return; - } - // 1. 按逗号分割整体参数(保留空项,避免丢失字段) String[] totalParts = paramStr.split(",", -1); if (totalParts.length < 2) { // 至少需要包名+类名 @@ -877,6 +907,7 @@ public class OpenApkUtils { this.add("com.hihonor.deskclock"); this.add("com.huawei.deskclock"); this.add("com.coloros.alarmclock"); + this.add("com.zui.deskclock"); this.add("com.android.BBKClock"); }}; @@ -896,6 +927,7 @@ public class OpenApkUtils { this.add("com.huawei.calculator"); this.add("com.miui.calculator"); this.add("com.coloros.calculator"); + this.add("com.zui.calculator"); this.add("com.android.bbkcalculator"); }}; @@ -911,9 +943,13 @@ public class OpenApkUtils { public String getCameraPackageName() { List pkgList = new ArrayList() {{ this.add("com.android.camera"); + this.add("com.android.camera2"); + this.add("com.mediatek.camera"); + this.add("com.softwinner.camera"); this.add("com.hihonor.camera"); this.add("com.huawei.camera"); this.add("com.oplus.camera"); + this.add("com.zui.camera"); }}; Optional optional = pkgList.stream().filter(new Predicate() { @@ -933,6 +969,7 @@ public class OpenApkUtils { this.add("com.miui.gallery"); this.add("com.coloros.gallery3d"); this.add("com.vivo.gallery"); + this.add("com.zui.gallery"); }}; Optional optional = pkgList.stream().filter(new Predicate() { diff --git a/app/src/main/java/com/xwad/os/view/jxw/widget/AppsDialog.java b/app/src/main/java/com/xwad/os/view/jxw/widget/AppsDialog.java index 1587c0c..8f3babc 100644 --- a/app/src/main/java/com/xwad/os/view/jxw/widget/AppsDialog.java +++ b/app/src/main/java/com/xwad/os/view/jxw/widget/AppsDialog.java @@ -188,7 +188,7 @@ public class AppsDialog extends Dialog { } // MyApp.getInstance().mBottomBtnOnClickListener.setContext(activity); // MyApp.getInstance().mBottomBtnOnClickListener.onClick(viewTag); - OpenApkUtils.getInstance().openJxwApp(activity, viewTag); + OpenApkUtils.getInstance().openJxwAppWithParam(activity, viewTag, true); } } diff --git a/app/src/main/java/com/xwad/os/view/jxw/widget/DefaultAppsDialog.java b/app/src/main/java/com/xwad/os/view/jxw/widget/DefaultAppsDialog.java index 906788d..a0fb27a 100644 --- a/app/src/main/java/com/xwad/os/view/jxw/widget/DefaultAppsDialog.java +++ b/app/src/main/java/com/xwad/os/view/jxw/widget/DefaultAppsDialog.java @@ -6,13 +6,14 @@ import android.content.Context; import android.graphics.Point; import android.os.Bundle; import android.text.TextUtils; +import android.util.Log; import android.view.Display; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; -import android.widget.RelativeLayout; import android.widget.TextView; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; @@ -20,12 +21,15 @@ import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.BaseViewHolder; import com.xwad.os.R; import com.xwad.os.bean.jxw.ItemsBean; +import com.xwad.os.utils.ApkUtils; import com.xwad.os.utils.OpenApkUtils; import java.util.ArrayList; import java.util.List; public class DefaultAppsDialog extends Dialog { + private static final String TAG = "DefaultAppsDialog"; + private Activity activity; private AppAdapter appAdapter; @@ -61,7 +65,7 @@ public class DefaultAppsDialog extends Dialog { } private void initView() { - GridLayoutManager gridLayoutManager = new GridLayoutManager(activity, 2); + GridLayoutManager gridLayoutManager = new GridLayoutManager(activity, 3); rv_apps = findViewById(R.id.rv_apps); appAdapter = new AppAdapter(getDefaultApps()); rv_apps.setLayoutManager(gridLayoutManager); @@ -86,10 +90,19 @@ public class DefaultAppsDialog extends Dialog { @Override public void convert(BaseViewHolder baseViewHolder, final ItemsBean itemsBean) { - RelativeLayout relativeLayout = baseViewHolder.getView(R.id.rl_root); - ((ImageView) baseViewHolder.getView(R.id.iv_app_icon)).setImageResource(mContext.getResources().getIdentifier(itemsBean.getIcon(), "drawable", mContext.getPackageName())); - ((TextView) baseViewHolder.getView(R.id.tv_app_name)).setText(itemsBean.getText()); - relativeLayout.setOnClickListener(new View.OnClickListener() { + ConstraintLayout constraintLayout = baseViewHolder.getView(R.id.rl_root); + ImageView iv_download = baseViewHolder.getView(R.id.iv_download); + if (ApkUtils.isAvailable(mContext, getPackageName(itemsBean.getTag()))) { + iv_download.setVisibility(View.GONE); + } else { + iv_download.setVisibility(View.VISIBLE); + } + ImageView iv_app_icon = baseViewHolder.getView(R.id.iv_app_icon); + iv_app_icon.setImageResource(mContext.getResources().getIdentifier(itemsBean.getIcon(), "drawable", mContext.getPackageName())); + TextView tv_app_name = baseViewHolder.getView(R.id.tv_app_name); + tv_app_name.setText(itemsBean.getText()); + + constraintLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { jumpTag(itemsBean); @@ -98,6 +111,15 @@ public class DefaultAppsDialog extends Dialog { } } + private String getPackageName(String tag) { + if (TextUtils.isEmpty(tag)) { + return ""; + } + String pkg = tag.substring(0, tag.indexOf(",")); + Log.e(TAG, "getPackageName: " + pkg); + return pkg; + } + public void jumpTag(ItemsBean itemsBean) { if (activity != null) { Callback callback = mCallback; @@ -106,14 +128,15 @@ public class DefaultAppsDialog extends Dialog { } // MyApp.getInstance().mBottomBtnOnClickListener.setContext(activity); // MyApp.getInstance().mBottomBtnOnClickListener.onClick(viewTag); - OpenApkUtils.getInstance().openJxwApp(activity, itemsBean.getTag()); + OpenApkUtils.getInstance().openJxwAppWithParam(activity, itemsBean.getTag(), false); } } private List getDefaultApps() { List itemsBeans = new ArrayList<>(); - itemsBeans.add(new ItemsBean("icon_bbx_launcher", "", "com.jxw.launcher,,,,资源下载", "资源下载")); - itemsBeans.add(new ItemsBean("icon_bbx_player", "", "com.study.flashplayer,,,,播放器", "播放器")); + itemsBeans.add(new ItemsBean("icon_bbx_launcher", "", "com.jxw.launcher,com.jxw.launcher.DummyActivity,,,许可证校验", "许可证校验")); + itemsBeans.add(new ItemsBean("icon_bbx_xzzx", "", "com.jxw.download,com.jxw.download.main.ui.HomeActivity,,,下载中心", "下载中心")); + itemsBeans.add(new ItemsBean("icon_bbx_player", "", "com.study.flashplayer,,,,Flash播放器", "Flash播放器")); return itemsBeans; } } \ No newline at end of file diff --git a/app/src/main/jni/xuewang.cpp b/app/src/main/jni/xuewang.cpp new file mode 100644 index 0000000..f5149e5 --- /dev/null +++ b/app/src/main/jni/xuewang.cpp @@ -0,0 +1,26 @@ +// +// Created by TT on 2025/12/29. +// + +#include +#include +#include +// 日志打印 +#include + +#define LOG_TAG "TAG_LOG" +#define LOGI(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +extern "C" +JNIEXPORT jstring JNICALL +Java_com_xwad_os_utils_JxwUtils_getAppId(JNIEnv *env, jclass thiz) { + std::string key = "hlhdpb"; + return env->NewStringUTF(key.c_str()); +} + +extern "C" +JNIEXPORT jstring JNICALL +Java_com_xwad_os_utils_JxwUtils_getAppSecret(JNIEnv *env, jclass thiz) { + std::string key = "WDNUnYMNL33lqlGIIZB"; + return env->NewStringUTF(key.c_str()); +} \ No newline at end of file diff --git a/app/src/main/res/drawable-nodpi/icon_jxw_aizndy.png b/app/src/main/res/drawable-nodpi/icon_jxw_aizndy.png new file mode 100644 index 0000000..6f2c154 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icon_jxw_aizndy.png differ diff --git a/app/src/main/res/drawable-nodpi/icon_jxw_launcher.png b/app/src/main/res/drawable-nodpi/icon_jxw_launcher.png new file mode 100644 index 0000000..153e202 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/icon_jxw_launcher.png differ diff --git a/app/src/main/res/drawable/ic_download.xml b/app/src/main/res/drawable/ic_download.xml new file mode 100644 index 0000000..ea2ffa7 --- /dev/null +++ b/app/src/main/res/drawable/ic_download.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index 3b6b3c2..aee66b2 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -146,7 +146,9 @@ @@ -194,19 +194,23 @@ app:layout_constraintStart_toEndOf="@+id/view2" app:layout_constraintTop_toTopOf="parent" /> - + - + diff --git a/app/src/main/res/layout/activity_login_successful.xml b/app/src/main/res/layout/activity_login_successful.xml index ca796bf..5ef8fd9 100644 --- a/app/src/main/res/layout/activity_login_successful.xml +++ b/app/src/main/res/layout/activity_login_successful.xml @@ -34,7 +34,8 @@ app:layout_constraintBottom_toTopOf="@+id/constraintLayout17" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.333" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_dialog_login_statu.xml b/app/src/main/res/layout/fragment_dialog_login_statu.xml index a0f11cc..983ba21 100644 --- a/app/src/main/res/layout/fragment_dialog_login_statu.xml +++ b/app/src/main/res/layout/fragment_dialog_login_statu.xml @@ -50,6 +50,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:layout_marginBottom="24dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@+id/constraintLayout15"> @@ -78,6 +79,7 @@ + + + + @@ -60,6 +66,8 @@ android:layout_height="48dp" android:layout_marginStart="16dp" android:src="@drawable/default_avatar" + app:error="@{@drawable/default_avatar}" + app:imageUrl="@{userAvatarInfo.avatar}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -98,9 +106,10 @@ android:layout_height="wrap_content" android:ellipsize="marquee" android:singleLine="true" - android:text="@string/default_nickname" + android:text="@{userAvatarInfo==null?@string/default_nickname:userAvatarInfo.sn_name}" android:textColor="@color/white" - android:textSize="9sp" /> + android:textSize="9sp" + tools:text="@string/default_nickname" /> + android:tag="@string/tag_args_new_arzd" + android:visibility="gone"> + + + + + + + + + + + + + android:tag="@string/tag_args_updae" + android:visibility="gone"> + android:tag="@string/tag_args_new_jzgk" + android:visibility="gone"> + android:tag="@string/tag_args_new_yjjs" + android:visibility="gone"> - @@ -8,17 +9,33 @@ android:id="@+id/iv_app_icon" android:layout_width="28dp" android:layout_height="28dp" - android:layout_centerHorizontal="true" /> + android:layout_marginTop="8dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + - \ No newline at end of file + android:textSize="9sp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/iv_app_icon" /> + \ No newline at end of file diff --git a/app/src/main/res/layout/item_tab.xml b/app/src/main/res/layout/item_tab.xml index 4504f96..6919f80 100644 --- a/app/src/main/res/layout/item_tab.xml +++ b/app/src/main/res/layout/item_tab.xml @@ -4,8 +4,8 @@ android:layout_width="wrap_content" android:layout_height="34dp" android:orientation="vertical" - android:paddingStart="9dp" - android:paddingRight="9dp"> + android:paddingStart="6dp" + android:paddingRight="6dp"> com.jxw.tbdd,com.jxw.yyhb.ui.activity.MainActivity,int:subject:1,jxwgb_6.0_tbdd,同步点读 com.jxw.question,com.jxw.question.module.ui.activity.ProgramEntryActivity,,jxwgb_6.0_tiku_xiaodu,题库 com.jxw.zjcc,com.jxw.zjcc.MainActivity,,jxwgb_6.0_xwzdtl,指尖查词 + com.jxw.launcher,com.jxw.launcher.DummyActivity,,,许可证 com.jxw.launcher,com.jxw.update.UpdateNewActivity,,,应用更新 com.jxw.launcher,com.jxw.launcher.XtazActivity,,,系统安装 com.tencent.mm,com.tencent.mm.ui.LauncherUI,,,微信