diff --git a/app/build.gradle b/app/build.gradle index 9b1b2f2..6ae1d1b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,8 +17,8 @@ android { minSdkVersion 23 targetSdkVersion 29 - versionCode 26 - versionName "1.2.5" + versionCode 27 + versionName "1.2.6" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5364d95..a8a6ac7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -253,7 +253,20 @@ - + + + + getAllLauncherApps() { - PackageManager packageManager = getPackageManager(); - - // 构建用于查询桌面应用的Intent - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_HOME); - - // 查询所有可以处理该Intent的Activity - List resolveInfoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL); - - List launcherPackageList = resolveInfoList.stream().filter(new Predicate() { - @Override - public boolean test(ResolveInfo resolveInfo) { - return !BuildConfig.APPLICATION_ID.equals(resolveInfo.activityInfo.packageName) - || !"com.jxw.launcher".equals(resolveInfo.activityInfo.packageName) - || !"com.handuan.os".equals(resolveInfo.activityInfo.packageName); - } - }).map(new Function() { - @Override - public ComponentName apply(ResolveInfo resolveInfo) { - return resolveInfo.getComponentInfo().getComponentName(); - } - }).collect(Collectors.toList()); - - return launcherPackageList; - } - - private void exitDesktop() { - List componentNames = getAllLauncherApps(); - Log.e(TAG, "exitDesktop: " + componentNames); - if (componentNames != null && componentNames.size() != 0) { - ComponentName componentName = componentNames.get(0); - Intent intent = new Intent(); - intent.setComponent(componentName); - try { - startActivity(intent); - } catch (Exception e) { - Log.e(TAG, "exitDesktop: " + e.getMessage()); - } - } - - startActivity(new Intent(Settings.ACTION_HOME_SETTINGS)); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - finishAndRemoveTask(); - } else { - finishAffinity(); - } - android.os.Process.killProcess(android.os.Process.myPid()); - System.exit(0); - } - - private void setEmpty() { + private void setEmpty() { new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { diff --git a/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java b/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java index 4b9883c..7a9df0d 100644 --- a/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java +++ b/app/src/main/java/com/xwad/os/activity/activation/ActivationActivity.java @@ -94,7 +94,7 @@ public class ActivationActivity extends BaseMvvmActivity { + private static final String TAG = "DownloadActivity"; + + private AppInfoAdapter mAppInfoAdapter; + private List mAppInfos; + + @Override + protected int getLayoutId() { + return R.layout.activity_other_app; + } + + @Override + protected void initDataBinding() { + mViewModel.setCtx(this); + mViewModel.setLifecycle(getLifecycleSubject()); + mViewModel.setVDBinding(mViewDataBinding); + mViewDataBinding.setClick(new BtnClick()); + } + + @Override + protected void initView() { + mAppInfoAdapter = new AppInfoAdapter(); + GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 4); + mViewDataBinding.rvContent.setLayoutManager(gridLayoutManager); + mViewDataBinding.rvContent.setAdapter(mAppInfoAdapter); + + registerAppChangedReceiver(); + } + + @Override + protected void initData() { + mViewModel.mListMutableLiveData.observe(this, new Observer>() { + @Override + public void onChanged(List appInfos) { + mAppInfos = appInfos; + mAppInfoAdapter.setAppInfos(appInfos); + if (appInfos == null || appInfos.isEmpty()) { + mViewDataBinding.clContent.setVisibility(View.GONE); + mViewDataBinding.llNodata.setVisibility(View.VISIBLE); + } else { + mViewDataBinding.clContent.setVisibility(View.VISIBLE); + mViewDataBinding.llNodata.setVisibility(View.GONE); + } + } + }); + mViewModel.getAdminApp(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mAppChangedReceiver != null) { + unregisterReceiver(mAppChangedReceiver); + } + } + + private AppChangedReceiver mAppChangedReceiver; + + private void registerAppChangedReceiver() { + if (mAppChangedReceiver == null) { + mAppChangedReceiver = new AppChangedReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_PACKAGE_ADDED); + filter.addAction(Intent.ACTION_PACKAGE_CHANGED); + filter.addAction(Intent.ACTION_PACKAGE_REPLACED); + filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addDataScheme("package"); + registerReceiver(mAppChangedReceiver, filter); + } + + class AppChangedReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.e("AppChangedReceiver", "onReceive: " + action); + if (TextUtils.isEmpty(action)) { + return; + } + mAppInfoAdapter.notifyDataSetChanged(); + } + } + + public class BtnClick { + public void exit(View view) { + finish(); + } + + public void downloadApp(View view) { + if (mAppInfos == null || mAppInfos.isEmpty()) { + Toaster.show("没有要下载的应用"); + } else { + if (ActivationUtil.getInstance().isActivation()) { + mAppInfos.forEach(new Consumer() { + @Override + public void accept(AppInfo appInfo) { + if (appInfo.getIs_must_components_down() == 1) { + if (!ApkUtils.isAvailable(OtherAppActivity.this, appInfo.getApp_package())) { + FileUtils.ariaDownload(OtherAppActivity.this, appInfo.getApp_url(), appInfo); + } + } + } + }); + } + } + } + } +} diff --git a/app/src/main/java/com/xwad/os/activity/app/OtherAppViewModel.java b/app/src/main/java/com/xwad/os/activity/app/OtherAppViewModel.java new file mode 100644 index 0000000..49a705e --- /dev/null +++ b/app/src/main/java/com/xwad/os/activity/app/OtherAppViewModel.java @@ -0,0 +1,74 @@ +package com.xwad.os.activity.app; + +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.AppInfo; +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.databinding.ActivityOtherAppBinding; +import com.xwad.os.network.NetInterfaceManager; + +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; + +public class OtherAppViewModel extends BaseViewModel { + + @Override + public ActivityOtherAppBinding getVDBinding() { + return binding; + } + + @Override + public void onDestroy() { + + } + + public MutableLiveData> mListMutableLiveData = new MutableLiveData<>(); + + public void getAdminApp() { + NetInterfaceManager.getInstance().get365AdminAppObservable() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAdminApp", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> listBaseResponse) { + Log.e("getAdminApp", "onNext: " + listBaseResponse); + if (listBaseResponse.code == 200) { + List appInfoList = listBaseResponse.data; + List forceAppInfoList = appInfoList.stream() + .filter(new Predicate() { + @Override + public boolean test(AppInfo appInfo) { + return appInfo.getIs_must_components() == 0; + } + }).collect(Collectors.toList()); + mListMutableLiveData.setValue(forceAppInfoList); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAdminApp", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAdminApp", "onComplete: "); + } + }); + } +} diff --git a/app/src/main/java/com/xwad/os/activity/download/DownloadActivity.java b/app/src/main/java/com/xwad/os/activity/download/DownloadActivity.java new file mode 100644 index 0000000..1cba80a --- /dev/null +++ b/app/src/main/java/com/xwad/os/activity/download/DownloadActivity.java @@ -0,0 +1,149 @@ +package com.xwad.os.activity.download; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.Color; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.style.ForegroundColorSpan; +import android.util.Log; +import android.view.View; + +import androidx.lifecycle.Observer; +import androidx.recyclerview.widget.GridLayoutManager; + +import com.hjq.toast.Toaster; +import com.xwad.os.R; +import com.xwad.os.activity.app.OtherAppActivity; +import com.xwad.os.adapter.AppInfoAdapter; +import com.xwad.os.base.mvvm.BaseMvvmActivity; +import com.xwad.os.bean.AppInfo; +import com.xwad.os.databinding.ActivityDownloadBinding; +import com.xwad.os.utils.ActivationUtil; +import com.xwad.os.utils.ApkUtils; +import com.xwad.os.utils.FileUtils; + +import java.util.List; +import java.util.function.Consumer; + +public class DownloadActivity extends BaseMvvmActivity { + private static final String TAG = "DownloadActivity"; + + private AppInfoAdapter mAppInfoAdapter; + private List mAppInfos; + + @Override + protected int getLayoutId() { + return R.layout.activity_download; + } + + @Override + protected void initDataBinding() { + mViewModel.setCtx(this); + mViewModel.setLifecycle(getLifecycleSubject()); + mViewModel.setVDBinding(mViewDataBinding); + mViewDataBinding.setClick(new BtnClick()); + } + + @Override + protected void initView() { + mAppInfoAdapter = new AppInfoAdapter(); + GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 4); + mViewDataBinding.rvContent.setLayoutManager(gridLayoutManager); + mViewDataBinding.rvContent.setAdapter(mAppInfoAdapter); + + SpannableString spannableString = new SpannableString(getResources().getString(R.string.bibeizujian_permission)); + spannableString.setSpan(new ForegroundColorSpan(Color.RED), 21, 35, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + mViewDataBinding.tvPermission.setText(spannableString); + + registerAppChangedReceiver(); + } + + @Override + protected void initData() { + mViewModel.mListMutableLiveData.observe(this, new Observer>() { + @Override + public void onChanged(List appInfos) { + mAppInfos = appInfos; + mAppInfoAdapter.setAppInfos(appInfos); + if (appInfos == null || appInfos.isEmpty()) { + mViewDataBinding.clContent.setVisibility(View.GONE); + mViewDataBinding.llNodata.setVisibility(View.VISIBLE); + } else { + mViewDataBinding.clContent.setVisibility(View.VISIBLE); + mViewDataBinding.llNodata.setVisibility(View.GONE); + } + } + }); + mViewModel.getAdminApp(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mAppChangedReceiver != null) { + unregisterReceiver(mAppChangedReceiver); + } + } + + private AppChangedReceiver mAppChangedReceiver; + + private void registerAppChangedReceiver() { + if (mAppChangedReceiver == null) { + mAppChangedReceiver = new AppChangedReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_PACKAGE_ADDED); + filter.addAction(Intent.ACTION_PACKAGE_CHANGED); + filter.addAction(Intent.ACTION_PACKAGE_REPLACED); + filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addDataScheme("package"); + registerReceiver(mAppChangedReceiver, filter); + } + + class AppChangedReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.e("AppChangedReceiver", "onReceive: " + action); + if (TextUtils.isEmpty(action)) { + return; + } + mAppInfoAdapter.notifyDataSetChanged(); + } + } + + public class BtnClick { + public void exit(View view) { + finish(); + } + + public void openOtherApp(View view) { + startActivity(new Intent(DownloadActivity.this, OtherAppActivity.class)); + } + + public void downloadApp(View view) { + if (mAppInfos == null || mAppInfos.isEmpty()) { + Toaster.show("没有要下载的应用"); + } else { + if (ActivationUtil.getInstance().isActivation()) { + mAppInfos.forEach(new Consumer() { + @Override + public void accept(AppInfo appInfo) { + if (appInfo.getIs_must_components_down() == 1) { + if (ApkUtils.isUpdate(DownloadActivity.this, appInfo)) { + FileUtils.ariaDownload(DownloadActivity.this, appInfo.getApp_url(), appInfo); + } + } + } + }); + } + } + } + } +} diff --git a/app/src/main/java/com/xwad/os/activity/download/DownloadViewModel.java b/app/src/main/java/com/xwad/os/activity/download/DownloadViewModel.java new file mode 100644 index 0000000..9ac96bd --- /dev/null +++ b/app/src/main/java/com/xwad/os/activity/download/DownloadViewModel.java @@ -0,0 +1,110 @@ +package com.xwad.os.activity.download; + +import android.util.Log; + +import androidx.lifecycle.MutableLiveData; + +import com.tencent.mmkv.MMKV; +import com.trello.rxlifecycle4.RxLifecycle; +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.xwad.os.base.mvvm.BaseViewModel; +import com.xwad.os.bean.AppInfo; +import com.xwad.os.bean.BaseResponse; +import com.xwad.os.config.CommonConfig; +import com.xwad.os.databinding.ActivityDownloadBinding; +import com.xwad.os.network.NetInterfaceManager; + +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; + +public class DownloadViewModel extends BaseViewModel { + + MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + @Override + public ActivityDownloadBinding getVDBinding() { + return binding; + } + + @Override + public void onDestroy() { + + } + + + public MutableLiveData> mListMutableLiveData = new MutableLiveData<>(); + + public void getAdminApp() { + NetInterfaceManager.getInstance().get365AdminAppObservable() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAdminApp", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> listBaseResponse) { + Log.e("getAdminApp", "onNext: " + listBaseResponse); + if (listBaseResponse.code == 200) { + List appInfoList = listBaseResponse.data; + List forceAppInfoList = appInfoList.stream() + .sorted(new Comparator() { + @Override + public int compare(AppInfo o1, AppInfo o2) { + if ("com.jxw.launcher".equals(o1.getApp_package()) && !"com.jxw.launcher".equals(o2.getApp_package())) { + return -1; + } else if (!"com.jxw.launcher".equals(o1.getApp_package()) && "com.jxw.launcher".equals(o2.getApp_package())) { + return 1; + } else { + return o1.getApp_package().compareTo(o2.getApp_package()); // 非目标包名按字母排序 + } + } + }) + .filter(new Predicate() { + @Override + public boolean test(AppInfo appInfo) { + return appInfo.getIs_must_components() == 1; + } + }).collect(Collectors.toList()); + mListMutableLiveData.setValue(forceAppInfoList); + Set packageSets = appInfoList.stream() + .filter(new Predicate() { + @Override + public boolean test(AppInfo appInfo) { + return appInfo.getIs_must_components() == 1; + } + }) + .map(new Function() { + @Override + public String apply(AppInfo appInfo) { + return appInfo.getApp_package(); + } + }) + .collect(Collectors.toSet()); + mMMKV.encode(CommonConfig.ESSENTIAL_COMPONENT_APPLICATIONS, packageSets); + + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAdminApp", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAdminApp", "onComplete: "); + } + }); + } +} diff --git a/app/src/main/java/com/xwad/os/activity/home/HomeViewModel.java b/app/src/main/java/com/xwad/os/activity/home/HomeViewModel.java index e575bab..9b92fb4 100644 --- a/app/src/main/java/com/xwad/os/activity/home/HomeViewModel.java +++ b/app/src/main/java/com/xwad/os/activity/home/HomeViewModel.java @@ -175,12 +175,12 @@ public class HomeViewModel extends BaseViewModel>() { @Override public void onSubscribe(@NonNull Disposable d) { - Log.e("checkUpdateUiUiOS", "onSubscribe: "); + Log.e("checkUpdate", "onSubscribe: "); } @Override public void onNext(@NonNull BaseResponse appUpdateInfoBaseResponse) { - Log.e("checkUpdateUiUiOS", "onNext: " + appUpdateInfoBaseResponse); + Log.e("checkUpdate", "onNext: " + appUpdateInfoBaseResponse); if (appUpdateInfoBaseResponse.code == 200) { AppUpdateInfo appUpdateInfo = appUpdateInfoBaseResponse.data; mAppUpdateInfoUiUiOSData.setValue(appUpdateInfo); @@ -191,13 +191,13 @@ public class HomeViewModel extends BaseViewModel() { + @Override + public void onChanged(Boolean aBoolean) { + finish(); + } + }); } @Override @@ -57,7 +64,9 @@ public class LoginSuccessfulActivity extends BaseMvvmActivity { + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + @Override public void onDestroy() { } + public MutableLiveData mCompleteLiveData = new MutableLiveData<>(); + + public void getAdminAppDownload() { + NetInterfaceManager.getInstance().getAdminAppObservable() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAdminAppDownload", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> listBaseResponse) { + Log.e("getAdminAppDownload", "onNext: " + listBaseResponse); + if (listBaseResponse.code == 200) { + List appInfoList = listBaseResponse.data; + Set packageSets = appInfoList.stream() + .filter(new Predicate() { + @Override + public boolean test(AppInfo appInfo) { + return appInfo.getIs_must_components() == 1; + } + }) + .map(new Function() { + @Override + public String apply(AppInfo appInfo) { + return appInfo.getApp_package(); + } + }) + .collect(Collectors.toSet()); + mMMKV.encode(CommonConfig.ESSENTIAL_COMPONENT_APPLICATIONS, packageSets); + + } + mCompleteLiveData.setValue(true); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAdminAppDownload", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAdminAppDownload", "onComplete: "); + mCompleteLiveData.setValue(true); + } + }); + } + public MutableLiveData mBooleanMutableLiveData = new MutableLiveData<>(); public void getAppInfo() { diff --git a/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java b/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java index c387071..5104995 100644 --- a/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java +++ b/app/src/main/java/com/xwad/os/activity/update/UpdateActivity.java @@ -67,7 +67,7 @@ public class UpdateActivity extends BaseMvvmActivity { + private static final String TAG = "AppInfoAdapter"; + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + private FragmentActivity mContext; + + private List mAppInfos; + + public void setAppInfos(List appInfos) { + mAppInfos = appInfos; + notifyDataSetChanged(); + } + + @NonNull + @Override + public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + mContext = (FragmentActivity) parent.getContext(); + AutoSizeCompat.autoConvertDensityOfGlobal(mContext.getResources()); + return new AppInfoAdapter.Holder(LayoutInflater.from(mContext).inflate(R.layout.item_app_info, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull Holder holder, int position) { + AutoSizeCompat.autoConvertDensityOfGlobal(mContext.getResources()); + AppInfo appInfo = mAppInfos.get(position); + GlideLoadUtils.getInstance().glideLoad(mContext, appInfo.getApp_img(), holder.iv_app_icon, R.drawable.icon_bbx_app); + if (!TextUtils.isEmpty(appInfo.getApp_name())) { + holder.tv_app_name.setText(appInfo.getApp_name()); + } else { + holder.tv_app_name.setText("未知应用"); + } + if (ApkUtils.isAvailable(mContext, appInfo.getApp_package())) { + holder.iv_download.setVisibility(View.GONE); + if (ApkUtils.isUpdate(mContext, appInfo)) { + holder.iv_update.setVisibility(View.VISIBLE); + } else { + holder.iv_update.setVisibility(View.GONE); + } + } else { + holder.iv_download.setVisibility(View.VISIBLE); + holder.iv_update.setVisibility(View.GONE); + } + holder.rl_root.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (ApkUtils.isAvailable(mContext, appInfo.getApp_package())) { + if (ApkUtils.isUpdate(mContext, appInfo)) { + OpenApkUtils.getInstance().showDownloadDialog(mContext, appInfo, "\"" + appInfo.getApp_name() + "\"\n更新后可继续使用!"); + } else { + ApkUtils.openPackage(mContext, appInfo.getApp_package()); + } + } else { + if (ActivationUtil.getInstance().isActivation()) { + OpenApkUtils.getInstance().showDownloadDialog(mContext, appInfo, "未安装\"" + appInfo.getApp_name() + "\"\n下载后可继续使用!"); + } else { + Toaster.show("请先激活设备"); + } + } + } + }); + } + + @Override + public int getItemCount() { + return mAppInfos == null ? 0 : mAppInfos.size(); + } + + public class Holder extends RecyclerView.ViewHolder { + ConstraintLayout rl_root; + ImageView iv_app_icon, iv_download, iv_update; + TextView tv_app_name; + + public Holder(@NonNull View itemView) { + super(itemView); + rl_root = itemView.findViewById(R.id.rl_root); + iv_app_icon = itemView.findViewById(R.id.iv_app_icon); + iv_download = itemView.findViewById(R.id.iv_download); + iv_update = itemView.findViewById(R.id.iv_update); + tv_app_name = itemView.findViewById(R.id.tv_app_name); + } + } +} diff --git a/app/src/main/java/com/xwad/os/bean/AppInfo.java b/app/src/main/java/com/xwad/os/bean/AppInfo.java index 436ed23..93cb25f 100644 --- a/app/src/main/java/com/xwad/os/bean/AppInfo.java +++ b/app/src/main/java/com/xwad/os/bean/AppInfo.java @@ -32,6 +32,8 @@ public class AppInfo implements Serializable { private String use_type; private int is_autodown; private String third_url; + private int is_must_components; + private int is_must_components_down; public int getId() { return id; @@ -209,6 +211,22 @@ public class AppInfo implements Serializable { this.third_url = third_url; } + public int getIs_must_components() { + return is_must_components; + } + + public void setIs_must_components(int is_must_components) { + this.is_must_components = is_must_components; + } + + public int getIs_must_components_down() { + return is_must_components_down; + } + + public void setIs_must_components_down(int is_must_components_down) { + this.is_must_components_down = is_must_components_down; + } + @NonNull @Override public String toString() { diff --git a/app/src/main/java/com/xwad/os/config/CommonConfig.java b/app/src/main/java/com/xwad/os/config/CommonConfig.java index 005ec52..802eeb7 100644 --- a/app/src/main/java/com/xwad/os/config/CommonConfig.java +++ b/app/src/main/java/com/xwad/os/config/CommonConfig.java @@ -1,10 +1,23 @@ package com.xwad.os.config; +import java.util.HashSet; +import java.util.Set; + public class CommonConfig { public static final String MMKV_ID = "InterProcessKV"; public static final String CLOUD_LESSON_SETTINGS_KEY = "cloud_lesson_settings_key"; public static final String DISALLOWED_RUNNING_APP_KEY = "disallowed_running_app"; + public static final String ESSENTIAL_COMPONENT_APPLICATIONS = "essential_component_applications"; + public static final Set ESSENTIAL_APPLICATIONS_SETS = new HashSet() {{ + this.add("com.jxw.jpkc"); + this.add("com.jxw.zncd"); + this.add("com.jxw.question"); + this.add("com.jxw.launcher"); + this.add("com.jxw.tbdd"); + this.add("com.jxw.download"); + this.add("com.jxw.tbfd"); + }}; public static final String ALIYUN_PUSH_ID = "aliyun_push_id_key"; diff --git a/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java b/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java index a258b36..61b8f60 100644 --- a/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java +++ b/app/src/main/java/com/xwad/os/fragment/mine/MineFragment.java @@ -16,6 +16,9 @@ import com.hjq.toast.Toaster; import com.tencent.mmkv.MMKV; import com.xwad.os.R; import com.xwad.os.activity.ExitActivity; +import com.xwad.os.activity.activation.ActivationActivity; +import com.xwad.os.activity.download.DownloadActivity; +import com.xwad.os.activity.login.LoginActivity; import com.xwad.os.activity.user.UserActivity; import com.xwad.os.base.mvvm.fragment.BaseMvvmFragment; import com.xwad.os.bean.SnInfo; @@ -25,9 +28,10 @@ import com.xwad.os.databinding.FragmentMineBinding; import com.xwad.os.jxw.StudyRecordMng; import com.xwad.os.jxw.ToastUtil; import com.xwad.os.jxw.event.UpdateColorEvent; +import com.xwad.os.utils.ActivationUtil; import com.xwad.os.utils.OpenApkUtils; +import com.xwad.os.utils.Utils; import com.xwad.os.view.jxw.view.dialog.QhbzDialog; -import com.xwad.os.view.jxw.widget.DefaultAppsDialog; import org.greenrobot.eventbus.EventBus; @@ -386,24 +390,41 @@ public class MineFragment extends BaseMvvmFragment { @@ -87,15 +85,16 @@ public class AccountFragment extends BaseMvvmFragment>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -135,4 +142,63 @@ public class AccountViewModel extends BaseViewModel>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAdminAppDownload", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> listBaseResponse) { + Log.e("getAdminAppDownload", "onNext: " + listBaseResponse); + if (listBaseResponse.code == 200) { + List appInfoList = listBaseResponse.data; + appInfoList.stream() + .sorted(new Comparator() { + @Override + public int compare(AppInfo o1, AppInfo o2) { + if ("com.jxw.launcher".equals(o1.getApp_package()) && !"com.jxw.launcher".equals(o2.getApp_package())) { + return -1; + } else if (!"com.jxw.launcher".equals(o1.getApp_package()) && "com.jxw.launcher".equals(o2.getApp_package())) { + return 1; + } else { + return o1.getApp_package().compareTo(o2.getApp_package()); // 非目标包名按字母排序 + } + } + }) + .filter(new Predicate() { + @Override + public boolean test(AppInfo appInfo) { + return appInfo.getIs_must_components() == 1; + } + }) + .forEach(new Consumer() { + @Override + public void accept(AppInfo appInfo) { + if (appInfo.getIs_must_components_down() == 1) { + if (!ApkUtils.isAvailable(getCtx(), appInfo.getApp_package())) { + FileUtils.ariaDownload(getCtx(), appInfo.getApp_url(), appInfo); + } + } + } + }); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAdminAppDownload", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAdminAppDownload", "onComplete: "); + } + }); + } } diff --git a/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java b/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java index 9b410f0..2c38a44 100644 --- a/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java +++ b/app/src/main/java/com/xwad/os/fragment/usercenter/info/InfoFragment.java @@ -132,6 +132,11 @@ public class InfoFragment extends BaseMvvmFragment>> getTestAppObservable() { + return getAppApi() + .getTestApp(DeviceSNManager.getDeviceSN()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + public Observable getPhoneCodeObservable(String mobile) { return mRetrofit.create(LoginApi.class) .getCode(mobile) @@ -537,28 +544,35 @@ public class NetInterfaceManager { public Observable> getLockScreenPwdObservable() { return getSnInfoApi() - .getLockScreenPwd(Utils.getSerial()) + .getLockScreenPwd(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable getUpdateLockScreenObservable() { return mRetrofit.create(SnInfoApi.class) - .updateLockScreen(Utils.getSerial()) + .updateLockScreen(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable>> getAdminAppObservable() { return mRetrofit.create(AppApi.class) - .getAdminApp(Utils.getSerial()) + .getAdminApp(DeviceSNManager.getDeviceSN()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable>> get365AdminAppObservable() { + return mRetrofit.create(AppApi.class) + .getAdminApp(DeviceSNManager.getDeviceSN(), "11", BuildConfig.APPLICATION_ID) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } public Observable>> getAppIconObservable() { return mRetrofit.create(GetAppIconApi.class) - .getAppIcon(Utils.getSerial()) + .getAppIcon(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } @@ -1075,7 +1089,7 @@ public class NetInterfaceManager { Log.e(TAG, "updateAdminInfo: software = " + software); } getSnInfoApi().sendAdminSn( - Utils.getSerial(), + DeviceSNManager.getDeviceSN(), "", machine, hardware, @@ -1241,7 +1255,7 @@ public class NetInterfaceManager { public ObservableSource apply(String s) throws Throwable { Log.e("SendAppInstallInfo", "apply: " + s); return getAppApi() - .installorRemove(Utils.getSerial(), s); + .installorRemove(DeviceSNManager.getDeviceSN(), s); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -1298,7 +1312,7 @@ public class NetInterfaceManager { MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), fileBody); Map params = new HashMap<>(); params.put("package", NetInterfaceManager.convertToRequestBody(packageInfo.packageName)); - Call call = getUploadAppImgApi().uploadAppImg(Utils.getSerial(), params, body); + Call call = getUploadAppImgApi().uploadAppImg(DeviceSNManager.getDeviceSN(), params, body); call.enqueue(new RetryCallback(call, 1, 30 * 1000) { @Override public void onRequestResponse(Call call, retrofit2.Response response) { @@ -1334,7 +1348,7 @@ public class NetInterfaceManager { public void screenshot() { // String path = mContext.getExternalFilesDir("db").getAbsolutePath(); String path = ContextCompat.getExternalFilesDirs(mContext, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath(); - String filePath = path + File.separator + Utils.getSerial() + ".png"; + String filePath = path + File.separator + DeviceSNManager.getDeviceSN() + ".png"; getScreenshot(filePath).concatMap(new Function>() { @Override public ObservableSource apply(Integer integer) throws Exception { @@ -1406,7 +1420,7 @@ public class NetInterfaceManager { private Observable getSendFile(String path, MultipartBody.Part body) { return getUploadScreenshotControl() - .getControlScreenshot(Utils.getSerial(), body) + .getControlScreenshot(DeviceSNManager.getDeviceSN(), body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } diff --git a/app/src/main/java/com/xwad/os/network/UrlAddress.java b/app/src/main/java/com/xwad/os/network/UrlAddress.java index 0f52b22..0688892 100644 --- a/app/src/main/java/com/xwad/os/network/UrlAddress.java +++ b/app/src/main/java/com/xwad/os/network/UrlAddress.java @@ -39,6 +39,8 @@ public class UrlAddress { public final static String APP_FORCE_INSTALL = "app/force-install"; /*根据包名获取更新*/ public final static String GET_NEWEST_APPUPDATE = "app/newestAppUpdate"; + /*获取灰度更新*/ + public static final String GET_TEST_APP_INFO = "app/getTestAppInfo"; /*发送卸载或者安装信息*/ public final static String SEND_INSTALLEDORREMOVED = "app/addAppInstall"; diff --git a/app/src/main/java/com/xwad/os/network/api/AppApi.java b/app/src/main/java/com/xwad/os/network/api/AppApi.java index 51e8c1e..93ec846 100644 --- a/app/src/main/java/com/xwad/os/network/api/AppApi.java +++ b/app/src/main/java/com/xwad/os/network/api/AppApi.java @@ -14,6 +14,18 @@ import retrofit2.http.POST; import retrofit2.http.Query; public interface AppApi { + @GET(UrlAddress.GET_ADMIN_APP) + Observable>> getAdminApp( + @Query("sn") String sn + ); + + @GET(UrlAddress.GET_ADMIN_APP) + Observable>> getAdminApp( + @Query("sn") String sn, + @Query("class_id") String class_id, + @Query("desktop_package") String desktop_package + ); + @GET(UrlAddress.APP_FORCE_INSTALL) Observable> getAdminApp( @Query("desktop_app_package") String desktop_app_package, @@ -27,15 +39,15 @@ public interface AppApi { @Query("type") int type ); + @GET(UrlAddress.GET_TEST_APP_INFO) + Observable>> getTestApp( + @Query("sn") String sn + ); + @FormUrlEncoded @POST(UrlAddress.SEND_INSTALLEDORREMOVED) Observable installorRemove( @Field("sn") String sn, @Field("app") String jsonString ); - - @GET(UrlAddress.GET_ADMIN_APP) - Observable>> getAdminApp( - @Query("sn") String sn - ); } diff --git a/app/src/main/java/com/xwad/os/push/PushManager.java b/app/src/main/java/com/xwad/os/push/PushManager.java index beaf6a8..9c90e9b 100644 --- a/app/src/main/java/com/xwad/os/push/PushManager.java +++ b/app/src/main/java/com/xwad/os/push/PushManager.java @@ -6,7 +6,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.graphics.Bitmap; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -29,12 +28,12 @@ import com.xwad.os.disklrucache.CacheHelper; import com.xwad.os.fragment.user.UserFragment; import com.xwad.os.gson.GsonUtils; import com.xwad.os.manager.ControlManager; +import com.xwad.os.manager.DeviceSNManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.network.RetryCallback; import com.xwad.os.service.ManagerService; import com.xwad.os.service.main.MainService; import com.xwad.os.utils.ApkUtils; -import com.xwad.os.utils.BitmapUtils; import com.xwad.os.utils.FileUtils; import com.xwad.os.utils.JgyUtils; import com.xwad.os.utils.ServiceAliveUtils; @@ -818,9 +817,9 @@ public class PushManager { //设置一个file文件 MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), fileBody); Map params = new HashMap<>(); - params.put("sn", Utils.getSerial(mContext)); + params.put("sn", DeviceSNManager.getDeviceSN()); params.put("createtime", String.valueOf(time)); - Call call = NetInterfaceManager.getInstance().getUploadScreenshotControl().uploadScreenshotCall(Utils.getSerial(mContext), body); + Call call = NetInterfaceManager.getInstance().getUploadScreenshotControl().uploadScreenshotCall(DeviceSNManager.getDeviceSN(), body); call.enqueue(new RetryCallback(call, 10, 30 * 1000) { @Override public void onRequestResponse(Call call, Response response) { diff --git a/app/src/main/java/com/xwad/os/service/DownloadService.java b/app/src/main/java/com/xwad/os/service/DownloadService.java index 9c93912..c6d7da0 100644 --- a/app/src/main/java/com/xwad/os/service/DownloadService.java +++ b/app/src/main/java/com/xwad/os/service/DownloadService.java @@ -204,7 +204,7 @@ public class DownloadService extends Service { @Download.onTaskComplete void taskComplete(DownloadTask task) { Log.e(TAG, "taskComplete: " + task.getFilePath()); - ApkUtils.installApp(DownloadService.this, task.getFilePath()); + ApkUtils.installApkFile(DownloadService.this, task.getFilePath()); String jsonString = task.getExtendField(); Log.e(TAG, "taskComplete: " + "下载完成:" + jsonString); AriaDownloadInfo ariaDownloadInfo = getAriaDownloadInfo(jsonString); diff --git a/app/src/main/java/com/xwad/os/service/ManagerService.java b/app/src/main/java/com/xwad/os/service/ManagerService.java index a3d08f3..a570b79 100644 --- a/app/src/main/java/com/xwad/os/service/ManagerService.java +++ b/app/src/main/java/com/xwad/os/service/ManagerService.java @@ -38,6 +38,7 @@ import com.xwad.os.R; import com.xwad.os.bean.BaseResponse; import com.xwad.os.config.CommonConfig; import com.xwad.os.gson.GsonUtils; +import com.xwad.os.manager.DeviceSNManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.receiver.ApkInstallReceiver; import com.xwad.os.receiver.BootReceiver; @@ -275,7 +276,7 @@ public class ManagerService extends Service implements NetworkUtils.OnNetworkSta private void getScreenLockState() { NetInterfaceManager.getInstance() .getSnInfoApi() - .getScreenshot(Utils.getSerial()) + .getScreenshot(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { diff --git a/app/src/main/java/com/xwad/os/service/RemoteService.java b/app/src/main/java/com/xwad/os/service/RemoteService.java new file mode 100644 index 0000000..b7452ba --- /dev/null +++ b/app/src/main/java/com/xwad/os/service/RemoteService.java @@ -0,0 +1,52 @@ +package com.xwad.os.service; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import com.tencent.mmkv.MMKV; +import com.xwad.os.IGetInfoInterface; +import com.xwad.os.config.CommonConfig; +import com.xwad.os.manager.DeviceSNManager; +import com.xwad.os.utils.Utils; + +public class RemoteService extends Service { + private static final String TAG = "RemoteService"; + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + public RemoteService() { + } + + @Override + public IBinder onBind(Intent intent) { + Log.e(TAG, "onBind: "); + return mBinde; + } + + @Override + public void onCreate() { + Log.e(TAG, "onCreate: "); + super.onCreate(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.e(TAG, "onStartCommand: "); + return super.onStartCommand(intent, flags, startId); + } + + private IBinder mBinde = new IGetInfoInterface.Stub() { + @Override + public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { + + } + + @Override + public String getSerial() throws RemoteException { + return DeviceSNManager.getDeviceSN(); + } + }; +} diff --git a/app/src/main/java/com/xwad/os/service/main/MainSContact.java b/app/src/main/java/com/xwad/os/service/main/MainSContact.java index 60d1699..35368a0 100644 --- a/app/src/main/java/com/xwad/os/service/main/MainSContact.java +++ b/app/src/main/java/com/xwad/os/service/main/MainSContact.java @@ -54,6 +54,8 @@ public class MainSContact { void getTestApp(); /*获取管理员应用*/ void getAdminApp(); + + void getAdminAppDownload(); /*获取id管控*/ void getAppInside(); diff --git a/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java b/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java index 1a4d020..7f8ba92 100644 --- a/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java +++ b/app/src/main/java/com/xwad/os/service/main/MainSPresenter.java @@ -2,6 +2,9 @@ package com.xwad.os.service.main; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; import android.util.Log; import com.google.gson.JsonObject; @@ -14,7 +17,7 @@ import com.xwad.os.bean.BaseResponse; import com.xwad.os.bean.UserInfo; import com.xwad.os.config.CommonConfig; import com.xwad.os.gson.GsonUtils; -import com.xwad.os.jxw.JxwPackageConfig; +import com.xwad.os.manager.DeviceSNManager; import com.xwad.os.network.NetInterfaceManager; import com.xwad.os.service.ManagerService; import com.xwad.os.utils.ActivationUtil; @@ -23,8 +26,12 @@ import com.xwad.os.utils.FileUtils; import com.xwad.os.utils.ServiceAliveUtils; import com.xwad.os.utils.Utils; +import java.util.Comparator; import java.util.List; import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -114,15 +121,16 @@ public class MainSPresenter implements MainSContact.Presenter { UserInfo userInfo = userInfoBaseResponse.data; int vip_level_id = userInfo.getVip_level_id(); if (vip_level_id != 0) { - if (!ApkUtils.isAvailable(mContext, JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME)) { - getAppInfo(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME); - } - if (!ApkUtils.isAvailable(mContext, "com.jxw.download")) { - getAppInfo("com.jxw.download"); - } - if (!ApkUtils.isAvailable(mContext, "com.study.flashplayer")) { - getAppInfo("com.study.flashplayer"); - } +// if (!ApkUtils.isAvailable(mContext, JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME)) { +// getAppInfo(JxwPackageConfig.JXW_LAUNCHER_PACKAGE_NAME); +// } +// if (!ApkUtils.isAvailable(mContext, "com.jxw.download")) { +// getAppInfo("com.jxw.download"); +// } +// if (!ApkUtils.isAvailable(mContext, "com.study.flashplayer")) { +// getAppInfo("com.study.flashplayer"); +// } + getAdminAppDownload(); } } else if (userInfoBaseResponse.code == 401) { @@ -224,7 +232,7 @@ public class MainSPresenter implements MainSContact.Presenter { public void getScreenLock() { NetInterfaceManager.getInstance() .getSnInfoApi() - .getScreenshot(Utils.getSerial()) + .getScreenshot(DeviceSNManager.getDeviceSN()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) @@ -282,12 +290,68 @@ public class MainSPresenter implements MainSContact.Presenter { @Override public void getTestApp() { + NetInterfaceManager.getInstance().getTestAppObservable() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getTestApp", "onSubscribe: "); + } + @Override + public void onNext(@NonNull BaseResponse> listBaseResponse) { + Log.e("getTestApp", "onNext: " + listBaseResponse); + if (listBaseResponse.code == 200) { + List appInfos = listBaseResponse.data; + PackageManager pm = mContext.getPackageManager(); + appInfos.forEach(new Consumer() { + @Override + public void accept(AppInfo appInfo) { + String packages = appInfo.getApp_package(); + long app_version_code = appInfo.getApp_version_code(); + PackageInfo packageInfo = null; + try { + packageInfo = pm.getPackageInfo(packages, 0); + + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (packageInfo != null) { + long appVersionCode; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + appVersionCode = packageInfo.getLongVersionCode(); + } else { + appVersionCode = packageInfo.versionCode; + } + if (app_version_code > appVersionCode) { + FileUtils.ariaDownload(mContext, appInfo.getApp_url(), appInfo); + } else { + Log.e("getTestApp", "intallApk: " + packages + " is up to date"); + } + } else { + FileUtils.ariaDownload(mContext, appInfo.getApp_url(), appInfo); + } + } + }); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getTestApp", "onError: "); + } + + @Override + public void onComplete() { + Log.e("getTestApp", "onComplete: "); + } + }); } @Override public void getAdminApp() { NetInterfaceManager.getInstance().getAdminAppObservable() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) .subscribe(new Observer>>() { @Override public void onSubscribe(@NonNull Disposable d) { @@ -319,6 +383,82 @@ public class MainSPresenter implements MainSContact.Presenter { }); } + @Override + public void getAdminAppDownload() { + NetInterfaceManager.getInstance().getAdminAppObservable() + .compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY)) + .subscribe(new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getAdminAppDownload", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> listBaseResponse) { + Log.e("getAdminAppDownload", "onNext: " + listBaseResponse); + if (listBaseResponse.code == 200) { + List appInfoList = listBaseResponse.data; + appInfoList.stream() + .sorted(new Comparator() { + @Override + public int compare(AppInfo o1, AppInfo o2) { + if ("com.jxw.launcher".equals(o1.getApp_package()) && !"com.jxw.launcher".equals(o2.getApp_package())) { + return -1; + } else if (!"com.jxw.launcher".equals(o1.getApp_package()) && "com.jxw.launcher".equals(o2.getApp_package())) { + return 1; + } else { + return o1.getApp_package().compareTo(o2.getApp_package()); // 非目标包名按字母排序 + } + } + }) + .filter(new Predicate() { + @Override + public boolean test(AppInfo appInfo) { + return appInfo.getIs_must_components() == 1; + } + }) + .forEach(new Consumer() { + @Override + public void accept(AppInfo appInfo) { + if (appInfo.getIs_must_components_down() == 1) { + if (!ApkUtils.isAvailable(mContext, appInfo.getApp_package())) { +// FileUtils.ariaDownload(mContext, appInfo.getApp_url(), appInfo); + } + } + } + }); + + Set packageSets = appInfoList.stream() + .filter(new Predicate() { + @Override + public boolean test(AppInfo appInfo) { + return appInfo.getIs_must_components() == 1; + } + }) + .map(new Function() { + @Override + public String apply(AppInfo appInfo) { + return appInfo.getApp_package(); + } + }) + .collect(Collectors.toSet()); + mMMKV.encode(CommonConfig.ESSENTIAL_COMPONENT_APPLICATIONS, packageSets); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getAdminAppDownload", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getAdminAppDownload", "onComplete: "); + } + }); + } + @Override public void getAppInside() { diff --git a/app/src/main/java/com/xwad/os/service/main/MainService.java b/app/src/main/java/com/xwad/os/service/main/MainService.java index 6d6d856..ec3de0a 100644 --- a/app/src/main/java/com/xwad/os/service/main/MainService.java +++ b/app/src/main/java/com/xwad/os/service/main/MainService.java @@ -96,7 +96,9 @@ public class MainService extends BaseRxService implements MainSContact.MainSView mPresenter.updateDeviceInfo(); mPresenter.getAppIcon(); mPresenter.getScreenLock(); + mPresenter.getTestApp(); mPresenter.getAdminApp(); + mPresenter.getAdminAppDownload(); mPresenter.getSystemSettings(); mPresenter.getLockScreenPwd(); diff --git a/app/src/main/java/com/xwad/os/utils/ApkUtils.java b/app/src/main/java/com/xwad/os/utils/ApkUtils.java index 173343d..0db3363 100644 --- a/app/src/main/java/com/xwad/os/utils/ApkUtils.java +++ b/app/src/main/java/com/xwad/os/utils/ApkUtils.java @@ -597,6 +597,7 @@ public class ApkUtils { * @param context 上下文 * @param filePath apk文件路径 */ + @Deprecated public static void installApp(Context context, String filePath) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { installAppatPie(context, filePath); @@ -853,9 +854,9 @@ public class ApkUtils { } } - public static boolean isUpdate(Context context, AppInfo appUpdateInfo) { - String packageName = appUpdateInfo.getApp_package(); - long versionCode = appUpdateInfo.getApp_version_code(); + public static boolean isUpdate(Context context, AppInfo appInfo) { + String packageName = appInfo.getApp_package(); + long versionCode = appInfo.getApp_version_code(); return isUpdate(context, packageName, versionCode); } diff --git a/app/src/main/java/com/xwad/os/utils/FileUtils.java b/app/src/main/java/com/xwad/os/utils/FileUtils.java index c07e923..54ff164 100644 --- a/app/src/main/java/com/xwad/os/utils/FileUtils.java +++ b/app/src/main/java/com/xwad/os/utils/FileUtils.java @@ -269,7 +269,7 @@ public class FileUtils { String fileMd5 = com.blankj.utilcode.util.FileUtils.getFileMD5ToString(file); Log.e("ariaDownload", "fileMD5 = " + fileMd5); if (fileMd5.equalsIgnoreCase(app_md5)) { - ApkUtils.installApp(context, file.getAbsolutePath()); + ApkUtils.installApkFile(context, file.getAbsolutePath()); } else { file.delete(); Aria.download(context) diff --git a/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java b/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java index ee45cd2..3a14de3 100644 --- a/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java +++ b/app/src/main/java/com/xwad/os/utils/OpenApkUtils.java @@ -25,6 +25,7 @@ import com.hjq.toast.Toaster; import com.tencent.mmkv.MMKV; import com.xwad.os.R; import com.xwad.os.activity.activation.ActivationActivity; +import com.xwad.os.activity.download.DownloadActivity; import com.xwad.os.activity.login.LoginActivity; import com.xwad.os.bean.AppInfo; import com.xwad.os.bean.BaseResponse; @@ -689,16 +690,6 @@ public class OpenApkUtils { } 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)); @@ -711,15 +702,39 @@ public class OpenApkUtils { return; } + if (checkInstall) { + if (!checkEssentialAppAllInstall()) { + activity.startActivity(new Intent(activity, DownloadActivity.class)); +// DefaultAppsDialog appsDialog = new DefaultAppsDialog(activity); +// appsDialog.show(); + Toaster.show("请先安装必备组件"); + return; + } + } + if (TextUtils.isEmpty(paramStr)) { Log.e(TAG, "context为空或参数字符串为空"); return; } -// } openJxwApp(activity, paramStr); } + private boolean checkEssentialAppAllInstall() { + Set essentialAppSets = mMMKV.decodeStringSet(CommonConfig.ESSENTIAL_COMPONENT_APPLICATIONS, CommonConfig.ESSENTIAL_APPLICATIONS_SETS); + Log.e(TAG, "checkEssentialAppAllInstall: " + essentialAppSets); + boolean allTrue = essentialAppSets.stream().allMatch(new Predicate() { + @Override + public boolean test(String s) { + boolean install = ApkUtils.isAvailable(mContext, s); + Log.e(TAG, "checkEssentialAppAllInstall: " + s + " " + install); + return install; + } + }); + Log.e(TAG, "checkEssentialAppAllInstall: " + allTrue); + return allTrue; + } + /** * 根据参数字符串打开对应页面 * @@ -864,6 +879,48 @@ public class OpenApkUtils { } } + public void showDownloadDialog(Activity context, AppInfo appInfo, String conetnt) { + Dialog dialog = new Dialog(context, R.style.ActionSheet); + Window window = dialog.getWindow(); + View inflate = ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.download_dialog, null); + TextView textView = inflate.findViewById(R.id.download_cancel); + TextView textView2 = inflate.findViewById(R.id.tag_title); + if (!TextUtils.isEmpty(appInfo.getApp_name())) { + textView2.setText(conetnt); + } + TextView textView3 = inflate.findViewById(R.id.download_ok); + textView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dialog.dismiss(); + } + }); + textView3.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + FileUtils.ariaDownload(mContext, appInfo.getApp_url(), appInfo); + Intent intent = new Intent(mContext, DownloadService.class); +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { +// mContext.startForegroundService(intent); +// } else { + mContext.startService(intent); +// } + dialog.dismiss(); + } + }); + WindowManager.LayoutParams attributes = window.getAttributes(); + attributes.x = 0; + attributes.y = 0; + attributes.gravity = Gravity.CENTER; + dialog.onWindowAttributesChanged(attributes); + dialog.setCanceledOnTouchOutside(true); + dialog.setContentView(inflate); + window.setDimAmount(0.6f); + dialog.show(); + window.setAttributes(attributes); + } + + public void showDownloadDialog(Activity context, String pkg, String appName) { Dialog dialog = new Dialog(context, R.style.ActionSheet); Window window = dialog.getWindow(); diff --git a/app/src/main/java/com/xwad/os/utils/Utils.java b/app/src/main/java/com/xwad/os/utils/Utils.java index 3a071b9..b3c1595 100644 --- a/app/src/main/java/com/xwad/os/utils/Utils.java +++ b/app/src/main/java/com/xwad/os/utils/Utils.java @@ -1,6 +1,7 @@ package com.xwad.os.utils; import android.Manifest; +import android.app.Activity; import android.app.ActivityManager; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; @@ -10,6 +11,7 @@ import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -44,6 +46,7 @@ import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.tencent.mmkv.MMKV; +import com.xwad.os.BuildConfig; import com.xwad.os.R; import com.xwad.os.config.CommonConfig; import com.xwad.os.network.NetInterfaceManager; @@ -66,7 +69,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static android.content.Context.WIFI_SERVICE; @@ -101,6 +107,8 @@ public class Utils { // } // return serial; // } + + public static String getAndroiodScreenProperty(Context context) { Log.e("getAndroiodScreenProperty", "heightPixels:" + context.getResources().getDisplayMetrics().heightPixels); Log.e("getAndroiodScreenProperty", "widthPixels:" + context.getResources().getDisplayMetrics().widthPixels); @@ -474,39 +482,57 @@ public class Utils { return powerManager.isInteractive(); } -// public static void exitDesktop(Activity context) { -// if ("HONOR".equalsIgnoreCase(Build.BRAND)) { -//// AdminManager.getInstance().exitDesktop(); -//// AdminManager.getInstance().setDefaultDesktop("com.hihonor.android.launcher"); -// } else { -// if ("U807".equals(BuildConfig.platform) && ApkUtils.isAvailable(context, "com.uiuipad.os")) { -// AdminManager.getInstance().setDefaultLauncher("com.uiuipad.os"); -// } else { -// AdminManager.getInstance().setDefaultLauncher(ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME); -// } -// -// if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { -// if ("U807".equals(BuildConfig.platform) && ApkUtils.isAvailable(context, "com.uiuipad.os")) { -// -// if (!ApkUtils.openPackage(context, "com.uiuipad.os", "com.uiuipad.os.Launcher")) { -// ApkUtils.gotoLauncher(context); -// } -// } else { -// -// if (!ApkUtils.openPackage(context, ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME, ApkUtils.ANDROID_LAUNCHER3_Quickstep_CLASS_NAME)) { -// ApkUtils.gotoLauncher(context); -// } -// } -// } else { -// -// if (!ApkUtils.openPackage(context, ApkUtils.ANDROID_LAUNCHER3_PACKAGE_NAME, ApkUtils.ANDROID_LAUNCHER3_CLASS_NAME)) { -// ApkUtils.gotoLauncher(context); -// } -// } -// } -// context.finish(); -// System.exit(0); -// } + public static void exitDesktop(Activity activity) { + activity.startActivity(new Intent(Settings.ACTION_HOME_SETTINGS)); + + List componentNames = getAllLauncherApps(activity); + Log.e(TAG, "exitDesktop: " + componentNames); + if (componentNames != null && componentNames.size() != 0) { + ComponentName componentName = componentNames.get(0); + Intent intent = new Intent(); + intent.setComponent(componentName); + try { + activity.startActivity(intent); + } catch (Exception e) { + Log.e(TAG, "exitDesktop: " + e.getMessage()); + } + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + activity.finishAndRemoveTask(); + } else { + activity.finishAffinity(); + } + android.os.Process.killProcess(android.os.Process.myPid()); + System.exit(0); + } + + private static List getAllLauncherApps(Context context) { + PackageManager packageManager = context.getPackageManager(); + + // 构建用于查询桌面应用的Intent + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_HOME); + + // 查询所有可以处理该Intent的Activity + List resolveInfoList = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL); + + List launcherPackageList = resolveInfoList.stream().filter(new Predicate() { + @Override + public boolean test(ResolveInfo resolveInfo) { + return !BuildConfig.APPLICATION_ID.equals(resolveInfo.activityInfo.packageName) + || !"com.jxw.launcher".equals(resolveInfo.activityInfo.packageName) + || !"com.handuan.os".equals(resolveInfo.activityInfo.packageName); + } + }).map(new Function() { + @Override + public ComponentName apply(ResolveInfo resolveInfo) { + return resolveInfo.getComponentInfo().getComponentName(); + } + }).collect(Collectors.toList()); + + return launcherPackageList; + } public static void triggerRebirth(Context context) { PackageManager packageManager = context.getPackageManager(); diff --git a/app/src/main/res/drawable-hdpi/icon_back1.png b/app/src/main/res/drawable-hdpi/icon_back1.png new file mode 100644 index 0000000..e4b6c8b Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_back1.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_btk.png b/app/src/main/res/drawable-hdpi/icon_btk.png new file mode 100644 index 0000000..94d2071 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_btk.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_qdy.webp b/app/src/main/res/drawable-hdpi/icon_qdy.webp new file mode 100644 index 0000000..c0b3b9e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_qdy.webp differ diff --git a/app/src/main/res/drawable-hdpi/icon_qst.png b/app/src/main/res/drawable-hdpi/icon_qst.png new file mode 100644 index 0000000..0ea9a57 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_qst.png differ diff --git a/app/src/main/res/drawable/ic_download_all.xml b/app/src/main/res/drawable/ic_download_all.xml new file mode 100644 index 0000000..dd2cfc8 --- /dev/null +++ b/app/src/main/res/drawable/ic_download_all.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_update.xml b/app/src/main/res/drawable/ic_update.xml new file mode 100644 index 0000000..88c0179 --- /dev/null +++ b/app/src/main/res/drawable/ic_update.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_activation.xml b/app/src/main/res/layout/activity_activation.xml index 4defda8..0912630 100644 --- a/app/src/main/res/layout/activity_activation.xml +++ b/app/src/main/res/layout/activity_activation.xml @@ -119,7 +119,8 @@ + android:layout_weight="1" + android:visibility="gone"> + android:layout_height="wrap_content"> - + app:layout_constraintTop_toTopOf="parent"> + + + + + + + android:layout_height="wrap_content" + android:layout_marginTop="4dp"> + + + + + + + + + + + + android:src="@drawable/icon_alipay" + android:visibility="gone" /> - - - - - - - - - - - - - - - - - - + app:layout_constraintTop_toTopOf="parent" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_other_app.xml b/app/src/main/res/layout/activity_other_app.xml new file mode 100644 index 0000000..972a2e1 --- /dev/null +++ b/app/src/main/res/layout/activity_other_app.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/book_layout_title_bar.xml b/app/src/main/res/layout/book_layout_title_bar.xml new file mode 100644 index 0000000..7cecdbc --- /dev/null +++ b/app/src/main/res/layout/book_layout_title_bar.xml @@ -0,0 +1,35 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_default_apps.xml b/app/src/main/res/layout/dialog_default_apps.xml index 057a7d0..06fe9ec 100644 --- a/app/src/main/res/layout/dialog_default_apps.xml +++ b/app/src/main/res/layout/dialog_default_apps.xml @@ -23,7 +23,7 @@ android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_marginTop="3dp" - android:text="必备组件" + android:text="组件安装" android:textColor="#333333" android:textSize="12sp" /> diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml index 57b416d..85a915c 100644 --- a/app/src/main/res/layout/fragment_mine.xml +++ b/app/src/main/res/layout/fragment_mine.xml @@ -763,7 +763,7 @@ android:layout_gravity="center_horizontal" android:layout_marginTop="2dp" android:singleLine="true" - android:text="必备组件" + android:text="组件安装" android:textColor="@color/white" android:textSize="@dimen/mine_app_name_size" app:layout_constraintEnd_toEndOf="@+id/app_icon11" diff --git a/app/src/main/res/layout/item_app_info.xml b/app/src/main/res/layout/item_app_info.xml new file mode 100644 index 0000000..d92a5f7 --- /dev/null +++ b/app/src/main/res/layout/item_app_info.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_dialog_app_force.xml b/app/src/main/res/layout/item_dialog_app_force.xml index b410b8d..7584823 100644 --- a/app/src/main/res/layout/item_dialog_app_force.xml +++ b/app/src/main/res/layout/item_dialog_app_force.xml @@ -1,6 +1,7 @@ @@ -31,7 +32,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" - android:text="当前壁纸" + tools:text="当前壁纸" android:textColor="#333333" android:textSize="9sp" app:layout_constraintBottom_toBottomOf="parent" diff --git a/app/src/main/res/values/colors_jxw.xml b/app/src/main/res/values/colors_jxw.xml index 7ca640f..f638f7f 100644 --- a/app/src/main/res/values/colors_jxw.xml +++ b/app/src/main/res/values/colors_jxw.xml @@ -10,6 +10,7 @@ #bbffffff #ff33b5e5 + #333333 \ No newline at end of file diff --git a/app/src/main/res/values/string_jxw.xml b/app/src/main/res/values/string_jxw.xml index 8611f45..634efb2 100644 --- a/app/src/main/res/values/string_jxw.xml +++ b/app/src/main/res/values/string_jxw.xml @@ -836,4 +836,8 @@ 设\t置 pag/exp_baoxiang_ywc.pag pag/exp_liwuhe_ywc.pag + + + 暂无内容,请先去下载吧! + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 997915f..4af8b59 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -70,5 +70,6 @@ 为学王365提供管控功能,请激活后使用 开启我吧 + 1、必备组件维持系统基本运行,请优先安装,并【允许】所有权限弹窗请求; diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index ac4f8c6..e993d30 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -137,4 +137,24 @@ stateVisible|adjustPan + + + + + +