version:1.2.0

fix:
update:优化登录和激活逻辑
This commit is contained in:
2026-01-06 09:34:39 +08:00
parent ee4c05b438
commit 6c28512c1a
64 changed files with 1570 additions and 337 deletions

44
app/CMakeLists.txt Normal file
View File

@@ -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})

View File

@@ -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 {

View File

@@ -262,6 +262,19 @@
</intent-filter>
</receiver>
<service
android:name=".service.main.MainService"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<data android:scheme="package" />
</intent-filter>
</service>
<receiver
android:name=".receiver.InstallResultReceiver"
android:enabled="true"
@@ -271,6 +284,7 @@
android:name=".alarm.AlarmService"
android:enabled="true"
android:exported="true" />
<service
android:name=".service.SocketService"
android:exported="true">
@@ -286,18 +300,7 @@
<data android:scheme="package" />
</intent-filter>
</service>
<!-- <service-->
<!-- android:name=".service.main.MainService"-->
<!-- android:enabled="true"-->
<!-- android:exported="true">-->
<!-- <intent-filter android:priority="1000">-->
<!-- <action android:name="android.intent.action.USER_PRESENT" />-->
<!-- <action android:name="android.intent.action.SCREEN_ON" />-->
<!-- <action android:name="android.intent.action.SCREEN_OFF" />-->
<!-- <data android:scheme="package" />-->
<!-- </intent-filter>-->
<!-- </service>-->
<!-- <service-->
<!-- android:name=".service.NotificationService"-->
@@ -313,7 +316,7 @@
android:exported="true" />
<receiver
android:name=".receiver.APKinstallReceiver"
android:name=".receiver.ApkInstallReceiver"
android:enabled="true"
android:exported="true"
android:permission="com.example.broadcast.permission">

View File

@@ -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<ActivationViewModel, ActivityActivationBinding> {
private Disposable pollingDisposable;
@Override
protected int getLayoutId() {
@@ -100,6 +110,12 @@ public class ActivationActivity extends BaseMvvmActivity<ActivationViewModel, Ac
}
}
});
mViewModel.mAlreadyActivatedData.observe(this, new Observer<Boolean>() {
@Override
public void onChanged(Boolean aBoolean) {
finish();
}
});
mViewModel.mPayInfoData.observe(this, new Observer<PayInfo>() {
@Override
@@ -129,10 +145,42 @@ public class ActivationActivity extends BaseMvvmActivity<ActivationViewModel, Ac
if (aBoolean) {
ActivationUtil.getInstance().startJxwLauncher();
finish();
startActivity(new Intent(ActivationActivity.this, LoginSuccessfulActivity.class));
// startHome();
}
}
});
startPolling();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (pollingDisposable != null && pollingDisposable.isDisposed()) {
pollingDisposable.dispose();
pollingDisposable = null;
}
}
public void startPolling() {
pollingDisposable = Observable.interval(0, 5, TimeUnit.SECONDS) // 立即开始每5秒执行
.subscribeOn(Schedulers.io()) // 在IO线程执行轮询
.observeOn(AndroidSchedulers.mainThread()) // 在主线程处理结果
.subscribe(tick -> {
// 此处执行轮询任务,例如网络请求
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 {

View File

@@ -74,6 +74,7 @@ public class ActivationViewModel extends BaseViewModel<ActivityActivationBinding
}
public MutableLiveData<OrderInfo> mOrderInfoData = new MutableLiveData<>();
public MutableLiveData<Boolean> mAlreadyActivatedData = new MutableLiveData<>();
public void getPayInfo(String vipId) {
NetInterfaceManager.getInstance().getBuyVipControl(vipId)
@@ -90,6 +91,10 @@ public class ActivationViewModel extends BaseViewModel<ActivityActivationBinding
if (baseResponse.code == 200) {
OrderInfo orderInfo = baseResponse.data;
mOrderInfoData.setValue(orderInfo);
} else if (baseResponse.code == 4009) {
ActivationUtil.getInstance().setActivation(1);
mAlreadyActivatedData.setValue(true);
} else {
Toaster.show(baseResponse.msg);
}
@@ -190,8 +195,8 @@ public class ActivationViewModel extends BaseViewModel<ActivityActivationBinding
if (baseResponse.code == 200) {
CodeBean codeBean = baseResponse.data;
mMMKV.encode(CommonConfig.ACTIVATIONBEAN_CODE_KEY, codeBean.getCode());
mGetCodeData.setValue(true);
ActivationUtil.getInstance().setActivation(1);
mGetCodeData.setValue(true);
} else {
ActivationUtil.getInstance().setActivation(0);
}

View File

@@ -76,7 +76,7 @@ public class EditActivity extends BaseMvvmActivity<EditViewModel, ActivityEditBi
mViewDataBinding.tvTitle.setText("请输入年级");
break;
case CommonConfig.UIUI_USER_CLASS_KEY:
mKey = "class";
mKey = "class_name";
mViewDataBinding.tvTitle.setText("请输入班级");
break;
default:

View File

@@ -18,7 +18,6 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.RelativeLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -35,6 +34,7 @@ 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.activity.permission.PermissionActivity;
import com.xwad.os.activity.update.UpdateActivity;
@@ -54,22 +54,23 @@ import com.xwad.os.fragment.english.EnglishFragment;
import com.xwad.os.fragment.math.MathFragment;
import com.xwad.os.fragment.mine.MineFragment;
import com.xwad.os.fragment.read.ReadFragment;
import com.xwad.os.fragment.safe.SafeFragment;
import com.xwad.os.jxw.JxwPackageConfig;
import com.xwad.os.jxw.SPUtils;
import com.xwad.os.jxw.StudyRecordAPKInfo;
import com.xwad.os.jxw.TabAdapter;
import com.xwad.os.jxw.event.UpdateColorEvent;
import com.xwad.os.jxw.util.Util;
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.DeviceSNManager;
import com.xwad.os.manager.RemoteManager;
import com.xwad.os.service.main.MainService;
import com.xwad.os.utils.ActivationUtil;
import com.xwad.os.utils.ApkUtils;
import com.xwad.os.utils.DataUtil;
import com.xwad.os.utils.OpenApkUtils;
import com.xwad.os.utils.Utils;
import com.xwad.os.view.jxw.widget.DefaultAppsDialog;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -131,12 +132,21 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
EventBus.getDefault().register(this);
}
Intent intent = new Intent(HomeActivity.this, MainService.class);
if (Build.VERSION.SDK_INT >= 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<HomeViewModel, ActivityHomeBi
@Override
public void onChanged(Boolean aBoolean) {
if (aBoolean) {
// if (!BuildConfig.DEBUG) {
ActivationUtil.getInstance().startJxwLauncher();
// }
}
}
});
@@ -235,6 +247,11 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
}
});
mViewModel.getUserInfo();
mViewModel.getSystemSettings();
mViewModel.getOauthToken();
mViewModel.getAnswerControlStatus();
initDatas();
}
@@ -374,6 +391,10 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
// mMainFragment.setCurrentItem();
// mViewPager.setCurrentItem(defaultCurrent);
break;
case "show_activation_dialog":
DefaultAppsDialog appsDialog = new DefaultAppsDialog(this);
appsDialog.show();
break;
default:
}
}
@@ -685,13 +706,37 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
public void onClick(View view) {
Log.e(TAG, "onClick: " + view.getTag());
OpenApkUtils.getInstance().openJxwApp(this, (String) view.getTag());
// if (!ActivationUtil.getInstance().isLogin()) {
// Toaster.show("请先登录");
// startActivity(new Intent(HomeActivity.this, LoginActivity.class));
// return;
// }
//
// if (!ActivationUtil.getInstance().isActivation()) {
// Toaster.show("请先激活后使用");
// startActivity(new Intent(HomeActivity.this, ActivationActivity.class));
// return;
// }
OpenApkUtils.getInstance().openJxwAppWithParam(this, (String) view.getTag(), true);
// MyApp.getInstance().mBottomBtnOnClickListener.setContext(this);
// MyApp.getInstance().mBottomBtnOnClickListener.onClick((String) view.getTag());
}
public void onGoJzx(View view) {
if (!ActivationUtil.getInstance().isLogin()) {
Toaster.show("请先登录");
startActivity(new Intent(HomeActivity.this, LoginActivity.class));
return;
}
if (!ActivationUtil.getInstance().isActivation()) {
Toaster.show("请先激活后使用");
startActivity(new Intent(HomeActivity.this, ActivationActivity.class));
return;
}
Log.e(TAG, "onGoJzx: " + view.getTag());
try {
int parseInt = Integer.parseInt(view.getTag().toString().split("\\|")[0]);
@@ -709,6 +754,18 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
}
public void onGoSjzx(View view) {
if (!ActivationUtil.getInstance().isLogin()) {
Toaster.show("请先登录");
startActivity(new Intent(HomeActivity.this, LoginActivity.class));
return;
}
if (!ActivationUtil.getInstance().isActivation()) {
Toaster.show("请先激活后使用");
startActivity(new Intent(HomeActivity.this, ActivationActivity.class));
return;
}
Log.e(TAG, "onGoSjzx: " + view.getTag());
try {
int parseInt = Integer.parseInt(view.getTag().toString().split("\\|")[0]);
@@ -722,7 +779,6 @@ public class HomeActivity extends BaseMvvmActivity<HomeViewModel, ActivityHomeBi
}
}
public class BtnClick {
public void exit(View view) {
lazyExit();

View File

@@ -108,6 +108,7 @@ public class HomeViewModel extends BaseViewModel<ActivityHomeBinding, ActivityEv
Log.e("getSystemSettings", "onNext: " + systemSettingsBaseResponse);
if (systemSettingsBaseResponse.code == 200) {
SystemSettings systemSettings = systemSettingsBaseResponse.data;
mMMKV.encode(CommonConfig.APP_INSTALLATION, systemSettings.getSetting_other_appInstaller());
mSystemSettingsMutableLiveData.setValue(systemSettings);
}
}
@@ -287,8 +288,10 @@ public class HomeViewModel extends BaseViewModel<ActivityHomeBinding, ActivityEv
Log.e("getUserInfo", "onNext: " + userInfoBaseResponse);
if (userInfoBaseResponse.code == 200) {
UserInfo userInfo = userInfoBaseResponse.data;
mUserInfoData.setValue(userInfo);
} else if (userInfoBaseResponse.code == 401) {
ActivationUtil.getInstance().setActivation(0);
mMMKV.encode(CommonConfig.ACCOUNT_LOGIN_STATU, 0);
}
}
@@ -304,4 +307,54 @@ public class HomeViewModel extends BaseViewModel<ActivityHomeBinding, ActivityEv
});
}
public void getOauthToken() {
NetInterfaceManager.getInstance().getOauthTokenObservable()
.subscribe(new Observer<BaseResponse>() {
@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<BaseResponse>() {
@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: ");
}
});
}
}

View File

@@ -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<LoginViewModel, ActivityLoginBinding> {
private Disposable mDisposable;
@Override
protected int getLayoutId() {
return R.layout.activity_login;
@@ -40,24 +55,88 @@ public class LoginActivity extends BaseMvvmActivity<LoginViewModel, ActivityLogi
@Override
public void onChanged(LoginInfo loginInfo) {
Toaster.show("登录成功");
startService(new Intent(LoginActivity.this, SocketService.class).setAction(SocketService.LOGIN_SUCCESSFUL));
Intent intent = new Intent();
setResult(Activity.RESULT_OK, intent);
finish();
}
});
mViewModel.mSentSuccessfullyData.observe(this, new Observer<Boolean>() {
@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<Long>() {
@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);

View File

@@ -56,6 +56,7 @@ public class LoginViewModel extends BaseViewModel<ActivityLoginBinding, Activity
@Override
public void onError(@NonNull Throwable e) {
Log.e("getPhoneCode", "onError: " + e.getMessage());
mSentSuccessfullyData.setValue(false);
}
@Override

View File

@@ -1,8 +1,11 @@
package com.xwad.os.activity.login.result;
import android.content.Intent;
import android.view.View;
import com.xwad.os.R;
import com.xwad.os.activity.home.HomeActivity;
import com.xwad.os.base.mvvm.BaseMvvmActivity;
import com.xwad.os.databinding.ActivityLoginBinding;
import com.xwad.os.databinding.ActivityLoginSuccessfulBinding;
public class LoginSuccessfulActivity extends BaseMvvmActivity<LoginSuccessfulViewModel, ActivityLoginSuccessfulBinding> {
@@ -30,8 +33,24 @@ public class LoginSuccessfulActivity extends BaseMvvmActivity<LoginSuccessfulVie
}
public class BtnClick {
@Override
protected void onDestroy() {
super.onDestroy();
startHome();
}
private void startHome() {
Intent intent = new Intent(LoginSuccessfulActivity.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 {
public void toHome(View view) {
finish();
}
}
}

View File

@@ -120,13 +120,6 @@ public class MainActivity extends BaseMvvmActivity<MainViewModel, ActivityMainBi
Utils.getAndroiodScreenProperty(this);
Intent intent = new Intent(MainActivity.this, SocketService.class);
if (Build.VERSION.SDK_INT >= 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) {

View File

@@ -178,6 +178,7 @@ public class UserActivity extends BaseMvvmActivity<UserViewModel, ActivityUserBi
public void onChanged(Boolean aBoolean) {
if (aBoolean) {
Toaster.show("更新成功");
mViewModel.getUserAvatarInfo();
}
}
});
@@ -284,10 +285,10 @@ public class UserActivity extends BaseMvvmActivity<UserViewModel, ActivityUserBi
}
MediaType mediaType = MediaType.Companion.parse("image/png");
RequestBody requestBody = RequestBody.Companion.create(avatarFile, mediaType);
MultipartBody.Part body = MultipartBody.Part.createFormData("avatar", avatarFile.getName(), requestBody);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", avatarFile.getName(), requestBody);
Map<String, RequestBody> 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);
}

View File

@@ -139,5 +139,44 @@ public class UserViewModel extends BaseViewModel<ActivityUserBinding, ActivityEv
Log.e("updateInfo", "onComplete: ");
}
});
}
public void updateAvatar(Map<String, RequestBody> params, MultipartBody.Part multipartBody) {
if (!ActivationUtil.getInstance().isLogin()) {
return;
}
NetInterfaceManager.getInstance().getupdateAvatarObservable(params, multipartBody)
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
.subscribe(new Observer<BaseResponse>() {
@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: ");
}
});
}
}

View File

@@ -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<AppAdapter.AppHolder> {
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<DesktopIcon> 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<AppAdapter.AppHolder> {
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<AppAdapter.AppHolder> {
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<AppAdapter.AppHolder> {
if (is_activation) {
mContext.startActivity(new Intent(mContext, ExitActivity.class));
} else {
Utils.exitDesktop((Activity) mContext);
Utils.exitDesktop(mContext);
}
}

View File

@@ -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<FileAdapter.AppHolder> {
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<DesktopIcon> desktopIcons;
@NonNull
@@ -98,7 +100,7 @@ public class FileAdapter extends RecyclerView.Adapter<FileAdapter.AppHolder> {
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 {

View File

@@ -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);

View File

@@ -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() {

View File

@@ -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";
}

View File

@@ -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();
}

View File

@@ -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);
}
}
}

View File

@@ -104,27 +104,34 @@ public class AppViewModel extends BaseViewModel<FragmentAppBinding, FragmentEven
DesktopIcon clockIcon = new DesktopIcon();
clockIcon.setLable("时钟");
clockIcon.setPackageName(OpenApkUtils.getInstance().getDeskClockPackageName());
clockIcon.setIcon(ApkUtils.getAppDrawable(getCtx(), OpenApkUtils.getInstance().getDeskClockPackageName()));
clockIcon.setIcon(getCtx().getDrawable(R.drawable.com_android_deskclock));
desktopIcons.add(clockIcon);
DesktopIcon calcIcon = new DesktopIcon();
calcIcon.setLable("计算器");
calcIcon.setPackageName(OpenApkUtils.getInstance().getCalculatorPackageName());
calcIcon.setIcon(ApkUtils.getAppDrawable(getCtx(), OpenApkUtils.getInstance().getCalculatorPackageName()));
calcIcon.setIcon(getCtx().getDrawable(R.drawable.com_android_calculator2));
desktopIcons.add(calcIcon);
DesktopIcon cameraIcon = new DesktopIcon();
cameraIcon.setLable("相机");
cameraIcon.setPackageName(OpenApkUtils.getInstance().getCameraPackageName());
cameraIcon.setIcon(ApkUtils.getAppDrawable(getCtx(), OpenApkUtils.getInstance().getCameraPackageName()));
cameraIcon.setIcon(getCtx().getDrawable(R.drawable.com_android_camera));
desktopIcons.add(cameraIcon);
DesktopIcon galleryIcon = new DesktopIcon();
galleryIcon.setLable("图库");
galleryIcon.setPackageName(OpenApkUtils.getInstance().getGalleryPackageName());
galleryIcon.setIcon(ApkUtils.getAppDrawable(getCtx(), OpenApkUtils.getInstance().getGalleryPackageName()));
galleryIcon.setIcon(getCtx().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(getCtx().getDrawable(R.drawable.icon_jxw_aizndy));
desktopIcons.add(desktopIcons.size(), AiAppIcon);
DesktopIcon AddAppIcon = new DesktopIcon();
AddAppIcon.setLable("添加应用");
AddAppIcon.setPackageName(AppManager.ADD_NAME);

View File

@@ -315,7 +315,7 @@ public class ChineseFragment extends BaseMvvmFragment<ChineseViewModel, Fragment
contentAdapter.notifyDataSetChanged();
// MyApp.getInstance().mBottomBtnOnClickListener.setContext(getActivity());
// MyApp.getInstance().mBottomBtnOnClickListener.onClick(obj);
OpenApkUtils.getInstance().openJxwApp(mContext, obj);
OpenApkUtils.getInstance().openJxwAppWithParam(mContext, obj, true);
}
private void saveTag(ItemsBean itemsBean) {

View File

@@ -219,13 +219,13 @@ public class EnglishFragment extends BaseMvvmFragment<EnglishViewModel, Fragment
private void load() {
TbddBookBean tbddData = TbddProviderUtil.getTbddData("英语", "", "");
if (tbddData != null) {
mViewDataBinding.ivZb.setVisibility(View.VISIBLE);
Glide.with(mContext).load(tbddData.getCoverUrl()).into(mViewDataBinding.ivCover);
} else {
mViewDataBinding.ivZb.setVisibility(View.GONE);
mViewDataBinding.ivCover.setBackgroundResource(R.drawable.icon_yw_tjsb);
}
if (tbddData != null) {
mViewDataBinding.ivZb.setVisibility(View.VISIBLE);
Glide.with(mContext).load(tbddData.getCoverUrl()).into(mViewDataBinding.ivCover);
} else {
mViewDataBinding.ivZb.setVisibility(View.GONE);
mViewDataBinding.ivCover.setBackgroundResource(R.drawable.icon_yw_tjsb);
}
}
public void getMyList() {
@@ -274,7 +274,7 @@ public class EnglishFragment extends BaseMvvmFragment<EnglishViewModel, Fragment
contentAdapter.notifyDataSetChanged();
// MyApp.getInstance().mBottomBtnOnClickListener.setContext(getActivity());
// MyApp.getInstance().mBottomBtnOnClickListener.onClick(obj);
OpenApkUtils.getInstance().openJxwApp(mContext, obj);
OpenApkUtils.getInstance().openJxwAppWithParam(mContext, obj, true);
}
private void saveTag(ItemsBean itemsBean) {

View File

@@ -253,7 +253,7 @@ public class MathFragment extends BaseMvvmFragment<MathViewModel, FragmentMathBi
contentAdapter.notifyDataSetChanged();
// MyApp.getInstance().mBottomBtnOnClickListener.setContext(getActivity());
// MyApp.getInstance().mBottomBtnOnClickListener.onClick(obj);
OpenApkUtils.getInstance().openJxwApp(mContext, obj);
OpenApkUtils.getInstance().openJxwAppWithParam(mContext, obj, true);
}
private void saveTag(ItemsBean itemsBean) {

View File

@@ -1,61 +1,41 @@
package com.xwad.os.fragment.mine;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.lifecycle.Observer;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.xwad.os.BuildConfig;
import com.tencent.mmkv.MMKV;
import com.xwad.os.R;
import com.xwad.os.activity.ExitActivity;
import com.xwad.os.activity.activation.ActivationActivity;
import com.xwad.os.activity.home.HomeActivity;
import com.xwad.os.activity.login.result.LoginSuccessfulActivity;
import com.xwad.os.activity.user.UserActivity;
import com.xwad.os.base.mvvm.fragment.BaseMvvmFragment;
import com.xwad.os.bean.jxw.AppInfo;
import com.xwad.os.bean.UserAvatarInfo;
import com.xwad.os.config.CommonConfig;
import com.xwad.os.databinding.FragmentMineBinding;
import com.tencent.mmkv.MMKV;
import com.xwad.os.jxw.SPUtils;
import com.xwad.os.jxw.StudyRecordMng;
import com.xwad.os.jxw.ToastUtil;
import com.xwad.os.jxw.adapter.ZhMenuAdapter;
import com.xwad.os.jxw.event.UpdateColorEvent;
import com.xwad.os.service.main.MainService;
import com.xwad.os.utils.OpenApkUtils;
import com.xwad.os.view.jxw.view.dialog.QhbzDialog;
import com.xwad.os.view.jxw.view.dialog.RemoveAppDialog;
import com.xwad.os.view.jxw.widget.AppsDialog;
import com.xwad.os.view.jxw.widget.DefaultAppsDialog;
import com.xwad.os.view.jxw.widget.RecyclerMarginClickHelper;
import org.greenrobot.eventbus.EventBus;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* A simple {@link Fragment} subclass.
@@ -208,6 +188,13 @@ public class MineFragment extends BaseMvvmFragment<MineViewModel, FragmentMineBi
@Override
protected void initData(Bundle savedInstanceState) {
// initAppData();
mViewModel.mUserAvatarInfoData.observe(this, new Observer<UserAvatarInfo>() {
@Override
public void onChanged(UserAvatarInfo userAvatarInfo) {
mViewDataBinding.setUserAvatarInfo(userAvatarInfo);
}
});
mViewModel.getSnInfo();
}
@Override
@@ -222,6 +209,12 @@ public class MineFragment extends BaseMvvmFragment<MineViewModel, FragmentMineBi
Log.e(TAG, "onDestroy: ");
}
@Override
public void onResume() {
super.onResume();
mViewModel.getUserAvatarInfo();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
@@ -377,5 +370,15 @@ public class MineFragment extends BaseMvvmFragment<MineViewModel, FragmentMineBi
}
});
}
public void register(View view) {
boolean regist_success = mMMKV.decodeBool(MainService.JXW_REGISTER_SUCCESS, false);
if (regist_success) {
startActivity(new Intent(mContext, LoginSuccessfulActivity.class));
} else {
OpenApkUtils.getInstance().openJxwAppWithParam(mContext, (String) view.getTag(), true);
}
}
}
}

View File

@@ -1,8 +1,22 @@
package com.xwad.os.fragment.mine;
import android.util.Log;
import androidx.lifecycle.MutableLiveData;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.ActivityEvent;
import com.xwad.os.base.mvvm.BaseViewModel;
import com.xwad.os.bean.BaseResponse;
import com.xwad.os.bean.SnInfo;
import com.xwad.os.bean.UserAvatarInfo;
import com.xwad.os.databinding.FragmentMineBinding;
import com.trello.rxlifecycle4.android.FragmentEvent;
import com.xwad.os.network.NetInterfaceManager;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
public class MineViewModel extends BaseViewModel<FragmentMineBinding, FragmentEvent> {
@Override
@@ -15,4 +29,64 @@ public class MineViewModel extends BaseViewModel<FragmentMineBinding, FragmentEv
}
public MutableLiveData<UserAvatarInfo> mUserAvatarInfoData = new MutableLiveData<>();
public void getUserAvatarInfo() {
NetInterfaceManager.getInstance()
.getUserAvatarInfoControl()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
.subscribe(new Observer<BaseResponse<UserAvatarInfo>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getUserAvatarInfo", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<UserAvatarInfo> 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<SnInfo> mSnInfoData = new MutableLiveData<>();
public void getSnInfo() {
NetInterfaceManager.getInstance().getSnInfoControl()
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), FragmentEvent.DESTROY))
.subscribe(new Observer<BaseResponse<SnInfo>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getSnInfo", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<SnInfo> 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: ");
}
});
}
}

View File

@@ -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<SafeViewModel, FragmentSafeBi
Log.e(TAG, "onItemClick66 " + appInfo.mStargss);
// MyApp.getInstance().mBottomBtnOnClickListener.setContext(mContext);
// MyApp.getInstance().mBottomBtnOnClickListener.onClick(appInfo.mStargss);
OpenApkUtils.getInstance().openJxwApp(mContext, appInfo.mStargss);
OpenApkUtils.getInstance().openJxwAppWithParam(mContext, appInfo.mStargss, true);
}
}

View File

@@ -19,7 +19,6 @@ import com.tencent.mmkv.MMKV;
import com.xwad.os.R;
import com.xwad.os.activity.activation.ActivationActivity;
import com.xwad.os.activity.login.LoginActivity;
import com.xwad.os.activity.vip.list.VipActivity;
import com.xwad.os.base.mvvm.fragment.BaseMvvmFragment;
import com.xwad.os.bean.UserInfo;
import com.xwad.os.bean.VipLevel;
@@ -29,7 +28,11 @@ import com.xwad.os.fragment.dialog.login.account.AccountLoginDialogFragment;
import com.xwad.os.fragment.dialog.login.code.CodeLoginDialogFragment;
import com.xwad.os.fragment.dialog.login.statu.LoginStatuDialogFragment;
import com.xwad.os.fragment.dialog.viplist.VipListDialogFragment;
import com.xwad.os.jxw.JxwPackageConfig;
import com.xwad.os.utils.ActivationUtil;
import com.xwad.os.utils.ApkUtils;
import com.xwad.os.utils.OpenApkUtils;
import com.xwad.os.view.jxw.widget.DefaultAppsDialog;
public class AccountFragment extends BaseMvvmFragment<AccountViewModel, FragmentAccountBinding> {
@@ -112,6 +115,31 @@ public class AccountFragment extends BaseMvvmFragment<AccountViewModel, Fragment
Intent intent = result.getData();
if (intent != null && result.getResultCode() == Activity.RESULT_OK) {
mViewModel.getUserInfo();
if (!ApkUtils.isAvailable(mContext, JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME)) {
mViewModel.getAppInfo(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME);
}
if (!ApkUtils.isAvailable(mContext, "com.jxw.download")) {
mViewModel.getAppInfo("com.jxw.download");
}
if (!ApkUtils.isAvailable(mContext, "com.study.flashplayer")) {
mViewModel.getAppInfo("com.study.flashplayer");
}
}
}
}
});
private ActivityResultLauncher<Intent> mActivationLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
@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<AccountViewModel, Fragment
public void openVipList(View view) {
// mVipListDialogFragment = new VipListDialogFragment();
// mVipListDialogFragment.show(getChildFragmentManager(), "mVipListDialogFragment");
startActivity(new Intent(mContext, ActivationActivity.class));
if (ActivationUtil.getInstance().isLogin()) {
if (!ActivationUtil.getInstance().isActivation()) {
mActivationLauncher.launch(new Intent(mContext, ActivationActivity.class));
}
} else {
Toaster.show("请先登录");
mLauncher.launch(new Intent(mContext, LoginActivity.class));
}
}
}

View File

@@ -4,15 +4,18 @@ import android.util.Log;
import androidx.lifecycle.MutableLiveData;
import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV;
import com.trello.rxlifecycle4.RxLifecycle;
import com.trello.rxlifecycle4.android.FragmentEvent;
import com.xwad.os.base.mvvm.BaseViewModel;
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.databinding.FragmentAccountBinding;
import com.xwad.os.network.NetInterfaceManager;
import com.xwad.os.utils.FileUtil;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
@@ -66,4 +69,35 @@ public class AccountViewModel extends BaseViewModel<FragmentAccountBinding, Frag
}
});
}
public void getAppInfo(String pkg) {
NetInterfaceManager.getInstance().getAdminAppObservable(pkg)
.subscribe(new Observer<BaseResponse<AppInfo>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getAppInfo", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<AppInfo> 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: ");
}
});
}
}

View File

@@ -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";
/*同步视频*/

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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<String, Long> 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<BaseResponse> getUpdateInfoObservable(Map<String, RequestBody> params, MultipartBody.Part multipartBody) {
return mRetrofit.create(SnInfoApi.class)
.updateUserInfo(params, multipartBody)
.updateUserInfo(getToken(), params, multipartBody)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
public Observable<BaseResponse> getupdateAvatarObservable(Map<String, RequestBody> 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<BaseResponse> 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<BaseResponse<LoginInfo>> 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<BaseResponse> getOauthTokenObservable() {
Map<String, String> 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<BaseResponse> getAnswerControlStatusControl() {
Map<String, String> 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());
}
/*
*

View File

@@ -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";
}

View File

@@ -37,6 +37,8 @@ public interface LoginApi {
@POST(UrlAddress.NEW_CODE_LOGIN)
Observable<BaseResponse<LoginInfo>> newCodeLogin(
@Field("mobile") String mobile,
@Field("code") String code
@Field("code") String code,
@Field("sn") String sn,
@Field("desktop_package") String desktop_package
);
}

View File

@@ -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<BaseResponse> updateUserInfo(@Body RequestBody requestBody);
Observable<BaseResponse> updateUserInfo(
@Header("token") String token,
@Body RequestBody requestBody
);
@Multipart
@POST(UrlAddress.UPDATE_INFO)
Observable<BaseResponse> updateUserInfo(
@Header("token") String token,
@PartMap Map<String, RequestBody> params,
@Part MultipartBody.Part body);
@Part MultipartBody.Part body
);
@Multipart
@POST(UrlAddress.UPDATE_avatar)
Observable<BaseResponse> updateAvatar(
@Header("token") String token,
@PartMap Map<String, RequestBody> params,
@Part MultipartBody.Part body
);
@GET(UrlAddress.GET_STUDY_STAT)
Observable<BaseResponse<StudyStatBean>> getStudyStat(
@@ -50,6 +64,7 @@ public interface SnInfoApi {
@FormUrlEncoded
@POST(UrlAddress.UPDATE_ADDRESS)
Observable<BaseResponse> updateAddress(
@Header("token") String token,
@Field("sn") String sn,
@Field("address") String address,
@Field("longitude") double longitude,

View File

@@ -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<BaseResponse> getOauthToken(
@QueryMap Map<String, String> params
);
@GET(UrlAddress.answer_Control_status)
Observable<BaseResponse> getAnswerControlStatus(
@Header("token") String token,
@QueryMap Map<String, String> params
);
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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) {

View File

@@ -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<Long>() {
@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<Long>() {
@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();
}
}
}
}

View File

@@ -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();

View File

@@ -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);

View File

@@ -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<String, String> paramMap) {
long timeStamp = System.currentTimeMillis();
//用于获取signature
SortedMap<String, String> 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<String, String> 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<String, String> 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;
}
}

View File

@@ -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<String> pkgList = new ArrayList<String>() {{
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<String> optional = pkgList.stream().filter(new Predicate<String>() {
@@ -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<String> optional = pkgList.stream().filter(new Predicate<String>() {

View File

@@ -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);
}
}

View File

@@ -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<ItemsBean> getDefaultApps() {
List<ItemsBean> 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;
}
}

View File

@@ -0,0 +1,26 @@
//
// Created by TT on 2025/12/29.
//
#include <jni.h>
#include <string>
#include <sys/system_properties.h>
// 日志打印
#include <android/log.h>
#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());
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="100dp"
android:height="100dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#2196F3"
android:pathData="M1024,748.54q0,25.6 -8.7,48.13t-24.06,40.96 -36.35,30.21 -45.57,15.87l0,2.05 -21.5,0 -1.02,0 -664.58,0q-2.05,0 -2.56,0.51t-2.56,0.51 -3.07,-0.51 -3.07,-0.51l-6.14,0 0,-1.02q-43.01,-2.05 -80.38,-19.46t-65.02,-46.59 -43.52,-67.58 -15.87,-81.41 15.87,-80.9 43.01,-66.56 63.49,-47.1 78.34,-21.5q7.17,-66.56 36.86,-124.42t76.29,-100.86 107.01,-67.58 129.02,-24.58q72.7,0 137.22,27.65t112.13,75.78 75.26,112.13 27.65,136.7q0,32.77 -6.14,64t-17.41,59.9q2.05,0 4.61,-0.51t4.61,-0.51q28.67,0 53.25,10.75t43.01,29.18 29.18,43.52 10.75,53.76zM687.1,596.99q12.29,-20.48 7.17,-23.55t-25.6,-3.07q-12.29,0 -34.3,-0.51t-33.28,-0.51q-16.38,0 -20.99,-13.31t-4.61,-36.86q0,-32.77 -0.51,-52.74t-0.51,-43.52q0,-26.62 -3.58,-38.91t-29.18,-12.29q-18.43,0 -27.65,0.51t-25.6,0.51q-27.65,0 -34.3,15.87t-6.66,31.23l0,32.77q0,13.31 0.51,25.6t0.51,25.6l0,29.7q0,16.38 -4.1,25.09t-19.46,8.7q-6.14,1.02 -16.9,1.54t-22.02,1.02 -21.5,0.51l-16.38,0q-21.5,0 -25.6,13.31t13.31,33.79q17.41,21.5 37.38,46.59t39.42,50.69 37.38,49.66 33.28,41.47q27.65,30.72 53.25,-1.02 15.36,-17.41 35.84,-45.06t41.98,-57.86 40.96,-58.37 31.74,-46.59z" />
</vector>

View File

@@ -146,7 +146,9 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rl_tab"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@@ -152,7 +152,7 @@
android:layout_height="match_parent"
android:background="@drawable/edit_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageView10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
@@ -194,19 +194,23 @@
app:layout_constraintStart_toEndOf="@+id/view2"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="@+id/tv_get_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:maxLines="1"
android:gravity="center"
android:onClick="@{click::getCode}"
android:singleLine="true"
android:text="获取"
android:textColor="@color/default_blue"
android:textSize="11sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/et_code"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView10"
android:layout_width="96dp"
android:layout_height="29dp"
android:adjustViewBounds="true"
android:onClick="@{click::getCode}"
android:scaleType="centerCrop"
android:src="@drawable/icon_login_sms_code_selector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -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" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout17"
@@ -106,6 +107,7 @@
android:layout_width="110dp"
android:layout_height="25dp"
android:adjustViewBounds="true"
android:onClick="@{click::toHome}"
android:scaleType="centerCrop"
android:src="@drawable/icon_activation_confirm"
app:layout_constraintBottom_toBottomOf="parent"

View File

@@ -51,5 +51,16 @@
android:layout_marginTop="9dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="6dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:maxLines="1"
android:singleLine="true"
android:text="支付成功后,请先下载上述软件,保证系统正常运行。"
android:textColor="@color/red"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>

View File

@@ -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 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:layout_marginTop="16dp">
<TextView
@@ -100,6 +102,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:visibility="gone"
android:layout_marginBottom="12dp">
<TextView
@@ -123,6 +126,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone"
android:layout_marginStart="4dp"
android:layout_marginBottom="16dp"
android:maxLines="1"

View File

@@ -9,6 +9,12 @@
<variable
name="click"
type="com.xwad.os.fragment.mine.MineFragment.BtnClick" />
<variable
name="userAvatarInfo"
type="com.xwad.os.bean.UserAvatarInfo" />
<import type="android.text.TextUtils" />
</data>
<!--基数3.2,图片宽高直接除-->
@@ -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" />
</LinearLayout>
<LinearLayout
@@ -344,8 +353,8 @@
android:layout_width="@dimen/mine_icon_width"
android:layout_height="match_parent"
android:onClick="onClick"
android:visibility="gone"
android:tag="@string/tag_args_new_arzd">
android:tag="@string/tag_args_new_arzd"
android:visibility="gone">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
@@ -383,11 +392,54 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/mine_icon_width"
android:layout_height="match_parent"
android:onClick="@{click::register}"
android:tag="@string/tag_args_jxw_main">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/app_icon12"
android:layout_width="@dimen/mine_icon_height"
android:layout_height="@dimen/mine_icon_height"
android:layout_gravity="center_horizontal"
android:src="@drawable/icon_bbx_yygx"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/app_name12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="2dp"
android:singleLine="true"
android:text="许可证"
android:textColor="@color/white"
android:textSize="@dimen/mine_app_name_size"
app:layout_constraintEnd_toEndOf="@+id/app_icon12"
app:layout_constraintStart_toStartOf="@+id/app_icon12"
app:layout_constraintTop_toBottomOf="@+id/app_icon12" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/mine_icon_width"
android:layout_height="match_parent"
android:onClick="onClick"
android:tag="@string/tag_args_updae">
android:tag="@string/tag_args_updae"
android:visibility="gone">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
@@ -429,8 +481,8 @@
android:layout_width="@dimen/mine_icon_width"
android:layout_height="match_parent"
android:onClick="onClick"
android:visibility="gone"
android:tag="@string/tag_args_new_jzgk">
android:tag="@string/tag_args_new_jzgk"
android:visibility="gone">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
@@ -472,8 +524,8 @@
android:layout_width="@dimen/mine_icon_width"
android:layout_height="match_parent"
android:onClick="onClick"
android:visibility="gone"
android:tag="@string/tag_args_new_yjjs">
android:tag="@string/tag_args_new_yjjs"
android:visibility="gone">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/rl_root"
android:layout_width="match_parent"
android:layout_height="69dp">
@@ -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" />
<ImageView
android:id="@+id/iv_download"
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_marginTop="20dp"
android:layout_marginStart="20dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/ic_download"
app:layout_constraintStart_toStartOf="@+id/iv_app_icon"
app:layout_constraintTop_toTopOf="@+id/iv_app_icon" />
<TextView
android:id="@+id/tv_app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_app_icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:gravity="center"
android:text="当前壁纸"
android:textColor="#333333"
android:textSize="9sp" />
</RelativeLayout>
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" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -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">
<ImageView
android:id="@+id/tv_tab_icon"

View File

@@ -672,6 +672,7 @@
<string name="tag_args_tbdd_yy_new_six">com.jxw.tbdd,com.jxw.yyhb.ui.activity.MainActivity,int:subject:1,jxwgb_6.0_tbdd,同步点读</string>
<string name="tag_args_tiku_xd">com.jxw.question,com.jxw.question.module.ui.activity.ProgramEntryActivity,,jxwgb_6.0_tiku_xiaodu,题库</string>
<string name="tag_args_tlzjcc">com.jxw.zjcc,com.jxw.zjcc.MainActivity,,jxwgb_6.0_xwzdtl,指尖查词</string>
<string name="tag_args_jxw_main">com.jxw.launcher,com.jxw.launcher.DummyActivity,,,许可证</string>
<string name="tag_args_updae">com.jxw.launcher,com.jxw.update.UpdateNewActivity,,,应用更新</string>
<string name="tag_args_updaex">com.jxw.launcher,com.jxw.launcher.XtazActivity,,,系统安装</string>
<string name="tag_args_weixin">com.tencent.mm,com.tencent.mm.ui.LauncherUI,,,微信</string>