diff --git a/app/build.gradle b/app/build.gradle index b369eba..6217113 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' static def appName() { - return "设备绑定" + return "小酷守护" } static def releaseTime() { @@ -16,8 +16,8 @@ android { applicationId "com.uiuipad.find" minSdkVersion 24 targetSdkVersion 29 - versionCode 1 - versionName "1.0" + versionCode 3 + versionName "1.0.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -57,10 +57,32 @@ android { v2SigningEnabled false } + U807 { + storeFile file("keystore/AllwinnerU807.jks") + storePassword "123456" + keyAlias "u807" + keyPassword "123456" + v2SigningEnabled false + } + } buildTypes { + U807Debug.initWith(debug) + U807Debug { + buildConfigField "String", "platform", '"U807"' + versionNameSuffix "-debug" + debuggable true + signingConfig signingConfigs.U807 + } + + U807Release.initWith(release) + U807Release { + buildConfigField "String", "platform", '"U807"' + signingConfig signingConfigs.U807 + } + debug { versionNameSuffix "-debug" debuggable true @@ -155,7 +177,9 @@ dependencies { implementation 'com.gitee.zackratos:UltimateBarX:0.8.0' implementation 'com.jakewharton.rxbinding2:rxbinding:2.2.0' - + //Aria + implementation 'com.arialyy.aria:core:3.8.15' + annotationProcessor 'com.arialyy.aria:compiler:3.8.15' } preBuild { diff --git a/app/keystore/AllwinnerU807.jks b/app/keystore/AllwinnerU807.jks new file mode 100644 index 0000000..c8d68c5 Binary files /dev/null and b/app/keystore/AllwinnerU807.jks differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 05f05b2..6bb0302 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -78,6 +78,31 @@ + + + + + + + + + + + + + + + + + + + android:value="333898263" /> + android:value="e1b374229ffe479eb34ba74432b7e454" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/uiuipad/find/activity/AudioActivity.java b/app/src/main/java/com/uiuipad/find/activity/AudioActivity.java new file mode 100644 index 0000000..330a3a7 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/activity/AudioActivity.java @@ -0,0 +1,164 @@ +package com.uiuipad.find.activity; + +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.os.PowerManager; +import android.os.Vibrator; +import android.util.Log; +import android.view.View; +import android.widget.TextView; + +import com.uiuipad.find.BuildConfig; +import com.uiuipad.find.R; +import com.uiuipad.find.base.BaseActivity; +import com.uiuipad.find.util.WakeUpUtils; + +import butterknife.BindView; +import butterknife.ButterKnife; + +public class AudioActivity extends BaseActivity { + private static final String TAG = AudioActivity.class.getSimpleName(); + + @BindView(R.id.tv_stop) + TextView tv_stop; + + private PowerManager pm; + private PowerManager.WakeLock wakeLock; + private AudioManager audioManager; + private Vibrator vibrator; + + @Override + public int getLayoutId() { + return R.layout.activity_audio; + } + + @Override + public void initView() { + ButterKnife.bind(this); + + tv_stop.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + releasePlayer(); + finish(); + } + }); + } + + @Override + public void initData() { + pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "WakeAndLock"); + wakeLock.acquire(60 * 1000L); + vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + if (vibrator.hasVibrator()) { + long[] pattern = {1000, 5000, 1000, 5000}; + vibrator.vibrate(pattern, 0); + } else { + Log.e(TAG, "initView: no vibrator"); + } + WakeUpUtils.wakeUpAndUnlockScreen(this); + setMaxVolume(); + defaultCallMediaPlayer(); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + Log.e(TAG, "onNewIntent: " + intent.getAction()); + } + + @Override + protected void onDestroy() { + vibrator.cancel(); + releasePlayer(); + mediaPlayer = null; + super.onDestroy(); + } + + private void releasePlayer() { + try { + if (mediaPlayer != null) { + if (mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + } + mediaPlayer.release(); + } + } catch (Exception e) { + Log.e(TAG, "releasePlayer: " + e.getMessage()); + } + } + + /** + * 播放系统默认来电铃声 + * + * @return MediaPlayer对象 + * @throws Exception + */ + MediaPlayer mediaPlayer; + + public void defaultCallMediaPlayer() { + if (mediaPlayer != null) { + if (mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + } + mediaPlayer.release(); + } + mediaPlayer = MediaPlayer.create(this, R.raw.test); + try { +// mediaPlayer.prepare(); + mediaPlayer.setLooping(false); + int duration = mediaPlayer.getDuration() / 1000; + Log.e(TAG, "defaultCallMediaPlayer: " + "duration: " + duration); + int loop = 0; + if (duration <= 1) { + loop = 30; + } else { + loop = (30 / duration); + } + final int[] soundCount = {0}; + int finalLoop = loop; + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mediaPlayer) { + if (soundCount[0] <= finalLoop) { + setMaxVolume(); + mediaPlayer.start(); + soundCount[0] += 1; + Log.e(TAG, "onCompletion: " + "loop: " + finalLoop); + Log.e(TAG, "onCompletion: " + "soundCount: " + soundCount[0]); + } else { + if (mediaPlayer.isPlaying()) { + mediaPlayer.stop(); + } + mediaPlayer.release(); + Log.e(TAG, "onCompletion: " + "loop: " + finalLoop); + Log.e(TAG, "onCompletion: " + "soundCount: " + soundCount[0]); + } + } + }); + mediaPlayer.setLooping(false); + mediaPlayer.start(); + } catch (Exception e) { + e.printStackTrace(); + Log.e(TAG, "defaultCallMediaPlayer: " + e.getMessage()); + } + } + + private void setMaxVolume() { + if (BuildConfig.DEBUG) { + return; + } + AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + int ringMax = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING); + int musicMax = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); + int voiceMax = audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); + audioManager.setStreamVolume(AudioManager.STREAM_RING, ringMax, 0); + audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, voiceMax, 0); + audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, musicMax, 0); //音乐音量 + audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); + audioManager.setSpeakerphoneOn(true); + } +} diff --git a/app/src/main/java/com/uiuipad/find/activity/main/MainAContact.java b/app/src/main/java/com/uiuipad/find/activity/main/MainAContact.java index 81b598c..458eedc 100644 --- a/app/src/main/java/com/uiuipad/find/activity/main/MainAContact.java +++ b/app/src/main/java/com/uiuipad/find/activity/main/MainAContact.java @@ -4,14 +4,17 @@ import android.graphics.Bitmap; import com.uiuipad.find.base.BasePresenter; import com.uiuipad.find.base.BaseView; +import com.uiuipad.find.bean.SnInfo; public class MainAContact { interface Presenter extends BasePresenter { /*获取二维码*/ void getQrCode(); + void getSnInfo(); } public interface MainView extends BaseView { void setQrCode(Bitmap bitmap); + void setSnInfo(SnInfo snInfo); } } diff --git a/app/src/main/java/com/uiuipad/find/activity/main/MainAPresenter.java b/app/src/main/java/com/uiuipad/find/activity/main/MainAPresenter.java index e34742c..b7129a8 100644 --- a/app/src/main/java/com/uiuipad/find/activity/main/MainAPresenter.java +++ b/app/src/main/java/com/uiuipad/find/activity/main/MainAPresenter.java @@ -4,12 +4,19 @@ import android.content.Context; import android.graphics.Bitmap; import android.util.Log; +import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.android.ActivityEvent; +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.bean.SnInfo; import com.uiuipad.find.comm.CommonConfig; +import com.uiuipad.find.network.NetInterfaceManager; import com.uiuipad.find.util.BitmapUtils; import com.uiuipad.find.util.CXAESUtil; import com.uiuipad.find.util.Utils; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.subjects.BehaviorSubject; /** @@ -53,4 +60,38 @@ public class MainAPresenter implements MainAContact.Presenter { mView.setQrCode(bitmap); } + @Override + public void getSnInfo() { + NetInterfaceManager.getInstance().getSnInfoControl() + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getSnInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse snInfoBaseResponse) { + Log.e("getSnInfo", "onNext: " + snInfoBaseResponse); + if (snInfoBaseResponse.code == 200) { + SnInfo snInfo = snInfoBaseResponse.data; + mView.setSnInfo(snInfo); + }else { + mView.setSnInfo(null); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getSnInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("getSnInfo", "onComplete: "); + } + }); + + } + } diff --git a/app/src/main/java/com/uiuipad/find/activity/main/MainActivity.java b/app/src/main/java/com/uiuipad/find/activity/main/MainActivity.java index 44e0745..f906160 100644 --- a/app/src/main/java/com/uiuipad/find/activity/main/MainActivity.java +++ b/app/src/main/java/com/uiuipad/find/activity/main/MainActivity.java @@ -1,12 +1,29 @@ package com.uiuipad.find.activity.main; +import android.content.ComponentName; +import android.content.Intent; +import android.content.ServiceConnection; import android.graphics.Bitmap; +import android.os.IBinder; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Button; import android.widget.ImageView; +import android.widget.TextView; import com.blankj.utilcode.util.NetworkUtils; +import com.blankj.utilcode.util.StringUtils; +import com.shehuan.niv.NiceImageView; import com.uiuipad.find.BuildConfig; import com.uiuipad.find.R; import com.uiuipad.find.base.BaseActivity; +import com.uiuipad.find.bean.SnInfo; +import com.uiuipad.find.service.ManagerService; +import com.uiuipad.find.service.main.MainService; +import com.uiuipad.find.util.TimeUtils; +import com.uiuipad.find.util.ToastUtil; +import com.uiuipad.find.util.Utils; import butterknife.BindView; import butterknife.ButterKnife; @@ -14,15 +31,29 @@ import butterknife.ButterKnife; public class MainActivity extends BaseActivity implements MainAContact.MainView, NetworkUtils.OnNetworkStatusChangedListener { private static final String TAG = MainActivity.class.getSimpleName(); - public static final String REFRESHACTION = BuildConfig.APPLICATION_ID + ".REFRESH"; - + @BindView(R.id.iv_back) + ImageView iv_back; + @BindView(R.id.tv_version) + TextView tv_version; + @BindView(R.id.iv_avatar) + NiceImageView iv_avatar; + @BindView(R.id.tv_phone) + TextView tv_phone; + @BindView(R.id.tv_serial) + TextView tv_serial; + @BindView(R.id.tv_bind_phone) + TextView tv_bind_phone; + @BindView(R.id.tv_bind_time) + TextView tv_bind_time; @BindView(R.id.iv_qrcode) ImageView iv_qrcode; + @BindView(R.id.bt_update) + Button bt_update; + private MainAPresenter mPresenter; - @Override public void onDisconnected() { @@ -38,6 +69,18 @@ public class MainActivity extends BaseActivity implements MainAContact.MainView, return R.layout.activity_main; } + + private long mPreClickTime; + + private void lazyExit() { + if (System.currentTimeMillis() - mPreClickTime > 3000) { + ToastUtil.show("再按一次,退出"); + mPreClickTime = System.currentTimeMillis(); + } else { + finish(); + } + } + @Override public void initView() { ButterKnife.bind(this); @@ -45,6 +88,41 @@ public class MainActivity extends BaseActivity implements MainAContact.MainView, mPresenter.setLifecycle(lifecycleSubject); mPresenter.attachView(this); NetworkUtils.registerNetworkStatusChangedListener(this); + + startService(new Intent(this, ManagerService.class)); + Intent intent = new Intent(MainActivity.this, MainService.class); + bindService(intent, serviceConnect, BIND_AUTO_CREATE); + startService(intent); + + iv_back.setOnClickListener(view -> lazyExit()); + + tv_version.setText(BuildConfig.VERSION_NAME); + tv_serial.setText(Utils.getSerial()); + + bt_update.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (mMainBinder != null) { + mMainBinder.getService().mPresenter.getSelfApp(); + } + } + }); + } + + MainService.MainBinder mMainBinder; + private ServiceConnect serviceConnect = new ServiceConnect(); + + private class ServiceConnect implements ServiceConnection { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + Log.e(TAG, "onServiceConnected: "); + mMainBinder = (MainService.MainBinder) service; + } + + @Override + public void onServiceDisconnected(ComponentName name) { + Log.e(TAG, "onServiceDisconnected: "); + } } @Override @@ -52,9 +130,35 @@ public class MainActivity extends BaseActivity implements MainAContact.MainView, mPresenter.getQrCode(); } + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == KeyEvent.ACTION_DOWN) { + lazyExit(); + return true; + } + return super.onKeyDown(keyCode, event); + } @Override public void setQrCode(Bitmap bitmap) { iv_qrcode.setImageBitmap(bitmap); + mPresenter.getSnInfo(); + } + + @Override + public void setSnInfo(SnInfo snInfo) { + if (snInfo==null){ + tv_phone.setText("未绑定"); + }else { + String phone =snInfo.getMobile(); + if (StringUtils.isEmpty(phone)){ + tv_phone.setText("未绑定"); + tv_bind_time.setText("未绑定"); + }else { + tv_phone.setText(phone); + long bindTime = snInfo.getBind_time(); + tv_bind_time.setText(String.format(getString(R.string.binding_time), TimeUtils.transferSecondToDate(bindTime))); + } + } } } diff --git a/app/src/main/java/com/uiuipad/find/base/BaseApplication.java b/app/src/main/java/com/uiuipad/find/base/BaseApplication.java index f7a0696..769ddbc 100644 --- a/app/src/main/java/com/uiuipad/find/base/BaseApplication.java +++ b/app/src/main/java/com/uiuipad/find/base/BaseApplication.java @@ -9,9 +9,11 @@ import android.util.Log; import com.alibaba.sdk.android.push.CloudPushService; import com.alibaba.sdk.android.push.CommonCallback; import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory; +import com.arialyy.aria.core.Aria; import com.tencent.mmkv.MMKV; import com.uiuipad.find.BuildConfig; import com.uiuipad.find.manager.MapManager; +import com.uiuipad.find.network.NetInterfaceManager; import com.uiuipad.find.push.PushManager; import com.uiuipad.find.util.Utils; @@ -31,6 +33,8 @@ public class BaseApplication extends Application { String rootDir = MMKV.initialize(this); Log.i(TAG, "mmkv root: " + rootDir); + Aria.init(this); + NetInterfaceManager.init(this); PushManager.init(this); MapManager.init(this); aliyunPushInit(); diff --git a/app/src/main/java/com/uiuipad/find/base/BaseLightLifecycleActivity.java b/app/src/main/java/com/uiuipad/find/base/BaseLightLifecycleActivity.java deleted file mode 100644 index b25eeed..0000000 --- a/app/src/main/java/com/uiuipad/find/base/BaseLightLifecycleActivity.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.uiuipad.find.base; - -import android.os.Bundle; - -import androidx.annotation.CallSuper; -import androidx.annotation.CheckResult; -import androidx.annotation.ContentView; -import androidx.annotation.LayoutRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; - -import com.trello.rxlifecycle4.LifecycleProvider; -import com.trello.rxlifecycle4.LifecycleTransformer; -import com.trello.rxlifecycle4.RxLifecycle; -import com.trello.rxlifecycle4.android.ActivityEvent; -import com.trello.rxlifecycle4.android.RxLifecycleAndroid; - -import io.reactivex.rxjava3.core.Observable; -import io.reactivex.rxjava3.subjects.BehaviorSubject; - -public abstract class BaseLightLifecycleActivity extends AppCompatActivity implements LifecycleProvider { - public final BehaviorSubject lifecycleSubject = BehaviorSubject.create(); - - public BaseLightLifecycleActivity() { - super(); - } - - @ContentView - public BaseLightLifecycleActivity(@LayoutRes int contentLayoutId) { - super(contentLayoutId); - } - - @Override - @NonNull - @CheckResult - public final Observable lifecycle() { - return lifecycleSubject.hide(); - } - - @Override - @NonNull - @CheckResult - public final LifecycleTransformer bindUntilEvent(@NonNull ActivityEvent event) { - return RxLifecycle.bindUntilEvent(lifecycleSubject, event); - } - - @Override - @NonNull - @CheckResult - public final LifecycleTransformer bindToLifecycle() { - return RxLifecycleAndroid.bindActivity(lifecycleSubject); - } - - @Override - @CallSuper - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - lifecycleSubject.onNext(ActivityEvent.CREATE); - setContentView(this.getLayoutId()); - initView(); - initData(); - } - - /** - * 设置布局 - */ - public abstract int getLayoutId(); - - /** - * 初始化视图 - */ - public abstract void initView(); - - - /** - * 初始化数据 - */ - public abstract void initData(); - - @Override - @CallSuper - protected void onStart() { - super.onStart(); - lifecycleSubject.onNext(ActivityEvent.START); - } - - @Override - @CallSuper - protected void onResume() { - super.onResume(); - lifecycleSubject.onNext(ActivityEvent.RESUME); - } - - @Override - @CallSuper - protected void onPause() { - lifecycleSubject.onNext(ActivityEvent.PAUSE); - super.onPause(); - } - - @Override - @CallSuper - protected void onStop() { - lifecycleSubject.onNext(ActivityEvent.STOP); - super.onStop(); - } - - @Override - @CallSuper - protected void onDestroy() { - lifecycleSubject.onNext(ActivityEvent.DESTROY); - super.onDestroy(); - } -} diff --git a/app/src/main/java/com/uiuipad/find/bean/AppInfo.java b/app/src/main/java/com/uiuipad/find/bean/AppInfo.java new file mode 100644 index 0000000..00deced --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/bean/AppInfo.java @@ -0,0 +1,98 @@ +package com.uiuipad.find.bean; + +import java.io.Serializable; + +public class AppInfo implements Serializable { + private static final long serialVersionUID = -7803980792149148619L; + + String app_name; + String app_package; + String app_version_name; + long app_version_code; + long app_size; + String app_url; + String app_icon; + String app_md5; + float app_score; + String app_developer; + + public String getApp_name() { + return app_name; + } + + public void setApp_name(String app_name) { + this.app_name = app_name; + } + + public String getApp_package() { + return app_package; + } + + public void setApp_package(String app_package) { + this.app_package = app_package; + } + + public String getApp_version_name() { + return app_version_name; + } + + public void setApp_version_name(String app_version_name) { + this.app_version_name = app_version_name; + } + + public long getApp_version_code() { + return app_version_code; + } + + public void setApp_version_code(long app_version_code) { + this.app_version_code = app_version_code; + } + + public long getApp_size() { + return app_size; + } + + public void setApp_size(long app_size) { + this.app_size = app_size; + } + + public String getApp_url() { + return app_url; + } + + public void setApp_url(String app_url) { + this.app_url = app_url; + } + + public String getApp_icon() { + return app_icon; + } + + public void setApp_icon(String app_icon) { + this.app_icon = app_icon; + } + + public String getApp_md5() { + return app_md5; + } + + public void setApp_md5(String app_md5) { + this.app_md5 = app_md5; + } + + public float getApp_score() { + return app_score; + } + + public void setApp_score(float app_score) { + this.app_score = app_score; + } + + public String getApp_developer() { + return app_developer; + } + + public void setApp_developer(String app_developer) { + this.app_developer = app_developer; + } +} diff --git a/app/src/main/java/com/uiuipad/find/bean/InstallAppInfo.java b/app/src/main/java/com/uiuipad/find/bean/InstallAppInfo.java new file mode 100644 index 0000000..1919514 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/bean/InstallAppInfo.java @@ -0,0 +1,78 @@ +package com.uiuipad.find.bean; + +import android.content.pm.PackageInfo; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; +import com.uiuipad.find.util.TimeUtils; + +import java.io.Serializable; + +public class InstallAppInfo implements Serializable { + private static final long serialVersionUID = 5074571830517943706L; + + String app_name; + String install_time; + String app_package; + long app_version_code; + String app_version_name; + long app_size; + + public String getApp_name() { + return app_name; + } + + public void setApp_name(String app_name) { + this.app_name = app_name; + } + + public String getInstall_time() { + return install_time; + } + + public void setInstall_time(String install_time) { + this.install_time = install_time; + } + + public String getApp_package() { + return app_package; + } + + public void setApp_package(String app_package) { + this.app_package = app_package; + } + + public long getApp_version_code() { + return app_version_code; + } + + public void setApp_version_code(long app_version_code) { + this.app_version_code = app_version_code; + } + + public String getApp_version_name() { + return app_version_name; + } + + public void setApp_version_name(String app_version_name) { + this.app_version_name = app_version_name; + } + + public long getApp_size() { + return app_size; + } + + public void setApp_size(long app_size) { + this.app_size = app_size; + } + + @NonNull + @Override + public String toString() { + return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); + } + + +} diff --git a/app/src/main/java/com/uiuipad/find/bean/SnInfo.java b/app/src/main/java/com/uiuipad/find/bean/SnInfo.java new file mode 100644 index 0000000..0797c55 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/bean/SnInfo.java @@ -0,0 +1,35 @@ +package com.uiuipad.find.bean; + +import java.io.Serializable; + +public class SnInfo implements Serializable { + private static final long serialVersionUID = 4733797166059861775L; + + int id ; + String mobile; + long bind_time; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public long getBind_time() { + return bind_time; + } + + public void setBind_time(long bind_time) { + this.bind_time = bind_time; + } +} diff --git a/app/src/main/java/com/uiuipad/find/bean/SnSetting.java b/app/src/main/java/com/uiuipad/find/bean/SnSetting.java new file mode 100644 index 0000000..2d90a67 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/bean/SnSetting.java @@ -0,0 +1,172 @@ +package com.uiuipad.find.bean; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; + +import java.io.Serializable; + +public class SnSetting implements Serializable { + private static final long serialVersionUID = -7000868688099311857L; + + int id; + String loss_str; + int is_loss; + int is_lockscreen; + String lockscreen_pwd; + int is_timecontrol; + String timecontrol_start; + String timecontrol_end; + int is_storeinstall; + int is_usb; + int is_bluetooth_file; + int is_developer; + int is_restore; + int is_topbar; + int is_bottombar; + int is_memory_card; + int is_control; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getLoss_str() { + return loss_str; + } + + public void setLoss_str(String loss_str) { + this.loss_str = loss_str; + } + + public int getIs_loss() { + return is_loss; + } + + public void setIs_loss(int is_loss) { + this.is_loss = is_loss; + } + + public int getIs_lockscreen() { + return is_lockscreen; + } + + public void setIs_lockscreen(int is_lockscreen) { + this.is_lockscreen = is_lockscreen; + } + + public String getLockscreen_pwd() { + return lockscreen_pwd; + } + + public void setLockscreen_pwd(String lockscreen_pwd) { + this.lockscreen_pwd = lockscreen_pwd; + } + + public int getIs_timecontrol() { + return is_timecontrol; + } + + public void setIs_timecontrol(int is_timecontrol) { + this.is_timecontrol = is_timecontrol; + } + + public String getTimecontrol_start() { + return timecontrol_start; + } + + public void setTimecontrol_start(String timecontrol_start) { + this.timecontrol_start = timecontrol_start; + } + + public String getTimecontrol_end() { + return timecontrol_end; + } + + public void setTimecontrol_end(String timecontrol_end) { + this.timecontrol_end = timecontrol_end; + } + + public int getIs_storeinstall() { + return is_storeinstall; + } + + public void setIs_storeinstall(int is_storeinstall) { + this.is_storeinstall = is_storeinstall; + } + + public int getIs_usb() { + return is_usb; + } + + public void setIs_usb(int is_usb) { + this.is_usb = is_usb; + } + + public int getIs_bluetooth_file() { + return is_bluetooth_file; + } + + public void setIs_bluetooth_file(int is_bluetooth_file) { + this.is_bluetooth_file = is_bluetooth_file; + } + + public int getIs_developer() { + return is_developer; + } + + public void setIs_developer(int is_developer) { + this.is_developer = is_developer; + } + + public int getIs_restore() { + return is_restore; + } + + public void setIs_restore(int is_restore) { + this.is_restore = is_restore; + } + + public int getIs_topbar() { + return is_topbar; + } + + public void setIs_topbar(int is_topbar) { + this.is_topbar = is_topbar; + } + + public int getIs_bottombar() { + return is_bottombar; + } + + public void setIs_bottombar(int is_bottombar) { + this.is_bottombar = is_bottombar; + } + + public int getIs_memory_card() { + return is_memory_card; + } + + public void setIs_memory_card(int is_memory_card) { + this.is_memory_card = is_memory_card; + } + + public int getIs_control() { + return is_control; + } + + public void setIs_control(int is_control) { + this.is_control = is_control; + } + + @NonNull + @Override + public String toString() { + return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); + } +} diff --git a/app/src/main/java/com/uiuipad/find/comm/CommonConfig.java b/app/src/main/java/com/uiuipad/find/comm/CommonConfig.java index 0c1ef36..c07e155 100644 --- a/app/src/main/java/com/uiuipad/find/comm/CommonConfig.java +++ b/app/src/main/java/com/uiuipad/find/comm/CommonConfig.java @@ -10,4 +10,46 @@ public class CommonConfig { public static final String MAP_LATITUDE_KEY = "map_latitude_key"; public static final String MAP_ADDRESS_KEY = "map_address_key"; public static final String MAP_ERROR_KEY = "map_error_key"; + + public static final String IS_LOGINED = "isLogined"; + + public static final String LOST_STATUS_KEY = "is_lost_mod"; + public static final String FIND_STRING_KEY = "find_string"; + + /*USB模式-充电*/ + public final static String AOLE_ACTION_USB_USB_CHARGE = "aole_action_usb_usb_charge"; + /*USB模式-MTP*/ + public final static String AOLE_ACTION_USB_USB_MTP = "aole_action_usb_usb_mtp"; + /*USB模式-MIDI*/ + public final static String AOLE_ACTION_USB_USB_MIDI = "aole_action_usb_usb_midi"; + + /*存储卡管控*/ + public final static String AOLE_ACTION_SDCARD_FORBID_ON = "aole_sdcard_forbid_on"; + /*开发者选项管控*/ + public final static String AOLE_ACTION_DEVELOPER_OPTIONS = "aole_Developeroptions"; + /*显示导航栏*/ + public final static String AOLE_ACTION_SHOW_NAVIGATION_BAR = "aole_show_NavigationBar"; + /*隐藏导航栏*/ + public final static String AOLE_ACTION_HIDE_NAVIGATION_BAR = "aole_hide_NavigationBar"; + /*显示状态栏*/ + public final static String AOLE_ACTION_SHOW_STATUS_BAR = "aole_show_statusBar"; + /*隐藏状态栏*/ + public final static String AOLE_ACTION_HIDE_STATUS_BAR = "aole_hide_statusBar"; + /*热点*/ + public final static String AOLE_ACTION_HOTSPOT_FORBID_ON = "aole_hotspot_forbid_on"; + /*蓝牙总开关*/ + public final static String AOLE_ACTION_BHT_FORBID_ON = "aole_bht_forbid_on"; + /*蓝牙传输开关*/ + public final static String AOLE_ACTION_BT_FORBID_ON = "aole_bt_forbid_on"; + /*蓝牙音频开关*/ + public final static String AOLE_ACTION_BHTVIDEO_FORBID_ON = "aole_bhtvideo_forbid_on"; + /*电话白名单开关*/ + public final static String AOLE_ACTION_WHITE_LIST_ON = "aole_white_list_on"; + /*电话白名单列表*/ + public final static String AOLE_ACTION_WHITE_LIST_ARRAY = "aole_white_list_Array"; + /*恢复出厂设置开关*/ + public final static String AOLE_ACTION_RESTORE_FORBID_ON = "aole_restore_forbid_on"; + /*WiFi白名单*/ + public final static String AOLE_ACTION_AOLE_SSID_WHITE_LIST = "aole_ssid_whiteList"; + } diff --git a/app/src/main/java/com/uiuipad/find/network/NetInterfaceManager.java b/app/src/main/java/com/uiuipad/find/network/NetInterfaceManager.java index 93e9f13..1151657 100644 --- a/app/src/main/java/com/uiuipad/find/network/NetInterfaceManager.java +++ b/app/src/main/java/com/uiuipad/find/network/NetInterfaceManager.java @@ -3,27 +3,59 @@ package com.uiuipad.find.network; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; +import android.os.Build; import android.os.Environment; +import android.provider.Settings; +import android.text.format.Formatter; import android.util.Log; import com.tencent.mmkv.MMKV; +import com.uiuipad.find.bean.AppInfo; +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.bean.SnInfo; +import com.uiuipad.find.bean.SnSetting; import com.uiuipad.find.comm.CommonConfig; -import com.uiuipad.find.network.api.BindDevices; +import com.uiuipad.find.network.api.app.GetAppApi; +import com.uiuipad.find.network.api.app.GetSelfAppApi; +import com.uiuipad.find.network.api.app.UpdateAppInstallApi; +import com.uiuipad.find.network.api.manage.RemoveLockScreenApi; +import com.uiuipad.find.network.api.manage.SnSettingApi; +import com.uiuipad.find.network.api.manage.UpdateSnLocationApi; +import com.uiuipad.find.network.api.manage.UploadSnScreenshotApi; +import com.uiuipad.find.network.api.sn.SnConfirmBindApi; +import com.uiuipad.find.network.api.sn.SnInfoApi; +import com.uiuipad.find.network.api.sn.UpdateSnInfoApi; import com.uiuipad.find.network.interceptor.MD5Util; import com.uiuipad.find.network.interceptor.RepeatRequestInterceptor; +import com.uiuipad.find.service.ManagerService; +import com.uiuipad.find.util.ApkUtils; +import com.uiuipad.find.util.ControlUtils; +import com.uiuipad.find.util.TimeUtils; +import com.uiuipad.find.util.Utils; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; +import io.reactivex.rxjava3.schedulers.Schedulers; import okhttp3.Cache; import okhttp3.Interceptor; +import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Protocol; import okhttp3.Request; +import okhttp3.RequestBody; import okhttp3.Response; import retrofit2.Retrofit; import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory; @@ -39,9 +71,6 @@ public class NetInterfaceManager { private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); private Retrofit mRetrofit; private OkHttpClient mOkHttpClient; - private Retrofit mJxwRetrofit; - private OkHttpClient mJxwOkHttpClient; -// private CacheHelper mCacheHelper; private final ConcurrentHashMap requestIdsMap = new ConcurrentHashMap<>(); @@ -58,49 +87,8 @@ public class NetInterfaceManager { this.mContext = context; this.mCrv = mContext.getContentResolver(); // this.mCacheHelper = new CacheHelper(mContext); - if (mRetrofit == null) { if (mOkHttpClient == null) { - Interceptor myHttpInterceptor = new Interceptor() { - @NotNull - @Override - public Response intercept(@NotNull Chain chain) throws IOException { - Request request = chain.request(); - String requestKey = MD5Util.getUpperMD5Str(request.method() + request.url().toString()); - Response response = chain.proceed(request); //准备返回Response - synchronized (requestIdsMap) { - requestIdsMap.remove(requestKey); //在这里移除正常的请求登记 - Log.e("REPEAT-REQUEST", "移除请求2:" + requestKey + " --- " + Thread.currentThread().getName() + " URL = " + request.url()); - } - return response; - } - }; - Interceptor mRequestInterceptor = new Interceptor() { - @NotNull - @Override - public Response intercept(@NotNull Chain chain) throws IOException { - Request request = chain.request(); - //拦截处理重复的HTTP 请求,类似 防止快速点击按钮去重 可以不去处理了,全局统一处理 - String requestKey = MD5Util.getUpperMD5Str(request.method() + request.url().toString()); - synchronized (requestIdsMap) { - if (requestIdsMap.get(requestKey) == null) { -// Log.e("REPEAT-REQUEST", "intercept: " + requestIdsMap); - requestIdsMap.put(requestKey, System.currentTimeMillis()); - Log.e("REPEAT-REQUEST", "注册请求:" + requestKey + " --- " + Thread.currentThread().getName() + " URL = " + request.url()); - } else { - //如果是重复的请求,抛出一个自定义的错误,这个错误大家根据自己的业务定义吧 - Log.e("REPEAT-REQUEST", "重复请求:" + requestKey + " --- " + Thread.currentThread().getName() + " URL = " + request.url()); - return new Response.Builder() - .protocol(Protocol.get(CUSTOM_REPEAT_REQ_PROTOCOL)) - .request(request) //multi thread - .build(); - } - } - Response originalResponse = chain.proceed(request); - return originalResponse.newBuilder().build(); - } - }; - //如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了 OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(timeOut, TimeUnit.SECONDS); // 设置连接超时时间 @@ -109,9 +97,6 @@ public class NetInterfaceManager { builder.retryOnConnectionFailure(true);// 设置进行连接失败重试 builder.addInterceptor(new RepeatRequestInterceptor()); -// builder.addInterceptor(myHttpInterceptor); -// builder.addNetworkInterceptor(mRequestInterceptor); - // 设置缓存文件路径 String cacheDirectory = getCacheDir() + "/OkHttpCache"; Cache cache = new Cache(new File(cacheDirectory), cacheSize); @@ -126,30 +111,6 @@ public class NetInterfaceManager { .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .build(); } - - if (mJxwRetrofit == null) { - if (mJxwOkHttpClient == null) { - //如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了 - OkHttpClient.Builder builder = new OkHttpClient.Builder(); - builder.connectTimeout(timeOut, TimeUnit.SECONDS); // 设置连接超时时间 - builder.writeTimeout(timeOut, TimeUnit.SECONDS);// 设置写入超时时间 - builder.readTimeout(timeOut, TimeUnit.SECONDS);// 设置读取数据超时时间 - builder.retryOnConnectionFailure(true);// 设置进行连接失败重试 - builder.addInterceptor(new RepeatRequestInterceptor()); - // 设置缓存文件路径 - String cacheDirectory = getCacheDir() + "/OkHttpCache"; - Cache cache = new Cache(new File(cacheDirectory), cacheSize); - builder.cache(cache);// 设置缓存 - mJxwOkHttpClient = builder.build(); - } - mJxwRetrofit = new Retrofit.Builder() - .client(mJxwOkHttpClient) - .baseUrl(UrlAddress.JXW_ROOT_URL) - .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) - .build(); - } - } private String getCacheDir() { @@ -189,13 +150,92 @@ public class NetInterfaceManager { return mOkHttpClient; } + public static RequestBody convertToRequestBody(String param) { + RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), param); + return requestBody; + } + + public static RequestBody convertToRequestBody(int param) { + RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(param)); + return requestBody; + } + + public static RequestBody convertToRequestBody(long param) { + RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), String.valueOf(param)); + return requestBody; + } + + /* * * Observable * * */ + public Observable> getSnSettingControl() { + return mRetrofit.create(SnSettingApi.class) + .getSnSetting(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + public Observable getUpdateSnLocationControl(String location, double longitude, double latitude) { + return mRetrofit.create(UpdateSnLocationApi.class) + .updateSnLocation(Utils.getSerial(), location, longitude, latitude) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + public Observable getRemoveLockScreenControl() { + return mRetrofit.create(RemoveLockScreenApi.class) + .removeLockScreen(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable getUpdateSnInfoControl() { + Map params = new HashMap<>(); + params.put("wifi_name", Utils.getWifiSsid(mContext)); + params.put("wifi_signal", Utils.getWifiRssi(mContext)); + params.put("battery", String.valueOf(Utils.getBattery(mContext))); + params.put("bluetooth", Utils.getBluetoothList()); + params.put("memory", Formatter.formatFileSize(mContext, Utils.getUsedMemory(mContext))); + params.put("storage", Utils.getDataTotalSize(mContext)); + params.put("memory_use", Formatter.formatFileSize(mContext, Utils.getUsedMemory(mContext))); + params.put("storage_use", Utils.getUsedSize(mContext)); + params.put("sn", Utils.getSerial()); + return mRetrofit.create(UpdateSnInfoApi.class) + .updateSnInfo(params) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable>> getAppControl() { + return mRetrofit.create(GetAppApi.class) + .getApp(Utils.getSerial(), Build.MODEL) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable>> getSelfAppControl() { + return mRetrofit.create(GetSelfAppApi.class) + .getSelfApp(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable getUpdateAppInstallControl(String jsonString) { + return mRetrofit.create(UpdateAppInstallApi.class) + .updateAppInstall(Utils.getSerial(), jsonString) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } + + public Observable> getSnInfoControl() { + return mRetrofit.create(SnInfoApi.class) + .getSnInfo(Utils.getSerial()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } /* * @@ -203,15 +243,134 @@ public class NetInterfaceManager { * * */ - public BindDevices getbindDevicesControl() { - return mRetrofit.create(BindDevices.class); + public SnConfirmBindApi getSnConfirmBindApi() { + return mRetrofit.create(SnConfirmBindApi.class); } + public UploadSnScreenshotApi getUploadSnScreenshotApi() { + return mRetrofit.create(UploadSnScreenshotApi.class); + } + + + /* * * execution * * */ + public void getSnSetting() { + getSnSettingControl().subscribe(new Observer>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getSnSetting", "onSubscribe: "); + } -} + @Override + public void onNext(@NonNull BaseResponse snSettingBaseResponse) { + Log.e("getSnSetting", "onNext: " + snSettingBaseResponse); + if (snSettingBaseResponse.code == 200) { + SnSetting snSetting = snSettingBaseResponse.data; + int is_control = snSetting.getIs_control(); + Settings.Global.putInt(mCrv,"is_control", is_control); + int is_loss = snSetting.getIs_loss(); + String loss_str = snSetting.getLoss_str(); + mMMKV.encode(CommonConfig.LOST_STATUS_KEY, is_loss); + mMMKV.encode(CommonConfig.FIND_STRING_KEY, loss_str); + int is_lockscreen = snSetting.getIs_lockscreen(); + mMMKV.encode(ManagerService.LOCK_STATE, is_lockscreen); + String lockscreen_pwd = snSetting.getLockscreen_pwd(); + Settings.Global.putString(mCrv, ManagerService.LOCK_SCREEN_PASSWORD, lockscreen_pwd); + int is_timecontrol = snSetting.getIs_timecontrol(); + String timecontrol_start = snSetting.getTimecontrol_start(); + String timecontrol_end = snSetting.getTimecontrol_end(); + if (is_timecontrol == 0) { + TimeUtils.setEmpty(mContext); + TimeUtils.ContralTime c = TimeUtils.getDefaltContralTime(mContext); + if (null != c) { + Log.e("getTimeControl", c.toString()); + } + } else { + TimeUtils.ContralTime c = TimeUtils.String2ContralTime(mContext, timecontrol_start + "-" + timecontrol_end); + if (null != c) { + Log.e("getTimeControl", "OK:" + c.toString()); + } + } + + ControlUtils.setSystemControl(mContext, snSetting); + + } else { + TimeUtils.setEmpty(mContext); + TimeUtils.ContralTime c = TimeUtils.getDefaltContralTime(mContext); + if (null != c) { + Log.e("getTimeControl", c.toString()); + } + ControlUtils.disableSystemControl(mContext); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getSnSetting", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getSnSetting", "onComplete: "); + } + }); + } + + + public void updateSnInfo() { + getUpdateSnInfoControl().subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("updateSnInfo", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("updateSnInfo", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("updateSnInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("updateSnInfo", "onComplete: "); + } + }); + } + + public void updateAppInstall() { + String jsonString = ApkUtils.getInstallAppInfo(mContext); + NetInterfaceManager.getInstance().getUpdateAppInstallControl(jsonString) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("updateAppInstall", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("updateAppInstall", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("updateAppInstall", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("updateAppInstall", "onComplete: "); + } + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/uiuipad/find/network/RetryCallback.java b/app/src/main/java/com/uiuipad/find/network/RetryCallback.java new file mode 100644 index 0000000..1f84859 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/RetryCallback.java @@ -0,0 +1,92 @@ +package com.uiuipad.find.network; + +import android.util.Log; + +import java.util.Timer; +import java.util.TimerTask; + +import io.reactivex.rxjava3.annotations.NonNull; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public abstract class RetryCallback implements Callback { + + private static final String TAG = RetryCallback.class.getSimpleName(); + + private int mRetryCount; + private long mRetryInterval; + + private int mCurrentRetryCount; + + private boolean isExecuting; + + private Call mCall; + + private Timer timer = new Timer(); + + public RetryCallback(Call call, int retryCount, long retryInterval) { + isExecuting = true; + mCall = call; + mRetryCount = retryCount; + mRetryInterval = retryInterval; + } + + @Override + public final void onResponse(@NonNull Call call, @NonNull Response response) { + Log.e(TAG, "onResponse"); + isExecuting = false; + if (!response.isSuccessful() && mCurrentRetryCount < mRetryCount) { + mCurrentRetryCount++; + retryRequest(call); + } else { + onRequestResponse(call, response); + } + } + + @Override + public final void onFailure(@NonNull Call call, @NonNull Throwable t) { + Log.e(TAG, "onFailure"); + isExecuting = false; + if (mCurrentRetryCount < mRetryCount) { + mCurrentRetryCount++; + Log.e(TAG, "onFailure: " + "RetryCount: " + mCurrentRetryCount); + Log.e(TAG, "onFailure: " + "RetryResponse: " + call.request()); + retryRequest(call); + } else { + onRequestFail(call, t); + } + } + + private void retryRequest(final Call call) { + Log.e(TAG, "retryRequest"); + onStartRetry(); + TimerTask timerTask = new TimerTask() { + @Override + public void run() { + synchronized (RetryCallback.this) { + mCall = call.clone(); + mCall.enqueue(RetryCallback.this); + isExecuting = true; + } + } + }; + timer.schedule(timerTask, mRetryInterval); + } + + public void cancelCall() { + synchronized (this) { + if (!isExecuting) { + timer.cancel(); + } else { + mCall.cancel(); + } + } + } + + public abstract void onRequestResponse(Call call, Response response); + + public abstract void onRequestFail(Call call, Throwable t); + + public abstract void onStartRetry(); +} \ No newline at end of file diff --git a/app/src/main/java/com/uiuipad/find/network/UrlAddress.java b/app/src/main/java/com/uiuipad/find/network/UrlAddress.java index 9b9a020..babd04a 100644 --- a/app/src/main/java/com/uiuipad/find/network/UrlAddress.java +++ b/app/src/main/java/com/uiuipad/find/network/UrlAddress.java @@ -1,82 +1,92 @@ package com.uiuipad.find.network; public class UrlAddress { - /*主页接口*/ - public static final String ROOT_URL = "https://led.aolelearn.com/android/"; + /* + * 主页接口 + * */ + public static final String ROOT_URL = "https://kxapi.uiuios.com/android/"; - /*绑定设备消息*/ - public final static String BIND_DEVICES = "sn/bindSn"; - /*发送绑定验证码*/ - public static final String SEND_BIND_VER_CODE = "Sn/sendBindVerCode"; + + /* + * 设备 + * */ + /*确认绑定设备*/ + public static final String SN_CONFIRM_BIND = "equipment/sn/snConfirmBind"; /*手动绑定设备*/ - public static final String EQUIPMENT_BIND = "Sn/equipmentBind"; - - /*设备激活*/ - public static final String SN_ACTIVATION = "sn/snActivation"; - /*获取设备是否激活*/ - public static final String GET_SN_IS_ACTIVATION = "sn/getSnIsActivation"; - /*获取设备激活二维码链接*/ - public static final String ACTIVATION_QRCODE = "pay/getActivationQrcode"; + public static final String EQUIPMENT_BIND = "equipment/sn/equipmentBind"; + /*发送绑定设备验证码*/ + public static final String SEND_BIND_VER_CODE = "equipment/sn/sendBindVerCode"; + /*上传设备信息*/ + public static final String UPDATE_SN_INFO = "equipment/sn/updateSnInfo"; + /*获取绑定信息*/ + public static final String GET_SN_INFO = "equipment/sn/getSnInfo"; - /*获取文件*/ - public static final String GET_FILES = "file/getFiles"; - /*获取操作指南*/ - public static final String GET_OPERATION_GUIDE = "file/getFiles"; - - - /*上传屏幕截图*/ - public final static String UPLOAD_SCREEN_SNAPSHOT = "sn/uploadScreenshot"; - /*浏览器网址管控*/ - public final static String SET_BROWSER_URL = "control/getBrowser"; - /*浏览器书签管控*/ - public final static String SET_BROWSER_LABEL = "control/getLabel"; - /*上传控制面版截图*/ - public static final String UPLOAD_CONTROL_SCREENSHOT = "sn/uploadControlScreenshot"; - - /*设备信息接口*/ - public static final String SNINFO = "sn/getSnInfo"; - /*获取用户头像和信息*/ - public static final String GET_USER_AVATAR_INFO = "sn/getUserAvatarInfo"; - /*获取设备类型*/ - public static final String GET_SN_TYPE = "sn/getSnType"; - /*获取正在运行的app*/ - public static final String RUN_NEW_APP = "app/runNewApp"; - /*获取所有应用*/ - public final static String GET_ALL_PACKAGE = "app/queryAllApp"; - //获取管理员所有应用 - public final static String GET_ADMIN_APP = "getAdminApp"; - - /*获取系统设置*/ - public final static String GET_SETTINGS = "control/getSetting"; - /*获取强制下载*/ - public final static String GET_FORCE_INSTALL = "app/getForceDownload"; - /*发送卸载或者安装信息*/ - public final static String SEND_INSTALLEDORREMOVED = "app/addAppInstall"; - /*发送设备基本信息*/ - public final static String UPDATE_SNINFO = "sn/updateAdminSn"; - /*根据包名获取更新*/ - public final static String GET_NEWESTAPPUPDATE = "app/newestAppUpdate"; - /*获取禁用包名*/ - public static final String GET_APP_ICON = "getAppIcon"; - /*获取灰度更新*/ - public static final String GET_TEST_APP_INFO = "app/getTestAppInfo"; - /*获取wifi*/ - public static final String GET_WIFI_ALIAS_PW = "getWifi"; - - /*获取屏幕管控*/ - public final static String GET_SCREEN_LOCK = "sn/getScreenshot"; - /*获取锁屏密码*/ - public static final String LOCK_SCREEN_PWD = "sn/getLockScreenPwd"; + /* + * 管控 + * */ + /*获取设备设置*/ + public static final String GET_SN_SETTING = "equipment/manage/getSnSetting"; + /*上传定位信息*/ + public static final String UPDATE_SN_LOCATION = "equipment/manage/updateSnLocation"; + /*上传截屏*/ + public static final String UPLOAD_SN_SCREENSHOT = "equipment/manage/uploadSnScreenshot"; /*解除锁屏*/ - public static final String UPDATE_LOCK_SCREEN = "sn/updateLockScreen"; + public static final String REMOVE_LOCK_SCREEN = "equipment/manage/removeLockScreen"; + /*获取专注模式设置*/ + public static final String GET_CLOUD_LESSON_SETTING = "equipment/manage/getCloudLessonSetting"; + /*获取专注模式应用*/ + public static final String GET_CLOUD_LESSON_APP = "equipment/manage/getCloudLessonApp"; + /*获取图标隐藏*/ + public static final String GET_APP_ICON = "app/app/getAppIcon"; + /*获取应用是否显示*/ + public static final String GET_APP_IS_SHOW = "app/app/getAppIsShow"; + /*更新显示隐藏应用*/ + public static final String APP_ICON_UPDATE = "app/app/appIconUpdate"; + /*获取浏览器书签*/ + public static final String GET_LABEL = "equipment/browser/getLabel"; + /*获取浏览器白名单*/ + public static final String GET_WHITE_LIST = "equipment/browser/getWhiteList"; + /* + * 时间管控 + * */ + /*获取整机时间管控*/ + public static final String GET_TIME_MANAGE_SN = "equipment/timeManage/getTimeManageSn"; + /*获取应用时间管控*/ + public static final String GET_TIME_MANAGE_APP = "equipment/timeManage/getTimeManageApp"; + + + /* + * 应用 + * */ + /*获取应用*/ + public static final String GET_APP = "app/app/getApp"; + /*获取全局更新应用*/ + public static final String GET_SELF_APP = "app/selfApp/getSelfApp"; + /*上传应用安装记录*/ + public static final String UPDATE_APP_INSTALL = "app/app/updateAppInstall"; + /*上传应用使用记录*/ + public static final String UPLOAD_APP_USE_LOG = "app/app/uploadAppUseLog"; + + /* + * 闹钟 + * */ + /*获取闹钟*/ + public static final String GET_ALARM_CLOCK = "equipment/alarmClock/getAlarmClock"; + /*闹钟完成调用*/ + public static final String UPDATE_ALARM_CLOCK = "equipment/alarmClock/updateAlarmClock"; + /*添加闹钟*/ + public static final String ALARM_CLOCK_ADD = "equipment/alarmClock/alarmClockAdd"; + /*编辑闹钟*/ + public static final String ALARM_CLOCK_EDIT = "equipment/alarmClock/alarmClockEdit"; + /*编号查询闹钟*/ + public static final String ALARM_CLOCK_BY_ID = "equipment/alarmClock/alarmClockById"; + /*删除闹钟*/ + public static final String ALARM_CLOCK_DELETE = "equipment/alarmClock/alarmClockDelete"; + + /*通过ip获取信息*/ public static final String PCONLINE_WHOIS = "http://whois.pconline.com.cn/"; public static final String WHOIS = "ipJson.jsp"; - - /*九学王测试服务器*/ - public static final String JXW_ROOT_URL = "http://api.jxwxxkj.com/"; - /*激活接口*/ - public static final String ADD_BY_AUTHORIZED = "api/thddevice/series/addByAuthorized"; } diff --git a/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockAddApi.java b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockAddApi.java new file mode 100644 index 0000000..213954c --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockAddApi.java @@ -0,0 +1,23 @@ +package com.uiuipad.find.network.api.alarmClock; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import java.util.Map; + +import io.reactivex.rxjava3.core.Observable; +import okhttp3.MultipartBody; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.QueryMap; + +public interface AlarmClockAddApi { + @FormUrlEncoded + @POST(UrlAddress.ALARM_CLOCK_ADD) + Observable alarmClockAdd( + @QueryMap Map params, + @Part MultipartBody.Part body + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockApi.java b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockApi.java new file mode 100644 index 0000000..002b56e --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockApi.java @@ -0,0 +1,15 @@ +package com.uiuipad.find.network.api.alarmClock; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface AlarmClockApi { + @GET(UrlAddress.GET_ALARM_CLOCK) + Observable getAlarmClock( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/BindDevices.java b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockByIdApi.java similarity index 51% rename from app/src/main/java/com/uiuipad/find/network/api/BindDevices.java rename to app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockByIdApi.java index 8bcc433..1732d07 100644 --- a/app/src/main/java/com/uiuipad/find/network/api/BindDevices.java +++ b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockByIdApi.java @@ -1,4 +1,4 @@ -package com.uiuipad.find.network.api; +package com.uiuipad.find.network.api.alarmClock; import com.uiuipad.find.bean.BaseResponse; import com.uiuipad.find.network.UrlAddress; @@ -7,11 +7,10 @@ import io.reactivex.rxjava3.core.Observable; import retrofit2.http.GET; import retrofit2.http.Query; -public interface BindDevices { - @GET(UrlAddress.BIND_DEVICES) - Observable getBindDevices( +public interface AlarmClockByIdApi { + @GET(UrlAddress.ALARM_CLOCK_BY_ID) + Observable alarmClockById( @Query("sn") String sn, - @Query("id") String id, - @Query("type") int type + @Query("id") String id ); } diff --git a/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockDeleteApi.java b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockDeleteApi.java new file mode 100644 index 0000000..0a9167c --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockDeleteApi.java @@ -0,0 +1,18 @@ +package com.uiuipad.find.network.api.alarmClock; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface AlarmClockDeleteApi { + @FormUrlEncoded + @POST(UrlAddress.ALARM_CLOCK_DELETE) + Observable alarmClockDelete( + @Field("sn") String sn, + @Field("id") String id + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockEditApi.java b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockEditApi.java new file mode 100644 index 0000000..faaf87f --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/AlarmClockEditApi.java @@ -0,0 +1,22 @@ +package com.uiuipad.find.network.api.alarmClock; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import java.util.Map; + +import io.reactivex.rxjava3.core.Observable; +import okhttp3.MultipartBody; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.QueryMap; + +public interface AlarmClockEditApi { + @FormUrlEncoded + @POST(UrlAddress.ALARM_CLOCK_EDIT) + Observable alarmClockEdit( + @QueryMap Map params, + @Part MultipartBody.Part body + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/alarmClock/UpdateAlarmClockApi.java b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/UpdateAlarmClockApi.java new file mode 100644 index 0000000..e9ad7e4 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/alarmClock/UpdateAlarmClockApi.java @@ -0,0 +1,18 @@ +package com.uiuipad.find.network.api.alarmClock; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface UpdateAlarmClockApi { + @FormUrlEncoded + @POST(UrlAddress.UPDATE_ALARM_CLOCK) + Observable updateAlarmClock( + @Field("sn") String sn, + @Field("id") String id + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/app/GetAppApi.java b/app/src/main/java/com/uiuipad/find/network/api/app/GetAppApi.java new file mode 100644 index 0000000..f432433 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/app/GetAppApi.java @@ -0,0 +1,19 @@ +package com.uiuipad.find.network.api.app; + +import com.uiuipad.find.bean.AppInfo; +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import java.util.List; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface GetAppApi { + @GET(UrlAddress.GET_APP) + Observable>> getApp( + @Query("sn") String sn, + @Query("platform") String platform + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/app/GetSelfAppApi.java b/app/src/main/java/com/uiuipad/find/network/api/app/GetSelfAppApi.java new file mode 100644 index 0000000..17fe5e1 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/app/GetSelfAppApi.java @@ -0,0 +1,18 @@ +package com.uiuipad.find.network.api.app; + +import com.uiuipad.find.bean.AppInfo; +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import java.util.List; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface GetSelfAppApi { + @GET(UrlAddress.GET_SELF_APP) + Observable>> getSelfApp( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/app/UpdateAppInstallApi.java b/app/src/main/java/com/uiuipad/find/network/api/app/UpdateAppInstallApi.java new file mode 100644 index 0000000..66a3da5 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/app/UpdateAppInstallApi.java @@ -0,0 +1,18 @@ +package com.uiuipad.find.network.api.app; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface UpdateAppInstallApi { + @FormUrlEncoded + @POST(UrlAddress.UPDATE_APP_INSTALL) + Observable updateAppInstall( + @Field("sn") String sn, + @Field("app") String app + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/AppIconApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/AppIconApi.java new file mode 100644 index 0000000..42d2556 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/AppIconApi.java @@ -0,0 +1,15 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface AppIconApi { + @GET(UrlAddress.GET_APP_ICON) + Observable getAppIcon( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/AppIconUpdateApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/AppIconUpdateApi.java new file mode 100644 index 0000000..c2b7dfc --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/AppIconUpdateApi.java @@ -0,0 +1,20 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface AppIconUpdateApi { + @FormUrlEncoded + @POST(UrlAddress.APP_ICON_UPDATE) + Observable appIconUpdate( + @Field("sn") String sn, + @Field("app_package") String app_package, + @Field("is_show") String is_show, + @Field("app_name") String app_name + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/AppIsShowApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/AppIsShowApi.java new file mode 100644 index 0000000..bc460cd --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/AppIsShowApi.java @@ -0,0 +1,16 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface AppIsShowApi { + @GET(UrlAddress.GET_APP_IS_SHOW) + Observable getAppIsShow( + @Query("sn") String sn, + @Query("app_package") String app_package + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/LabelApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/LabelApi.java new file mode 100644 index 0000000..1e545fa --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/LabelApi.java @@ -0,0 +1,15 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface LabelApi { + @GET(UrlAddress.GET_LABEL) + Observable getLabel( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/RemoveLockScreenApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/RemoveLockScreenApi.java new file mode 100644 index 0000000..3a0580f --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/RemoveLockScreenApi.java @@ -0,0 +1,17 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface RemoveLockScreenApi { + @FormUrlEncoded + @POST(UrlAddress.REMOVE_LOCK_SCREEN) + Observable removeLockScreen( + @Field("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/SnSettingApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/SnSettingApi.java new file mode 100644 index 0000000..5fc4761 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/SnSettingApi.java @@ -0,0 +1,16 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.bean.SnSetting; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface SnSettingApi { + @GET(UrlAddress.GET_SN_SETTING) + Observable> getSnSetting( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/UpdateSnLocationApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/UpdateSnLocationApi.java new file mode 100644 index 0000000..a934ee0 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/UpdateSnLocationApi.java @@ -0,0 +1,20 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface UpdateSnLocationApi { + @FormUrlEncoded + @POST(UrlAddress.UPDATE_SN_LOCATION) + Observable updateSnLocation( + @Field("sn") String sn, + @Field("location") String location, + @Field("location_longitude") double locationLongitude, + @Field("location_latitude") double locationLatitude + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/UploadSnScreenshotApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/UploadSnScreenshotApi.java new file mode 100644 index 0000000..00a8302 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/UploadSnScreenshotApi.java @@ -0,0 +1,22 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import java.util.Map; + +import okhttp3.MultipartBody; +import retrofit2.Call; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.Part; +import retrofit2.http.PartMap; + +public interface UploadSnScreenshotApi { + @Multipart + @POST(UrlAddress.UPLOAD_SN_SCREENSHOT) + Call uploadSnScreenshot( + @PartMap Map params, + @Part MultipartBody.Part body + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/manage/WhiteListApi.java b/app/src/main/java/com/uiuipad/find/network/api/manage/WhiteListApi.java new file mode 100644 index 0000000..7a7ad7a --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/manage/WhiteListApi.java @@ -0,0 +1,15 @@ +package com.uiuipad.find.network.api.manage; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface WhiteListApi { + @GET(UrlAddress.GET_WHITE_LIST) + Observable getWhiteList( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/sn/EquipmentBindApi.java b/app/src/main/java/com/uiuipad/find/network/api/sn/EquipmentBindApi.java new file mode 100644 index 0000000..7695e2f --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/sn/EquipmentBindApi.java @@ -0,0 +1,19 @@ +package com.uiuipad.find.network.api.sn; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface EquipmentBindApi { + @FormUrlEncoded + @POST(UrlAddress.EQUIPMENT_BIND) + Observable equipmentBind( + @Field("sn") String sn, + @Field("mobile") String mobile, + @Field("ver_code") String ver_code + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/sn/SendBindVerCodeApi.java b/app/src/main/java/com/uiuipad/find/network/api/sn/SendBindVerCodeApi.java new file mode 100644 index 0000000..52734cf --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/sn/SendBindVerCodeApi.java @@ -0,0 +1,17 @@ +package com.uiuipad.find.network.api.sn; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface SendBindVerCodeApi { + @FormUrlEncoded + @POST(UrlAddress.SEND_BIND_VER_CODE) + Observable sendBindVerCode( + @Field("mobile") String mobile + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/sn/SnConfirmBindApi.java b/app/src/main/java/com/uiuipad/find/network/api/sn/SnConfirmBindApi.java new file mode 100644 index 0000000..6567420 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/sn/SnConfirmBindApi.java @@ -0,0 +1,19 @@ +package com.uiuipad.find.network.api.sn; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface SnConfirmBindApi { + @FormUrlEncoded + @POST(UrlAddress.SN_CONFIRM_BIND) + Observable snConfirmBind( + @Field("sn") String sn, + @Field("userId") String userId, + @Field("type") int type + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/sn/SnInfoApi.java b/app/src/main/java/com/uiuipad/find/network/api/sn/SnInfoApi.java new file mode 100644 index 0000000..ef80e4d --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/sn/SnInfoApi.java @@ -0,0 +1,17 @@ +package com.uiuipad.find.network.api.sn; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.bean.SnInfo; +import com.uiuipad.find.bean.SnSetting; +import com.uiuipad.find.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface SnInfoApi { + @GET(UrlAddress.GET_SN_INFO) + Observable> getSnInfo( + @Query("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/network/api/sn/UpdateSnInfoApi.java b/app/src/main/java/com/uiuipad/find/network/api/sn/UpdateSnInfoApi.java new file mode 100644 index 0000000..8589f20 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/network/api/sn/UpdateSnInfoApi.java @@ -0,0 +1,31 @@ +package com.uiuipad.find.network.api.sn; + +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.network.UrlAddress; + +import java.util.Map; + +import io.reactivex.rxjava3.core.Observable; +import okhttp3.RequestBody; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.PartMap; + +public interface UpdateSnInfoApi { + @Multipart + @POST(UrlAddress.UPDATE_SN_INFO) + Observable updateSnInfo( + @PartMap Map params +// @Field("wifi_name") String wifi_name, +// @Field("wifi_signal") String wifi_signal, +// @Field("battery") String battery, +// @Field("bluetooth") String bluetooth, +// @Field("memory") String memory, +// @Field("storage") String storage, +// @Field("memory_use") String memory_use, +// @Field("storage_use") String storage_use, +// @Field("sn") String sn + ); +} diff --git a/app/src/main/java/com/uiuipad/find/push/PushManager.java b/app/src/main/java/com/uiuipad/find/push/PushManager.java index bc9998e..01582bd 100644 --- a/app/src/main/java/com/uiuipad/find/push/PushManager.java +++ b/app/src/main/java/com/uiuipad/find/push/PushManager.java @@ -4,46 +4,122 @@ import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.os.Handler; +import android.os.PowerManager; import android.util.Log; import android.view.Gravity; import android.view.WindowManager; +import com.baidu.location.BDAbstractLocationListener; +import com.baidu.location.BDLocation; +import com.baidu.location.LocationClient; +import com.google.gson.Gson; import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; import com.tencent.mmkv.MMKV; -import com.uiuipad.find.activity.main.MainActivity; +import com.uiuipad.find.activity.AudioActivity; +import com.uiuipad.find.bean.AppInfo; import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.bean.SnSetting; import com.uiuipad.find.comm.CommonConfig; import com.uiuipad.find.dialog.CustomDialog; import com.uiuipad.find.gson.GsonUtils; +import com.uiuipad.find.manager.MapManager; import com.uiuipad.find.network.NetInterfaceManager; -import com.uiuipad.find.service.main.MainService; +import com.uiuipad.find.network.RetryCallback; +import com.uiuipad.find.service.ManagerService; +import com.uiuipad.find.util.ApkUtils; +import com.uiuipad.find.util.CmdUtil; +import com.uiuipad.find.util.ControlUtils; import com.uiuipad.find.util.ToastUtil; import com.uiuipad.find.util.Utils; +import java.io.File; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.TimeUnit; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableEmitter; +import io.reactivex.rxjava3.core.ObservableOnSubscribe; import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.functions.Consumer; import io.reactivex.rxjava3.schedulers.Schedulers; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.Response; public class PushManager { private static final String TAG = PushManager.class.getSimpleName(); - public static final String ACTION_REFRESH_BINDING_STATUS = "RefreshBindingStatus"; - - @SuppressLint("StaticFieldLeak") private static PushManager sInstance; private Context mContext; private ContentResolver mResolver; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); - // 1.绑定设备 - private static final String BIND_DEVIVES = "1"; + /*绑定设备*/ + private static final String BIND_DEVICES = "1"; + /*设备定位*/ + private static final String DEVICE_LOCATION = "2"; + /*设备截屏*/ + private static final String DEVICE_SCREENSHOT = "3"; + /*设备发出声音*/ + private static final String DEVICE_SPEAKER = "4"; + /*丢失模式*/ + private static final String LOST_MODE = "5"; + /*刷新*/ + private static final String REFRESH_NETWORK = "6"; + /*设备锁屏*/ + private static final String LOCK_SCREEN = "7"; + /*设备锁屏密码*/ + private static final String SCREEN_PASSWORD = "8"; + /*设备重启*/ + private static final String DEVICE_REBOOT = "9"; + /*设备加速*/ + private static final String DEVICE_CLEAR = "10"; + /*全局应用更新*/ + private static final String GLOBAL_UPDATES = "11"; + /*时间约定*/ + private static final String TIME_CONTROL = "12"; + /*应用市场安装开关*/ + private static final String APPSTORE_INSTALL = "13"; + /*usb开关*/ + private static final String USB_CONTROL = "14"; + /*专注模式*/ + private static final String FOCUS_MODE = "15"; + /*应用图标隐藏*/ + private static final String APP_CONTROL = "16"; + /*闹钟*/ + private static final String ALARM_CLOCK = "17"; + /*浏览器管控*/ + private static final String BROWSER_CONTROL = "18"; + /*蓝牙文件传输*/ + private static final String BLUETOOTH_CONTROL = "19"; + /*开发者模式*/ + private static final String DEVELOPER_MODE = "20"; + /*恢复出厂开关*/ + private static final String DEVICE_RESET = "21"; + /*顶部通知栏开关*/ + private static final String ACTIONBAR_CONTROL = "22"; + /*底部导航条*/ + private static final String NAVIGATIONBAR_CONTROL = "23"; + /*存储卡开关*/ + private static final String TF_CONTROL = "24"; + /*重装应用*/ + private static final String APP_REINSTALL = "25"; + /*卸载应用*/ + private static final String APP_UNINSTALL = "26"; + /*清除应用缓存*/ + private static final String CLEAR_APP_CACHE = "27"; + /*应用管控开关*/ + private static final String SYSTEM_CONTROL = "29"; private PushManager(Context context) { if (context == null) { @@ -69,14 +145,124 @@ public class PushManager { public void setPushContent(String title, String extras) { switch (title) { - case BIND_DEVIVES: + case BIND_DEVICES: ToastUtil.debugShow("收到推送消息: 绑定设备"); bindService(extras); break; + case DEVICE_LOCATION: + ToastUtil.debugShow("收到管控:设备定位"); + NetInterfaceManager.getInstance().updateSnInfo(); + startLocation(); + break; + case DEVICE_SCREENSHOT: + ToastUtil.debugShow("收到管控:设备截图"); + screenshot(extras); + break; + case DEVICE_SPEAKER: + ToastUtil.debugShow("收到管控:查找设备"); + playSound(extras); + break; + case LOST_MODE: + ToastUtil.debugShow("收到管控:丢失模式"); + setLostMode(extras); + break; + case REFRESH_NETWORK: + + break; + case LOCK_SCREEN: + ToastUtil.debugShow("收到推送消息: 锁屏"); + setLock_screen(extras); + break; + case SCREEN_PASSWORD: + break; + case DEVICE_REBOOT: + ToastUtil.debugShow("收到管控:设备重启"); + ControlUtils.rebootDevices(mContext); + break; + case DEVICE_CLEAR: + ToastUtil.debugShow("收到管控:一键加速"); + ControlUtils.killBackgroundApp(mContext); + break; + case GLOBAL_UPDATES: + ToastUtil.debugShow("收到管控:全局更新"); + globalUpdate(mContext, extras); + break; + case TIME_CONTROL: + break; + case APPSTORE_INSTALL: + case USB_CONTROL: + case BLUETOOTH_CONTROL: + case DEVELOPER_MODE: + case DEVICE_RESET: + case ACTIONBAR_CONTROL: + case NAVIGATIONBAR_CONTROL: + case TF_CONTROL: + case SYSTEM_CONTROL: + NetInterfaceManager.getInstance().getSnSetting(); + break; + case FOCUS_MODE: + break; + case APP_CONTROL: + break; + case ALARM_CLOCK: + break; + case BROWSER_CONTROL: + break; + case APP_REINSTALL: + break; + case APP_UNINSTALL: + break; + case CLEAR_APP_CACHE: + break; default: } } + private void globalUpdate(Context context, String extras) { + Gson gson = new Gson(); + Type type = new TypeToken() { + }.getType(); + AppInfo appInfo = gson.fromJson(extras, type); + ApkUtils.checkAppInstall(context, appInfo); + } + + private void startLocation() { + LocationClient locationClient = MapManager.getInstance().getLocationClient(); + locationClient.stop(); + locationClient.start(); + locationClient.registerLocationListener(new BDAbstractLocationListener() { + @Override + public void onReceiveLocation(BDLocation bdLocation) { + Log.e(TAG, "onReceiveLocation: "); + if (bdLocation != null) { + NetInterfaceManager.getInstance().getUpdateSnLocationControl(mMMKV.decodeString(CommonConfig.MAP_ADDRESS_KEY, "-"), bdLocation.getLongitude(), bdLocation.getLatitude()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("startLocation", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("startLocation", "onSubscribe: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("startLocation", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("startLocation", "onComplete: "); + } + }); + } + locationClient.stop(); + } + }); + } + private Disposable subscribe; private long cutdownTime = 30; @@ -85,9 +271,9 @@ public class PushManager { void bindService(final String jsonString) { ToastUtil.debugShow("收到绑定设备请求"); JsonObject object = GsonUtils.getJsonObject(jsonString); - String userName = object.get("member_name").getAsString(); - final String id = object.get("id").getAsString(); - String phoneNum = object.get("member_phone").getAsString(); + String userName = object.get("username").getAsString(); + final String id = object.get("userId").getAsString(); + String phoneNum = object.get("mobile").getAsString(); dialog = new CustomDialog(mContext); subscribe = Observable.interval(1, TimeUnit.SECONDS) .subscribeOn(Schedulers.io()) @@ -98,7 +284,7 @@ public class PushManager { if (aLong < cutdownTime && (subscribe != null && !subscribe.isDisposed())) { dialog.setNegtiveText("拒绝" + "(" + (cutdownTime - aLong) + ")"); } else { - bind(id, 0); + snConfirmBind(id, 2); dialog.dismiss(); if (subscribe != null) subscribe.dispose(); @@ -113,7 +299,7 @@ public class PushManager { .setOnClickBottomListener(new CustomDialog.OnClickBottomListener() { @Override public void onPositiveClick() { - bind(id, 1); + snConfirmBind(id, 1); dialog.dismiss(); if (subscribe != null) subscribe.dispose(); @@ -122,7 +308,7 @@ public class PushManager { @Override public void onNegtiveClick() { - bind(id, 0); + snConfirmBind(id, 2); ToastUtil.show("设备取消绑定"); dialog.dismiss(); if (subscribe != null) @@ -137,26 +323,25 @@ public class PushManager { dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); } - private void bind(final String id, int type) { + private void snConfirmBind(final String id, int type) { NetInterfaceManager.getInstance() - .getbindDevicesControl() - .getBindDevices(Utils.getSerial(), id, type) + .getSnConfirmBindApi() + .snConfirmBind(Utils.getSerial(), id, type) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { @Override public void onSubscribe(@NonNull Disposable d) { - Log.e("bind", "onSubscribe: "); + Log.e("snConfirmBind", "onSubscribe: "); } @Override public void onNext(@NonNull BaseResponse baseResponse) { int code = baseResponse.code; - Log.e("bind", "onNext: " + baseResponse); + Log.e("snConfirmBind", "onNext: " + baseResponse); String msg = baseResponse.msg; if (code == 200) { ToastUtil.show("绑定成功"); - sendZyosRefreshIntent(); } else if (code == 301) { ToastUtil.show(msg); } @@ -164,25 +349,147 @@ public class PushManager { @Override public void onError(@NonNull Throwable e) { - Log.e("bind", "onError: " + e.getMessage()); + Log.e("snConfirmBind", "onError: " + e.getMessage()); onComplete(); } @Override public void onComplete() { - Log.e("bind", "onComplete: "); - Intent serviceIntent = new Intent(MainService.RefreshInfoReceiver.REFRESH_RECEIVER_ACTION); - mContext.sendBroadcast(serviceIntent); - Intent activityIntent = new Intent(MainActivity.REFRESHACTION); - mContext.sendBroadcast(activityIntent); + Log.e("snConfirmBind", "onComplete: "); } }); } - private void sendZyosRefreshIntent() { - Intent intent = new Intent(ACTION_REFRESH_BINDING_STATUS); - intent.setPackage("com.uiui.zyos"); + private void playSound(String extras) { + Intent intent = new Intent(mContext, AudioActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mContext.startActivity(intent); + } + + private void setLostMode(String extras) { + NetInterfaceManager.getInstance().getSnSetting(); + SnSetting snSetting = GsonUtils.toJavaObject(extras, SnSetting.class); + if (snSetting == null) { + return; + } + int is_lose = snSetting.getIs_loss(); + String lose_str = snSetting.getLoss_str(); + mMMKV.encode(CommonConfig.LOST_STATUS_KEY, is_lose); + mMMKV.encode(CommonConfig.FIND_STRING_KEY, lose_str); + Intent intent = new Intent(); + intent.setAction(ManagerService.ACTION_UPDATE); mContext.sendBroadcast(intent); } + private void setLock_screen(String jsonString) { + int type; + JsonObject jSONObject = GsonUtils.getJsonObject(jsonString); + type = jSONObject.get("is_lockscreen").getAsInt(); + if (!ControlUtils.isServiceAlice(mContext, ManagerService.class.getName())) { + mContext.startService(new Intent(mContext, ManagerService.class)); + } + Intent intent = new Intent(); +// intent.putExtra("name", name); + mMMKV.encode(ManagerService.LOCK_STATE, type); + if (1 == type) { + intent.setAction(ManagerService.ACTION_LOCK); + } else if (0 == type) { + intent.setAction(ManagerService.ACTION_UNLOCK); + } + mContext.sendBroadcast(intent); + NetInterfaceManager.getInstance().getSnSetting(); + + } + + public void screenshot(String s) { +// JsonObject jSONObject = GsonUtils.getJsonObject(s); +// long createTime = jSONObject.getLong("createTime"); + long createTime = System.currentTimeMillis() / 1000; + PowerManager.WakeLock mWakeLock = ControlUtils.acquireWakeLock(mContext, 60 * 1000); + ControlUtils.release(mWakeLock); + if (createTime != 0) { + Log.e("createTime", String.valueOf(createTime)); + Handler.getMain().postDelayed(new Runnable() { + @Override + public void run() { + doscreenshot(createTime); + } + }, 1234); + } + } + + public void doscreenshot(final long time) { + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter e) throws Exception { + String filepath = mContext.getExternalFilesDir("db").getAbsolutePath(); + int n = CmdUtil.execute("screencap -p " + filepath + File.separator + time + ".jpg").code; + e.onNext(n); + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(Integer integer) { + if (integer == 0) { + uplaodImage(time); + } else { + Log.e("doss", "失败"); + } + } + + @Override + public void onError(Throwable e) { + Log.e("doss", "Throwable=" + e.getMessage()); + } + + @Override + public void onComplete() { + + } + }); + } + + private void uplaodImage(long time) { + String filepath = mContext.getExternalFilesDir("db").getAbsolutePath(); +// String filepath = mContext.getFileStreamPath("screenshot").getAbsolutePath(); + //放在app内部data下面 + File file = new File(filepath + File.separator + time + ".jpg"); + Log.e(TAG, "uplaodImage: " + file.getAbsolutePath()); + //不要直接使用常用图片格式 + if (!file.exists()) { + Log.e("uplaodImage", "File does not exists"); + return; + } + //File转RequestBody + MediaType mediaType = MediaType.Companion.parse("image/png"); + RequestBody fileBody = RequestBody.Companion.create(file, mediaType); + //设置一个file文件 + MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), fileBody); + Map params = new HashMap<>(); + params.put("sn", Utils.getSerial()); + params.put("type", "1"); + Call call = NetInterfaceManager.getInstance().getUploadSnScreenshotApi().uploadSnScreenshot(params, body); + call.enqueue(new RetryCallback(call, 10, 30 * 1000) { + @Override + public void onRequestResponse(Call call, Response response) { + Log.e(TAG, "onRequestResponse: " + response.body().toString()); + } + + @Override + public void onRequestFail(Call call, Throwable t) { + Log.e(TAG, "onRequestFail: "); + } + + @Override + public void onStartRetry() { + Log.e(TAG, "onStartRetry: "); + } + }); + } } diff --git a/app/src/main/java/com/uiuipad/find/receiver/APKinstallReceiver.java b/app/src/main/java/com/uiuipad/find/receiver/APKinstallReceiver.java new file mode 100644 index 0000000..3617861 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/receiver/APKinstallReceiver.java @@ -0,0 +1,117 @@ +package com.uiuipad.find.receiver; + +import android.annotation.SuppressLint; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; + +import com.uiuipad.find.network.NetInterfaceManager; + +import java.util.concurrent.TimeUnit; + +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableEmitter; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; + +public class APKinstallReceiver extends BroadcastReceiver { + private static String TAG = APKinstallReceiver.class.getSimpleName(); + @SuppressLint("StaticFieldLeak") + private static Context mContext; + private static NewAppListener newAppListener; + + static { + sendAppInfo(); + } + + @Override + public void onReceive(final Context context, Intent intent) { + mContext = context; + // an Intent broadcast. + String action = intent.getAction(); +// ApkUtils.addShortcut(context); +// JGYUtils.getInstance().cleanLauncherCache(); +// ControlManager.getInstance().setDefaultApp(); + Log.e(TAG, "onReceive: " + "action = " + action); + String state; + if (TextUtils.isEmpty(action)) { + Log.e(TAG, "onReceive: " + "action is empty "); + return; + } + String packageName = intent.getDataString().replace("package:", ""); + switch (action) { + case Intent.ACTION_PACKAGE_ADDED: + state = "安装了:"; + break; + case Intent.ACTION_PACKAGE_REPLACED: +// cleanLauncher3Cache(); + state = "重装了:"; + break; + case Intent.ACTION_PACKAGE_REMOVED: + state = "卸载了:"; + break; + default: + state = "未知:"; + break; + } + Log.e(TAG, "sendAppInfo: " + state + packageName); +// ApkUtils.RemoveTask(mContext, packageName); + newAppListener.setNewAppListener(packageName); +// if (JGYUtils.PACKAGE_APPSTORE.equals(packageName)) { +// //启动应用市场 +// JGYUtils.getInstance().wakeUpDeviceInfo(); +// } else if (JGYUtils.PACKAGE_UPDATETOOLS.equals(packageName)) { +// //启动升级组件 +// JGYUtils.getInstance().wakeUpUpdateTools(); +// } + } + + private void cleanLauncher3Cache() { + try { +// new CacheUtils().cleanApplicationUserData(mContext, "com.android.launcher3"); + } catch (Exception e) { + Log.e(TAG, "onReceive: " + e.getMessage()); + e.printStackTrace(); + } + } + + public interface NewAppListener { + void setNewAppListener(String packageName); + } + + private static void sendAppInfo() { + Observable.create((ObservableEmitter emitter) -> newAppListener = emitter::onNext) + .throttleLast(5, TimeUnit.SECONDS) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("sendAppInfo", "onSubscribe: "); + } + + @Override + public void onNext(String s) { + Log.e("sendAppInfo", "onNext: " + s); +// int isLogined = (int) SPUtils.get(mContext, CommonConfig.isLogined, 2); +// if (isLogined == 2) return; +// NetInterfaceManager.getInstance().SendAppInstallInfo(); +// NetInterfaceManager.getInstance().getForceInstall(); +// NetInterfaceManager.getInstance().getAllappPackage(); +// NetInterfaceManager.getInstance().getAppInside(); +// MainService.mPresenter.getSnIsActivation(); + NetInterfaceManager.getInstance().updateAppInstall(); + } + + @Override + public void onError(Throwable e) { + Log.e("sendAppInfo", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("sendAppInfo", "onComplete: "); + } + }); + } +} diff --git a/app/src/main/java/com/uiuipad/find/receiver/BootReceiver.java b/app/src/main/java/com/uiuipad/find/receiver/BootReceiver.java index eb6b981..d3afc76 100644 --- a/app/src/main/java/com/uiuipad/find/receiver/BootReceiver.java +++ b/app/src/main/java/com/uiuipad/find/receiver/BootReceiver.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.util.Log; +import com.uiuipad.find.service.ManagerService; import com.uiuipad.find.service.main.MainService; public class BootReceiver extends BroadcastReceiver { @@ -28,6 +29,7 @@ public class BootReceiver extends BroadcastReceiver { || Intent.ACTION_SCREEN_OFF.equals(action) ) { context.startService(new Intent(context, MainService.class)); + context.startService(new Intent(context, ManagerService.class)); } } } diff --git a/app/src/main/java/com/uiuipad/find/receiver/InstallResultReceiver.java b/app/src/main/java/com/uiuipad/find/receiver/InstallResultReceiver.java new file mode 100644 index 0000000..22cf69c --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/receiver/InstallResultReceiver.java @@ -0,0 +1,59 @@ +package com.uiuipad.find.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInstaller; +import android.os.Build; +import android.util.Log; + +import androidx.annotation.RequiresApi; + +public class InstallResultReceiver extends BroadcastReceiver { + private static final String TAG = "InstallResultReceiver"; + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @Override + public void onReceive(Context context, Intent intent) { + // an Intent broadcast. + //throw new UnsupportedOperationException("Not yet implemented"); + + + if (intent != null) { + final int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_FAILURE); + if (status == PackageInstaller.STATUS_SUCCESS) { + // success + String PACKAGE_NAME = intent.getStringExtra("android.content.pm.extra.PACKAGE_NAME"); + + Log.e(TAG, "APP Install Success!"); + } else { + String msg = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE); + Log.e(TAG, "onReceive: " + msg); + String PACKAGE_NAME = intent.getStringExtra("android.content.pm.extra.PACKAGE_NAME"); + + } + } +// String s = intent.getAction(); +// Log.e("fht", s); +// Bundle extras = intent.getExtras(); +// Set ks = extras.keySet(); +// Iterator iterator = ks.iterator(); +// while (iterator.hasNext()) { +// Log.d("KEY", iterator.next()); +// } + String STATUS = intent.getStringExtra(PackageInstaller.EXTRA_STATUS); + String PACKAGE_NAME = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME); + String SESSION_ID = intent.getStringExtra(PackageInstaller.EXTRA_SESSION_ID); + String STATUS_MESSAGE = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE); + String LEGACY_STATUS = intent.getStringExtra("android.content.pm.extra.LEGACY_STATUS"); +// Log.e("fht", STATUS); +// Log.e("fht", PACKAGE_NAME); +// Log.e("fht", SESSION_ID); +// Log.e("fht", LEGACY_STATUS); +// Log.e("fht", STATUS_MESSAGE); + if (STATUS_MESSAGE != null && "INSTALL_SUCCEEDED".equals(STATUS_MESSAGE)) { +// ToastUtil.show(PACKAGE_NAME + "安装成功"); + } + } +} diff --git a/app/src/main/java/com/uiuipad/find/service/ManagerService.java b/app/src/main/java/com/uiuipad/find/service/ManagerService.java new file mode 100644 index 0000000..b0614cf --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/service/ManagerService.java @@ -0,0 +1,935 @@ +package com.uiuipad.find.service; + +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.Color; +import android.graphics.PixelFormat; +import android.media.AudioAttributes; +import android.media.SoundPool; +import android.os.Build; +import android.os.Handler; +import android.os.IBinder; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.blankj.utilcode.util.NetworkUtils; +import com.tencent.mmkv.MMKV; +import com.tuo.customview.VerificationCodeView; +import com.uiuipad.find.BuildConfig; +import com.uiuipad.find.R; +import com.uiuipad.find.bean.BaseResponse; +import com.uiuipad.find.comm.CommonConfig; +import com.uiuipad.find.network.NetInterfaceManager; +import com.uiuipad.find.receiver.APKinstallReceiver; +import com.uiuipad.find.receiver.BootReceiver; +import com.uiuipad.find.util.ControlUtils; +import com.uiuipad.find.util.TimeUtils; + +import java.util.concurrent.TimeUnit; + +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.core.ObservableEmitter; +import io.reactivex.rxjava3.core.ObservableOnSubscribe; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; + +/** + * @author jgy02 + */ +public class ManagerService extends Service implements NetworkUtils.OnNetworkStatusChangedListener { + private String TAG = ManagerService.class.getSimpleName(); + + public static final String ACTION_LOCK = BuildConfig.APPLICATION_ID + "_LockScreenReceiver_lockscreen"; + public static final String ACTION_UNLOCK = BuildConfig.APPLICATION_ID + "_LockScreenReceiver_unlockscreen"; + public static final String ACTION_UPDATE = BuildConfig.APPLICATION_ID + "_TimeChangedReceiver_update"; + + public static final String LOCK_SCREEN_PASSWORD = "aios_lockScreenPasswordKey"; + private static final String DEFAULT_PASSWORD = "6666"; + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + private WindowManager windowManager; + private View topView; + private View lostModeView; + private boolean screenLocked = false; + private boolean timeLocked = false; + private boolean lostMode = false; + + private SoundPool soundPool; + private int soundId; + + @Override + public void onDisconnected() { + + } + + @Override + public void onConnected(NetworkUtils.NetworkType networkType) { + if (ControlUtils.getScreenStatus(ManagerService.this)) { + getScreenLockState(); + } + } + + private interface Start { + void onstar(long time); + } + + private Start start; + + private final ObservableOnSubscribe subscribe = new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + start = new Start() { + @Override + public void onstar(long time) { + emitter.onNext(time); + } + }; + } + }; + + private Observer timeObserver = new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(Long aLong) { + Log.e("TimeObserver", "onNext: " + aLong); + int isLogined = mMMKV.decodeInt(CommonConfig.IS_LOGINED, 2); + if (isLogined == 2) { + + } + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onComplete() { + + } + }; + + private static KillAppListener killAppListener; + + public interface KillAppListener { + void killApp(String action); + } + + private final ObservableOnSubscribe killSubscribe = new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + killAppListener = new KillAppListener() { + @Override + public void killApp(String action) { + emitter.onNext(action); + } + }; + } + }; + + private Observer killObserver = new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.e("killObserver", "onSubscribe: "); + } + + @Override + public void onNext(String action) { + Log.e("killObserver", "onNext: " + action); +// ControlUtils.killPackage(ManagerService.this, JGYUtils.PACKAGE_APPSTORE); +// int is_activation = Settings.Global.getInt(getContentResolver(), CommonConfig.UIUI_ACTIVATION_KEY, 0); +// Log.e(TAG, "onReceive: is_activation = " + is_activation); +// if (is_activation == 0) { +// ControlUtils.killPackage(ManagerService.this, JGYUtils.PACKAGE_OS); +// } + } + + @Override + public void onError(Throwable e) { + Log.e("killObserver", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + Log.e("killObserver", "onComplete: "); + } + }; + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public void onCreate() { + super.onCreate(); + AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME) // 设置音效使用场景 + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build(); // 设置音效的类型 + soundPool = new SoundPool.Builder().setAudioAttributes(attr) // 设置音效池的属性 + .setMaxStreams(1) // 设置最多可容纳10个音频流 + .build(); // ① + // load方法加载指定音频文件,并返回所加载的音效ID + // 此处使用HashMap来管理这些音频流 + soundId = soundPool.load(this, R.raw.click, 1); + + NetworkUtils.registerNetworkStatusChangedListener(this); + registLockReceiver(); + registerTimeReceiver(); + registerScreenLockReceiver(); + registAppReceive(); + registBootReceive(); + registerBatteryReceiver(); + setFloatingWindow(); + Observable.create(subscribe) + .throttleFirst(3, TimeUnit.HOURS) + .subscribe(timeObserver); + + Observable.create(killSubscribe) + .throttleLast(3, TimeUnit.MINUTES) +// .throttleLast(3, TimeUnit.SECONDS) + .subscribe(killObserver); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + start.onstar(System.currentTimeMillis()); + return START_STICKY; + } + + private void getScreenLockState() { +// NetInterfaceManager.getInstance() +// .getScreenLockControl() +// .getScreenshot(Utils.getSerial()) +// .subscribeOn(Schedulers.io()) +// .observeOn(AndroidSchedulers.mainThread()) +// .subscribe(new Observer() { +// @Override +// public void onSubscribe(Disposable d) { +// Log.e("getScreenLockState", "onSubscribe: "); +// } +// +// @Override +// public void onNext(BaseResponse baseResponse) { +// Log.e("getScreenLockState", "onNext: "); +// int code = baseResponse.code; +// if (code == 200) { +// JsonObject jsonObject = GsonUtils.getJsonObject(GsonUtils.toJSONString(baseResponse.data)); +// int is_screen_lock = jsonObject.get("is_screen_lock").getAsInt(); +// setLockedState(is_screen_lock); +// } else { +// if (!timeLocked) { +// hideFloatingWindow(); +// } +// screenLocked = false; +// mMMKV.encode(LOCK_STATE, 0); +// } +// } +// +// @Override +// public void onError(Throwable e) { +// Log.e("getScreenLockState", "onError: " + e.getMessage()); +// } +// +// @Override +// public void onComplete() { +// Log.e("getScreenLockState", "onComplete: "); +// } +// }); + } + + private void setLockedState(int lockedState) { + if (lockedState == 1) { + if (!timeLocked) { + showFloatingWindow("屏幕已锁定"); + } + screenLocked = true; + mMMKV.encode(LOCK_STATE, 1); + } else { + if (!timeLocked) { + hideFloatingWindow(); + } + screenLocked = false; + mMMKV.encode(LOCK_STATE, 0); + } + } + + public static final String LOCK_STATE = "SCRENN_LOOCKED_STATE"; + + private void showFloatingWindow(String name) { + if (Settings.canDrawOverlays(this)) { + // 获取WindowManager服务 + if (null == windowManager) { + windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); + } + DisplayMetrics dm = new DisplayMetrics(); + windowManager.getDefaultDisplay().getRealMetrics(dm); + int width = dm.widthPixels; // 屏幕宽度(像素) + int height = dm.heightPixels; // 屏幕高度(像素) + // 新建悬浮窗控件 + final Button button = new Button(getApplicationContext()); + button.setText("霸屏测试"); + button.setAlpha(0.9f); + button.setBackgroundColor(Color.BLACK); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// windowManager.removeView(button); + } + }); + if (null == topView) { + topView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_screen_lock, null); + initTopView(topView, name); + } else { + if ("added".equals(topView.getTag())) { + initTopView(topView, name); + } else { + return; + } + return; + } + // topView.setAlpha(0.8f); + // 设置LayoutParam + WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + layoutParams.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; + //TYPE_SYSTEM_OVERLAY可以下滑通知栏 +// layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; + } else { + layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; + } + layoutParams.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; + layoutParams.format = PixelFormat.RGBA_8888; + layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; + layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT; + //systemUiVisibility 关闭通知栏和导航栏 + layoutParams.systemUiVisibility = + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_IMMERSIVE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + layoutParams.x = 0; + layoutParams.y = 0; + // 将悬浮窗控件添加到WindowManager + windowManager.addView(topView, layoutParams); + topView.setTag("added"); + } + } + + private void initTopView(View view, String name) { + TextView textView = view.findViewById(R.id.textView); + TextView tv_hint = view.findViewById(R.id.tv_hint); + textView.setText(name); + LinearLayout ll_keyboard = view.findViewById(R.id.ll_keyboard); + VerificationCodeView codeView = view.findViewById(R.id.icv); + codeView.getEditText().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + ll_keyboard.setVisibility(View.VISIBLE); + } + }); + codeView.setInputCompleteListener(new VerificationCodeView.InputCompleteListener() { + @Override + public void inputComplete() { + checkPassword(codeView, tv_hint); + } + + @Override + public void deleteContent() { + + } + }); + TextView bt0 = view.findViewById(R.id.bt_0); + TextView bt1 = view.findViewById(R.id.bt_1); + TextView bt2 = view.findViewById(R.id.bt_2); + TextView bt3 = view.findViewById(R.id.bt_3); + TextView bt4 = view.findViewById(R.id.bt_4); + TextView bt5 = view.findViewById(R.id.bt_5); + TextView bt6 = view.findViewById(R.id.bt_6); + TextView bt7 = view.findViewById(R.id.bt_7); + TextView bt8 = view.findViewById(R.id.bt_8); + TextView bt9 = view.findViewById(R.id.bt_9); + TextView bt_del = view.findViewById(R.id.bt_del); + TextView bt_confirm = view.findViewById(R.id.bt_confirm); + bt0.setOnClickListener(view1 -> add(codeView, "0")); + bt1.setOnClickListener(view1 -> add(codeView, "1")); + bt2.setOnClickListener(view1 -> add(codeView, "2")); + bt3.setOnClickListener(view1 -> add(codeView, "3")); + bt4.setOnClickListener(view1 -> add(codeView, "4")); + bt5.setOnClickListener(view1 -> add(codeView, "5")); + bt6.setOnClickListener(view1 -> add(codeView, "6")); + bt7.setOnClickListener(view1 -> add(codeView, "7")); + bt8.setOnClickListener(view1 -> add(codeView, "8")); + bt9.setOnClickListener(view1 -> add(codeView, "9")); + bt_del.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + tv_hint.setText(""); + codeView.clearInputContent(); + } + }); + bt_confirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + checkPassword(codeView, tv_hint); + } + }); + } + + private void checkPassword(VerificationCodeView codeView, TextView tv_hint) { + String content = codeView.getInputContent(); + if (TextUtils.isEmpty(content) || content.length() != 4) { + return; + } + Log.e(TAG, "inputComplete: " + content); + String password = Settings.Global.getString(getContentResolver(), LOCK_SCREEN_PASSWORD); + if ((!TextUtils.isEmpty(content) && !TextUtils.isEmpty(password))) { + if (password.equals(content)) { + hide(); + } else { + postDelayed(codeView, tv_hint); + tv_hint.setText("密码错误"); + Log.e("initTopView", "onClick: 密码错误"); + } + } else if (DEFAULT_PASSWORD.equals(content)) { + hide(); + } else { + postDelayed(codeView, tv_hint); + tv_hint.setText("密码错误"); + Log.e("initTopView", "onClick: 密码错误"); + } + } + + private void hide() { + Handler.getMain().postDelayed(new Runnable() { + @Override + public void run() { + hideFloatingWindow(); + } + }, 1000); + mMMKV.encode(ManagerService.LOCK_STATE, 0); + NetInterfaceManager.getInstance().getRemoveLockScreenControl() + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("getRemoveLockScreenApi", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getRemoveLockScreenApi", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + + } + }); + } + + private void hideFloatingWindow() { + if (null == windowManager) { + return; + } + if (null != topView) { + windowManager.removeView(topView); + topView = null; + } + } + + private void showLostWindow(String name) { + if (Settings.canDrawOverlays(this)) { + // 获取WindowManager服务 + if (null == windowManager) { + windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); + } + DisplayMetrics dm = new DisplayMetrics(); + windowManager.getDefaultDisplay().getRealMetrics(dm); + int width = dm.widthPixels; // 屏幕宽度(像素) + int height = dm.heightPixels; // 屏幕高度(像素) + // 新建悬浮窗控件 + final Button button = new Button(getApplicationContext()); + button.setText("霸屏测试"); + button.setAlpha(0.9f); + button.setBackgroundColor(Color.BLACK); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// windowManager.removeView(button); + } + }); + if (null == lostModeView) { + lostModeView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.activity_screen_lost, null); + initLostView(lostModeView, name); + } else { + if ("added".equals(lostModeView.getTag())) { + initLostView(lostModeView, name); + } else { + return; + } + return; + } + // lostModeView.setAlpha(0.8f); + // 设置LayoutParam + WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + layoutParams.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; + //TYPE_SYSTEM_OVERLAY可以下滑通知栏 +// layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; + } else { + layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE; + } + layoutParams.flags |= WindowManager.LayoutParams.FLAG_BLUR_BEHIND + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; + layoutParams.format = PixelFormat.RGBA_8888; + layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT; + layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT; + //systemUiVisibility 关闭通知栏和导航栏 + layoutParams.systemUiVisibility = + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_IMMERSIVE + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + layoutParams.x = 0; + layoutParams.y = 0; + // 将悬浮窗控件添加到WindowManager + windowManager.addView(lostModeView, layoutParams); + lostModeView.setTag("added"); + } + } + + private void initLostView(View view, String name) { + TextView textView = view.findViewById(R.id.textView); + TextView tv_hint = view.findViewById(R.id.tv_hint); + textView.setText(name); + LinearLayout ll_keyboard = view.findViewById(R.id.ll_keyboard); + VerificationCodeView codeView = view.findViewById(R.id.icv); + codeView.getEditText().setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + ll_keyboard.setVisibility(View.VISIBLE); + } + }); + codeView.setInputCompleteListener(new VerificationCodeView.InputCompleteListener() { + @Override + public void inputComplete() { + checkPasswordLost(codeView, tv_hint); + } + + @Override + public void deleteContent() { + + } + }); + TextView bt0 = view.findViewById(R.id.bt_0); + TextView bt1 = view.findViewById(R.id.bt_1); + TextView bt2 = view.findViewById(R.id.bt_2); + TextView bt3 = view.findViewById(R.id.bt_3); + TextView bt4 = view.findViewById(R.id.bt_4); + TextView bt5 = view.findViewById(R.id.bt_5); + TextView bt6 = view.findViewById(R.id.bt_6); + TextView bt7 = view.findViewById(R.id.bt_7); + TextView bt8 = view.findViewById(R.id.bt_8); + TextView bt9 = view.findViewById(R.id.bt_9); + TextView bt_del = view.findViewById(R.id.bt_del); + TextView bt_confirm = view.findViewById(R.id.bt_confirm); + bt0.setOnClickListener(view1 -> add(codeView, "0")); + bt1.setOnClickListener(view1 -> add(codeView, "1")); + bt2.setOnClickListener(view1 -> add(codeView, "2")); + bt3.setOnClickListener(view1 -> add(codeView, "3")); + bt4.setOnClickListener(view1 -> add(codeView, "4")); + bt5.setOnClickListener(view1 -> add(codeView, "5")); + bt6.setOnClickListener(view1 -> add(codeView, "6")); + bt7.setOnClickListener(view1 -> add(codeView, "7")); + bt8.setOnClickListener(view1 -> add(codeView, "8")); + bt9.setOnClickListener(view1 -> add(codeView, "9")); + bt_del.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + tv_hint.setText(""); + codeView.clearInputContent(); + } + }); + bt_confirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + checkPasswordLost(codeView, tv_hint); + } + }); + } + + private void checkPasswordLost(VerificationCodeView codeView, TextView tv_hint) { + String content = codeView.getInputContent(); + if (TextUtils.isEmpty(content) || content.length() != 4) { + return; + } + Log.e(TAG, "inputComplete: " + content); + String password = Settings.Global.getString(getContentResolver(), LOCK_SCREEN_PASSWORD); + if ((!TextUtils.isEmpty(content) && !TextUtils.isEmpty(password))) { + if (password.equals(content)) { + hideLost(); + } else { + postDelayed(codeView, tv_hint); + Log.e("initLostView", "onClick: 密码错误"); + } + } else if (DEFAULT_PASSWORD.equals(content)) { + hideLost(); + } else { + postDelayed(codeView, tv_hint); + Log.e("initLostView", "onClick: 密码错误"); + } + } + + private void postDelayed(VerificationCodeView view, TextView tv_hint) { + tv_hint.setText("密码错误"); + Handler.getMain().postDelayed(new Runnable() { + @Override + public void run() { + view.clearInputContent(); + tv_hint.setText(""); + } + }, 1000); + } + + private void hideLost() { + Handler.getMain().postDelayed(new Runnable() { + @Override + public void run() { + hideLostWindow(); + } + }, 1000); + mMMKV.encode(ManagerService.LOCK_STATE, 0); + NetInterfaceManager.getInstance().getRemoveLockScreenControl() + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("getRemoveLockScreenApi", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getRemoveLockScreenApi", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + + } + }); + mMMKV.encode(CommonConfig.LOST_STATUS_KEY, 0); + } + + private void hideLostWindow() { + if (null == windowManager) { + return; + } + if (null != lostModeView) { + windowManager.removeView(lostModeView); + lostModeView = null; + } + } + + private void add(VerificationCodeView codeView, String text) { + Log.e(TAG, "add: text = " + text); + String oldText = codeView.getEditText().getText().toString(); + Log.e(TAG, "add: " + oldText); + codeView.getEditText().setText(text); + soundPool.play(soundId, 1, 1, 0, 0, 1); + } + + private LockScreenReceiver lockScreenReceiver; + + private void registLockReceiver() { + if (null == lockScreenReceiver) { + lockScreenReceiver = new LockScreenReceiver(); + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(ACTION_LOCK); + filter.addAction(ACTION_UNLOCK); + registerReceiver(lockScreenReceiver, filter); + } + } + + private class LockScreenReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (TextUtils.isEmpty(action)) { + getScreenLockState(); + return; + } + if (lostMode) { + return; + } + if (ACTION_LOCK.equals(action)) { +// String name = intent.getStringExtra("name"); + String name = "屏幕已锁定"; + if (!timeLocked) { + showFloatingWindow(name); + } + screenLocked = true; + } else if (ACTION_UNLOCK.equals(action)) { + if (!timeLocked) { + hideFloatingWindow(); + } + screenLocked = false; + } + } + } + + private TimeChangedReceiver mTimeChangedReceiver; + + /** + * 监听时间和日期变化 + */ + private void registerTimeReceiver() { + mTimeChangedReceiver = new TimeChangedReceiver(); + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_DATE_CHANGED); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(Intent.ACTION_TIME_TICK); + filter.addAction(ACTION_UPDATE); + registerReceiver(mTimeChangedReceiver, filter); + } + + private class TimeChangedReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_DATE_CHANGED.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "data changed"); + } else if (Intent.ACTION_TIME_CHANGED.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "time changed"); + } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "timezone changed"); + } else if (Intent.ACTION_TIME_TICK.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "time tick"); + setFloatingWindow(); + } else if (ACTION_UPDATE.equals(action)) { + Log.e(TAG, "TimeChangedReceiver:" + "date update"); + setFloatingWindow(); + } + } + } + + private void setFloatingWindow() { + Log.e(TAG, "setFloatingWindow: "); + int is_lose = mMMKV.decodeInt(CommonConfig.LOST_STATUS_KEY); + if (is_lose == 1) { + String lose_str = mMMKV.decodeString(CommonConfig.FIND_STRING_KEY); + showLostWindow(lose_str); + lostMode = true; + return; + } else { + hideLostWindow(); + lostMode = false; + } + + TimeUtils.ContralTime workingContralTime = TimeUtils.getWorkingDayContralTime(ManagerService.this); + TimeUtils.ContralTime weekContralTime = TimeUtils.getWeekDayContralTime(ManagerService.this); +// if (null != workingContralTime) { + if (TimeUtils.inContralTime(workingContralTime, weekContralTime)) { + if (!screenLocked) { + showFloatingWindow("可用时间:\n" + TimeUtils.getNowTimeString(ManagerService.this)); + } else { + TextView textView = topView.findViewById(R.id.textView); + textView.setText("可用时间:\n" + TimeUtils.getNowTimeString(ManagerService.this)); + } + timeLocked = true; + } else { +// getScreenLockState(); + int is_screen_lock = mMMKV.decodeInt(LOCK_STATE, 0); + setLockedState(is_screen_lock); + if (!screenLocked) { + hideFloatingWindow(); + } + timeLocked = false; + } +// } else { +// if (!screenlocked) { +// hideFloatingWindow() +// } +// getScreenLockState() +// timelocked = false +// } + } + + private ScreenLockReceiver screenLockReceiver; + + private void registerScreenLockReceiver() { + if (null == screenLockReceiver) { + screenLockReceiver = new ScreenLockReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_BOOT_COMPLETED); + filter.addAction(Intent.ACTION_USER_PRESENT); + filter.addAction(Intent.ACTION_SHUTDOWN); + filter.addAction(Intent.ACTION_FACTORY_RESET); + filter.addAction(Intent.ACTION_MASTER_CLEAR); + registerReceiver(screenLockReceiver, filter); + } + + private class ScreenLockReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.e(TAG, "onReceive:" + action); + if (TextUtils.isEmpty(action)) { + Log.e(TAG, "onReceive: is NULL"); + return; + } + switch (action) { + case Intent.ACTION_USER_PRESENT: + case Intent.ACTION_SCREEN_ON: + sendScreenState(1); + break; + case Intent.ACTION_SCREEN_OFF: + case Intent.ACTION_SHUTDOWN: + case Intent.ACTION_FACTORY_RESET: + case Intent.ACTION_MASTER_CLEAR: + sendScreenState(0); + killAppListener.killApp(action); + break; + default: + break; + } + } + } + + private void sendScreenState(int stateCode) { +// Log.e(TAG, "sendScreenState: code:" + stateCode); +//// Log.e(TAG, "sendScreenState: sn: " + Utils.getSerial()); +// NetInterfaceManager.getInstance().setScreen() +// .setScreenState(Utils.getSerial(), stateCode) +// .subscribeOn(Schedulers.io()) +// .observeOn(AndroidSchedulers.mainThread()) +// .subscribe(new Observer() { +// @Override +// public void onSubscribe(Disposable d) { +// Log.e("sendScreenState", "onSubscribe: "); +// } +// +// @Override +// public void onNext(BaseResponse baseResponse) { +// Log.e("sendScreenState", "onNext: " + baseResponse.msg); +// } +// +// @Override +// public void onError(Throwable e) { +// // TODO: 2022/7/11 接口本身问题 +//// Log.e("sendScreenState", "onError: " + e.getMessage()); +// } +// +// @Override +// public void onComplete() { +// Log.e("sendScreenState", "onComplete: "); +// } +// }); + } + + private APKinstallReceiver apKinstallReceiver; + + private void registAppReceive() { + if (null == apKinstallReceiver) { + apKinstallReceiver = new APKinstallReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_PACKAGE_ADDED); + filter.addAction(Intent.ACTION_PACKAGE_REPLACED); + filter.addAction(Intent.ACTION_PACKAGE_REMOVED); + filter.addDataScheme("package"); + registerReceiver(apKinstallReceiver, filter); + } + + private BootReceiver bootReceiver; + + private void registBootReceive() { + if (null == bootReceiver) { + bootReceiver = new BootReceiver(); + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_USER_PRESENT); + registerReceiver(bootReceiver, filter); + } + } + + private BatteryReceiver batteryReceiver; + + private void registerBatteryReceiver() { + if (null == batteryReceiver) { + batteryReceiver = new BatteryReceiver(); + } + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_POWER_DISCONNECTED); + registerReceiver(batteryReceiver, filter); + } + + private class BatteryReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { + + } else if (Intent.ACTION_POWER_CONNECTED.equals(action) || Intent.ACTION_POWER_DISCONNECTED.equals(action)) { +// ControlManager.getInstance().setDefaultUSBstate(); + } else if (Intent.ACTION_BATTERY_LOW.equals(action) || Intent.ACTION_BATTERY_OKAY.equals(action)) { + + } + } + } + + + @Override + public void onDestroy() { + super.onDestroy(); + NetworkUtils.unregisterNetworkStatusChangedListener(this); + if (null != mTimeChangedReceiver) { + unregisterReceiver(mTimeChangedReceiver); + } + if (null != lockScreenReceiver) { + unregisterReceiver(lockScreenReceiver); + } + if (null != screenLockReceiver) { + unregisterReceiver(screenLockReceiver); + } + if (null != apKinstallReceiver) { + unregisterReceiver(apKinstallReceiver); + } + if (null != bootReceiver) { + unregisterReceiver(bootReceiver); + } + } +} diff --git a/app/src/main/java/com/uiuipad/find/service/RemoteService.java b/app/src/main/java/com/uiuipad/find/service/RemoteService.java new file mode 100644 index 0000000..0f250a5 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/service/RemoteService.java @@ -0,0 +1,40 @@ +package com.uiuipad.find.service; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; + +import com.uiuipad.find.util.Utils; +import com.uiuipad.sn.SystemInfoInterface; + +public class RemoteService extends Service { + private String TAG = RemoteService.class.getSimpleName(); + + public RemoteService() { + } + + @Override + public IBinder onBind(Intent intent) { + Log.e(TAG, "onBind: "); + return mBinde; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return super.onStartCommand(intent, flags, startId); + } + + SystemInfoInterface.Stub mBinde = new SystemInfoInterface.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 Utils.getSerial(); + } + }; +} diff --git a/app/src/main/java/com/uiuipad/find/service/main/MainSContact.java b/app/src/main/java/com/uiuipad/find/service/main/MainSContact.java index b4ae1c9..fe82d60 100644 --- a/app/src/main/java/com/uiuipad/find/service/main/MainSContact.java +++ b/app/src/main/java/com/uiuipad/find/service/main/MainSContact.java @@ -6,10 +6,16 @@ import com.uiuipad.find.base.BaseView; public class MainSContact { interface Presenter extends BasePresenter { - + void updateSnInfo(); + void getSnSetting(); + void getApp(); + void getSelfApp(); } - public interface MainView extends BaseView { - + public interface MainView extends BaseView { + void updateSnInfoFinish(); + void getSnSettingFinish(); + void getAppFinish(); + void getSelfAppFinish(); } } diff --git a/app/src/main/java/com/uiuipad/find/service/main/MainSPresenter.java b/app/src/main/java/com/uiuipad/find/service/main/MainSPresenter.java index e4aed5a..2cc617d 100644 --- a/app/src/main/java/com/uiuipad/find/service/main/MainSPresenter.java +++ b/app/src/main/java/com/uiuipad/find/service/main/MainSPresenter.java @@ -1,11 +1,22 @@ package com.uiuipad.find.service.main; import android.content.Context; +import android.util.Log; import com.tencent.mmkv.MMKV; +import com.trello.rxlifecycle4.RxLifecycle; import com.trello.rxlifecycle4.android.ActivityEvent; +import com.uiuipad.find.bean.AppInfo; +import com.uiuipad.find.bean.BaseResponse; import com.uiuipad.find.comm.CommonConfig; +import com.uiuipad.find.network.NetInterfaceManager; +import com.uiuipad.find.util.ApkUtils; +import java.util.List; + +import io.reactivex.rxjava3.annotations.NonNull; +import io.reactivex.rxjava3.core.Observer; +import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.subjects.BehaviorSubject; /** @@ -43,5 +54,105 @@ public class MainSPresenter implements MainSContact.Presenter { this.mView = null; } + @Override + public void updateSnInfo() { + NetInterfaceManager.getInstance().getUpdateSnInfoControl() + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("updateSnInfo", "onSubscribe: "); + } + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("updateSnInfo", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("updateSnInfo", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("updateSnInfo", "onComplete: "); + mView.updateSnInfoFinish(); + } + }); + } + + @Override + public void getSnSetting() { + NetInterfaceManager.getInstance().getSnSetting(); + mView.getSnSettingFinish(); + } + + @Override + public void getApp() { +// NetInterfaceManager.getInstance().getAppControl() +//// .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) +//// .subscribe(new Observer>>() { +//// @Override +//// public void onSubscribe(@NonNull Disposable d) { +//// Log.e("getApp", "onSubscribe: "); +//// } +//// +//// @Override +//// public void onNext(@NonNull BaseResponse> baseResponse) { +//// Log.e("getApp", "onNext: " + baseResponse); +//// if (baseResponse.code==200){ +//// List appInfoList =baseResponse.data; +//// ApkUtils.checkAppInstall(mContext,appInfoList); +//// } +//// } +//// +//// @Override +//// public void onError(@NonNull Throwable e) { +//// Log.e("getApp", "onError: " + e.getMessage()); +//// } +//// +//// @Override +//// public void onComplete() { +//// Log.e("getApp", "onComplete: "); +//// } +//// }); + mView.getAppFinish(); + } + + @Override + public void getSelfApp() { + NetInterfaceManager.getInstance().getSelfAppControl() + .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) + .subscribe(new Observer>>() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("getSelfApp", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse> baseResponse) { + Log.e("getSelfApp", "onNext: " + baseResponse); + if (baseResponse.code == 200) { + List appInfoList = baseResponse.data; + ApkUtils.checkAppInstall(mContext, appInfoList); + } else { + Log.e("getSelfApp", "onNext: no updates found"); + } + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("getSelfApp", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("getSelfApp", "onComplete: "); + mView.getSelfAppFinish(); + } + }); + } } diff --git a/app/src/main/java/com/uiuipad/find/service/main/MainService.java b/app/src/main/java/com/uiuipad/find/service/main/MainService.java index fe8acab..d6a2384 100644 --- a/app/src/main/java/com/uiuipad/find/service/main/MainService.java +++ b/app/src/main/java/com/uiuipad/find/service/main/MainService.java @@ -8,6 +8,7 @@ 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; @@ -16,7 +17,11 @@ import android.util.Log; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; +import com.arialyy.annotations.Download; +import com.arialyy.aria.core.Aria; +import com.arialyy.aria.core.task.DownloadTask; import com.blankj.utilcode.util.NetworkUtils; +import com.google.gson.JsonObject; import com.tencent.mmkv.MMKV; import com.trello.rxlifecycle4.LifecycleProvider; import com.trello.rxlifecycle4.LifecycleTransformer; @@ -26,6 +31,9 @@ import com.trello.rxlifecycle4.android.RxLifecycleAndroid; import com.uiuipad.find.R; import com.uiuipad.find.activity.main.MainActivity; import com.uiuipad.find.comm.CommonConfig; +import com.uiuipad.find.gson.GsonUtils; +import com.uiuipad.find.network.NetInterfaceManager; +import com.uiuipad.find.util.ApkUtils; import org.jetbrains.annotations.NotNull; @@ -41,9 +49,6 @@ public class MainService extends Service implements MainSContact.MainView, Netwo public MainSPresenter mPresenter; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); - //执行所有请求的时间 - long runningTime; - private final BehaviorSubject lifecycleSubject = BehaviorSubject.create(); @NotNull @@ -76,7 +81,15 @@ public class MainService extends Service implements MainSContact.MainView, Netwo @Override public IBinder onBind(Intent intent) { - return null; + return mMainBinder; + } + + public MainBinder mMainBinder = new MainBinder(); + + public class MainBinder extends Binder { + public MainService getService() { + return MainService.this; + } } @Override @@ -86,15 +99,51 @@ public class MainService extends Service implements MainSContact.MainView, Netwo mPresenter = new MainSPresenter(this); mPresenter.setLifecycle(lifecycleSubject); mPresenter.attachView(this); + Aria.download(this).register(); registerReceivers(); + mPresenter.updateSnInfo(); + } + //在这里处理任务执行中的状态,如进度进度条的刷新 + @Download.onTaskRunning + void running(DownloadTask task) { + Log.e("aria running", "正在下载:" + task.getState() + "-" + task.getPercent() + "--" + task.getExtendField()); + String appName = ""; + try { + String jsonString = task.getExtendField(); + JsonObject jsonObject = GsonUtils.getJsonObject(jsonString); + if (!TextUtils.isEmpty(jsonString) && jsonObject != null) { + appName = jsonObject.get("app_name").getAsString(); + } + } catch (Exception e) { + Log.e("running", "running: " + e.getMessage()); + } + } + + @Download.onTaskComplete + void taskComplete(DownloadTask task) { + //在这里处理任务完成的状态 + ApkUtils.installApp(MainService.this, task.getFilePath()); + Log.e("taskComplete", task.getExtendField()); + } + + @Download.onTaskFail + void taskFail(DownloadTask task, Exception e) { + Aria.download(this).resumeAllTask(); + try { + String filepath = task.getFilePath(); + String packageName = task.getExtendField(); + Log.e(TAG, "taskFail: " + packageName + "filepath: " + filepath); + Aria.download(this).load(task.getDownloadEntity().getId()).cancel(true); + Log.e(TAG, "taskFail: " + "Exception: " + e.getLocalizedMessage()); + } catch (Exception ex) { + + } } private void registerReceivers() { -// registerWiFiReceiver(); - registerRefreshReceiver(); -// registerPasswordReceiver(); + } private static final String CHANNEL_ID = "CHANNEL_ID"; @@ -137,32 +186,6 @@ public class MainService extends Service implements MainSContact.MainView, Netwo mNotificationManagerCompat.notify(NotificationID, builder.build()); } - - private RefreshInfoReceiver mRefreshInfoReceiver; - - private void registerRefreshReceiver() { - if (mRefreshInfoReceiver == null) { - mRefreshInfoReceiver = new RefreshInfoReceiver(); - } - IntentFilter filter = new IntentFilter(); - filter.addAction(RefreshInfoReceiver.REFRESH_RECEIVER_ACTION); - registerReceiver(mRefreshInfoReceiver, filter); - } - - - public class RefreshInfoReceiver extends BroadcastReceiver { - public static final String REFRESH_RECEIVER_ACTION = "Receiver_Refresh_Action"; - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - Log.e("RefreshInfoReceiver", "onReceive: " + action); - if (!TextUtils.isEmpty(action)) { - - } - } - } - @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand: " + System.currentTimeMillis()); @@ -175,16 +198,25 @@ public class MainService extends Service implements MainSContact.MainView, Netwo lifecycleSubject.onNext(ActivityEvent.DESTROY); NetworkUtils.unregisterNetworkStatusChangedListener(this); mPresenter.detachView(); - -// if (mWifiReceiver != null) { -// unregisterReceiver(mRefreshInfoReceiver); -// } - if (mRefreshInfoReceiver != null) { - unregisterReceiver(mRefreshInfoReceiver); - } -// if (mPasswdReceiver != null) { -// unregisterReceiver(mPasswdReceiver); -// } } + @Override + public void updateSnInfoFinish() { + mPresenter.getSnSetting(); + } + + @Override + public void getSnSettingFinish() { + mPresenter.getApp(); + } + + @Override + public void getAppFinish() { + mPresenter.getSelfApp(); + } + + @Override + public void getSelfAppFinish() { + NetInterfaceManager.getInstance().updateAppInstall(); + } } diff --git a/app/src/main/java/com/uiuipad/find/util/ApkUtils.java b/app/src/main/java/com/uiuipad/find/util/ApkUtils.java new file mode 100644 index 0000000..bdfb859 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/util/ApkUtils.java @@ -0,0 +1,387 @@ +package com.uiuipad.find.util; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageInstaller; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.Build; +import android.util.Log; + +import androidx.annotation.RequiresApi; + +import com.google.gson.JsonObject; +import com.uiuipad.find.BuildConfig; +import com.uiuipad.find.bean.AppInfo; +import com.uiuipad.find.bean.InstallAppInfo; +import com.uiuipad.find.gson.GsonUtils; +import com.uiuipad.find.receiver.InstallResultReceiver; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class ApkUtils { + private static final String TAG = ApkUtils.class.getSimpleName(); + + /** + * 获取第三方应用 + * + * @param context + * @return + */ + public static List queryFilterAppList(Context context) { + PackageManager pm = context.getPackageManager(); + // 查询所有已经安装的应用程序 + List appInfos = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);// GET_UNINSTALLED_PACKAGES代表已删除,但还有安装目录的 + List applicationInfos = new ArrayList<>(); + for (ApplicationInfo app : appInfos) { + if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 1) { + //通过flag排除系统应用,会将电话、短信也排除掉 + } else { + applicationInfos.add(app.packageName); + Log.e("queryFilterAppInfo", app.packageName); + } + } + return applicationInfos; + } + + /** + * 判断是否为系统应用 + * + * @param context 上下文 + * @param pkgName 包名 + * @return + */ + public static boolean isSystemApp(Context context, String pkgName) { + boolean isSystemApp = false; + PackageInfo pi = null; + try { + PackageManager pm = context.getPackageManager(); + pi = pm.getPackageInfo(pkgName, 0); + } catch (PackageManager.NameNotFoundException e) { + Log.e("isSystemApp: NameNotFoundException:", e.getMessage()); + } + // 是系统中已安装的应用 + if (pi != null) { + boolean isSysApp = (pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1; + boolean isSysUpd = (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1; + isSystemApp = isSysApp || isSysUpd; + } + return isSystemApp; + } + + + /** + * 检查手机上是否安装了指定的软件 + */ + public static boolean isAvailable(Context context, String packageName) { + // 获取packagemanager + final PackageManager packageManager = context.getPackageManager(); + // 获取所有已安装程序的包信息 + List packageInfos = packageManager.getInstalledPackages(0); + // 用于存储所有已安装程序的包名 + List packageNames = new ArrayList<>(); + // 从pinfo中将包名字逐一取出,压入pName list中 + if (packageInfos != null) { + for (int i = 0; i < packageInfos.size(); i++) { + String packName = packageInfos.get(i).packageName; + packageNames.add(packName); + } + } + // 判断packageNames中是否有目标程序的包名,有TRUE,没有FALSE + return packageNames.contains(packageName); + } + + + /** + * 通过路径安装APK,兼容Android 9以上 + * + * @param context 上下文 + * @param filePath apk文件路径 + */ + public static void installApp(Context context, String filePath) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + installAppatPie(context, filePath); + } else { + installApps(filePath); + } + } + + public static boolean installApps(String apkPath) { + ToastUtil.show("正在安装应用"); + Process process = null; + BufferedReader successResult = null; + BufferedReader errorResult = null; + StringBuilder successMsg = new StringBuilder(); + StringBuilder errorMsg = new StringBuilder(); + try { + process = new ProcessBuilder("pm", "install", "-i", BuildConfig.APPLICATION_ID, "--user", "0", apkPath).start(); + successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String s; + while ((s = successResult.readLine()) != null) { + successMsg.append(s); + } + while ((s = errorResult.readLine()) != null) { + errorMsg.append(s); + } + } catch (Exception e) { + Log.e("installApps1", e.getMessage()); + } finally { + try { + if (successResult != null) { + successResult.close(); + } + if (errorResult != null) { + errorResult.close(); + } + } catch (Exception e) { + Log.e("installApps2", e.getMessage()); + } + if (process != null) { + process.destroy(); + } + } + Log.e("result", "" + errorMsg.toString()); + //如果含有“success”认为安装成功 + Log.e("installApp", successMsg.toString()); +// if (!successMsg.toString().equalsIgnoreCase("success")) { +// install(context, new File(apkPath)); +// } + return successMsg.toString().equalsIgnoreCase("success"); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public static void installAppatPie(Context context, String apkFilePath) { + File file = new File(apkFilePath); + PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); + PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(PackageInstaller + .SessionParams.MODE_FULL_INSTALL); + sessionParams.setSize(file.length()); + int sessionId = createSession(packageInstaller, sessionParams); + if (sessionId != -1) { + boolean copySuccess = copyApkFile(packageInstaller, sessionId, apkFilePath); + if (copySuccess) { + install(packageInstaller, sessionId, context); + } + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static boolean copyApkFile(PackageInstaller pi, int sessionId, String apkFilePath) { + boolean success = false; + File apkFile = new File(apkFilePath); + PackageInstaller.Session session = null; + try { + session = pi.openSession(sessionId); + OutputStream out = session.openWrite("app.apk", 0, apkFile.length()); + FileInputStream input = new FileInputStream(apkFile); + int read = 0; + byte[] buffer = new byte[65536]; +// while (read != -1) { +// read = input.read(buffer); +// out.write(buffer, 0, read); +// } + while (true) { + read = input.read(buffer); + if (read == -1) { + session.fsync(out); + success = true; + out.close(); + input.close(); + break; + } + out.write(buffer, 0, read); + } + } catch (IOException e) { + e.printStackTrace(); + Log.e("fht", "copyApkFile" + e.getMessage()); + } + return success; + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static void install(PackageInstaller packageInstaller, int sessionId, Context context) { + try { + PackageInstaller.Session session = packageInstaller.openSession(sessionId); + Intent intent = new Intent(context, InstallResultReceiver.class); + PendingIntent pendingIntent = PendingIntent.getBroadcast( + context, + 1, intent, + PendingIntent.FLAG_UPDATE_CURRENT + ); + session.commit(pendingIntent.getIntentSender()); + } catch (IOException e) { + e.printStackTrace(); + Log.e(TAG, "install: " + e.getMessage()); + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static int createSession(PackageInstaller packageInstaller, PackageInstaller.SessionParams sessionParams) { + int sessionId = -1; + try { + sessionId = packageInstaller.createSession(sessionParams); + } catch (IOException e) { + e.printStackTrace(); + } + return sessionId; + } + + + public static void uninstallApp(Context context, String packageName) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + uninstall(context, packageName); + } else { + deleteApkInSilence(packageName); + } + } + + /** + * 根据包名卸载应用 + * + * @param packageName 包名 + */ + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + public static void uninstall(Context context, String packageName) { + Intent broadcastIntent = new Intent(context, InstallResultReceiver.class); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, + broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller(); + packageInstaller.uninstall(packageName, pendingIntent.getIntentSender()); + } + + public static void deleteApkInSilence(String packageName) { + Class pmService; + Class activityTherad; + Method method; + try { + activityTherad = Class.forName("android.app.ActivityThread"); + Class paramTypes[] = getParamTypes(activityTherad, "getPackageManager"); + method = activityTherad.getMethod("getPackageManager", paramTypes); + Object PackageManagerService = method.invoke(activityTherad); + pmService = PackageManagerService.getClass(); + Class paramTypes1[] = getParamTypes(pmService, "deletePackageAsUser"); + method = pmService.getMethod("deletePackageAsUser", paramTypes1); + //getUserId + method.invoke(PackageManagerService, packageName, null, getUserId(Binder.getCallingUid()), 0x00000040); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + + private static Class[] getParamTypes(Class cls, String mName) { + Class cs[] = null; + Method[] mtd = cls.getMethods(); + for (int i = 0; i < mtd.length; i++) { + if (!mtd[i].getName().equals(mName)) { + continue; + } + cs = mtd[i].getParameterTypes(); + } + return cs; + } + + public static final int PER_USER_RANGE = 100000; + + public static int getUserId(int uid) { + return uid / PER_USER_RANGE; + } + + + /** + * @param appInfos 安装强制应用 + */ + public static void checkAppInstall(Context context, List appInfos) { + if (appInfos == null || appInfos.size() == 0) { + return; + } + for (AppInfo appInfo : appInfos) { + checkAppInstall(context, appInfo); + } + } + + public static void checkAppInstall(Context context, AppInfo appInfo) { + if (appInfo == null) { + Log.e("checkAppInstall", "AppInfo is null"); + return; + } + String packageName = appInfo.getApp_package(); + long app_version_code = appInfo.getApp_version_code(); + String url = appInfo.getApp_url(); + JsonObject extra = GsonUtils.getJsonObject(GsonUtils.toJSONString(appInfo)); + PackageManager packageManager = context.getPackageManager(); + PackageInfo packageInfo = null; + try { + packageInfo = packageManager.getPackageInfo(packageName, 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(context, url, extra); + Log.e("checkAppInstall", "upgrade: " + packageName); + } else { + Log.e("checkAppInstall", "intallApk: " + packageName + " is up to date"); + } + } else { + Log.e("checkAppInstall", "checkAppInstall: not installed " + packageName); + FileUtils.ariaDownload(context, url, extra); + } + } + + + public static String getInstallAppInfo(Context context) { + PackageManager pm = context.getPackageManager(); + List packageInfos = pm.getInstalledPackages(0); + List filter = packageInfos.stream().filter(packageInfo -> !isSystemApp(context, packageInfo.packageName)).collect(Collectors.toList()); + List installAppInfos = new ArrayList<>(); + for (PackageInfo packageInfo : filter) { + InstallAppInfo installAppInfo = packageInfo2AppInfo(pm, packageInfo); + installAppInfos.add(installAppInfo); + } + return GsonUtils.toJSONString(installAppInfos); + } + + public static InstallAppInfo packageInfo2AppInfo(PackageManager packageManager, PackageInfo packageInfo) { + InstallAppInfo appInfo = new InstallAppInfo(); + appInfo.setApp_name(packageInfo.applicationInfo.loadLabel(packageManager).toString()); + appInfo.setInstall_time(TimeUtils.transferLongToDate(packageInfo.lastUpdateTime)); + appInfo.setApp_package(packageInfo.packageName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + appInfo.setApp_version_code(packageInfo.getLongVersionCode()); + } else { + appInfo.setApp_version_code(packageInfo.versionCode); + } + appInfo.setApp_version_name(packageInfo.versionName); + appInfo.setApp_size(new File(packageInfo.applicationInfo.publicSourceDir).length()); + return appInfo; + } + +} diff --git a/app/src/main/java/com/uiuipad/find/util/CmdUtil.java b/app/src/main/java/com/uiuipad/find/util/CmdUtil.java new file mode 100644 index 0000000..353c04c --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/util/CmdUtil.java @@ -0,0 +1,145 @@ +package com.uiuipad.find.util; + +import android.text.TextUtils; +import android.util.Log; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; + +public class CmdUtil { + private static final String TAG = "CmdUtil"; + + private static final String COMMAND_SH = "sh"; + private static final String COMMAND_EXIT = "exit\n"; + private static final String COMMAND_LINE_END = "\n"; + + + /** + * 运行命令 + * + * @param command 命令 + * @return 结果 + */ + public static Result execute(String command) { + Log.i(TAG, "execute() command = " + command); + Result result = new Result(); + + if (TextUtils.isEmpty(command)) { + Log.w(TAG, "WARNING: command should not be null or empty"); + return result; + } + + Process process = null; + DataOutputStream dos = null; + + try { + process = Runtime.getRuntime().exec(COMMAND_SH); + dos = new DataOutputStream(process.getOutputStream()); + dos.write(command.trim().getBytes()); + dos.writeBytes(COMMAND_LINE_END); + dos.flush(); + dos.writeBytes(COMMAND_EXIT); + dos.flush(); + result.code = process.waitFor(); + result.success = readBuffer(new BufferedReader(new InputStreamReader(process.getInputStream()))); + result.error = readBuffer(new BufferedReader(new InputStreamReader(process.getErrorStream()))); + Log.i(TAG, "result = " + result); + } catch (IOException ioe) { + ioe.printStackTrace(); + Log.e(TAG, ioe.getMessage()); + } catch (InterruptedException ie) { + ie.printStackTrace(); + Log.e(TAG, ie.getMessage()); + } finally { + try { + if (null != dos) { + dos.close(); + } + } catch (IOException ioe) { + ioe.printStackTrace(); + Log.e(TAG, ioe.getMessage()); + } + if (null != process) { + process.destroy(); + } + } + return result; + } + + private static String readBuffer(BufferedReader bufferedReader) throws IOException { + StringBuilder sb = new StringBuilder(); + String s; + while ((s = bufferedReader.readLine()) != null) { + sb.append(s); + } + return sb.toString(); + } + + + /** + * Command执行结果 + */ + public static final class Result { + + public static final int SUCCESS = 0; + public static final int ERROR = -1; + + public int code = ERROR; + public String error; + public String success; + + @Override + public String toString() { + return "Result{" + + "code=" + code + + ", error='" + error + '\'' + + ", success='" + success + '\'' + + '}'; + } + } + + + /** + * 执行 adb 命令 + * + * @param cmd 命令 + * @return + */ + public static StringBuffer shellExec(String cmd) { + Runtime mRuntime = Runtime.getRuntime(); //执行命令的方法 + try { + //Process中封装了返回的结果和执行错误的结果 + Process mProcess = mRuntime.exec(cmd); //加入参数 + //使用BufferReader缓冲各个字符,实现高效读取 + //InputStreamReader将执行命令后得到的字节流数据转化为字符流 + //mProcess.getInputStream()获取命令执行后的的字节流结果 + BufferedReader mReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream())); + //实例化一个字符缓冲区 + StringBuffer mRespBuff = new StringBuffer(); + //实例化并初始化一个大小为1024的字符缓冲区,char类型 + char[] buff = new char[1024]; + int ch = 0; + //read()方法读取内容到buff缓冲区中,大小为buff的大小,返回一个整型值,即内容的长度 + //如果长度不为null + while ((ch = mReader.read(buff)) != -1) { + //就将缓冲区buff的内容填进字符缓冲区 + mRespBuff.append(buff, 0, ch); + } + //结束缓冲 + mReader.close(); + Log.i("shell", "shellExec: " + mRespBuff); + //弹出结果 +// Log.i("shell", "执行命令: " + cmd + "执行成功"); + return mRespBuff; + + } catch (IOException e) { + // 异常处理 + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } +} + diff --git a/app/src/main/java/com/uiuipad/find/util/ControlUtils.java b/app/src/main/java/com/uiuipad/find/util/ControlUtils.java new file mode 100644 index 0000000..7eb8274 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/util/ControlUtils.java @@ -0,0 +1,322 @@ +package com.uiuipad.find.util; + +import android.app.ActivityManager; +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.content.Intent; +import android.os.PowerManager; +import android.provider.Settings; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.uiuipad.find.BuildConfig; +import com.uiuipad.find.bean.SnSetting; +import com.uiuipad.find.comm.CommonConfig; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * @author TT + * 管控功能都放这里 + */ +public class ControlUtils { + + private static final String TAG = ControlUtils.class.getSimpleName(); + + /** + * 重启设备 + * + * @param context + */ + public static void rebootDevices(Context context) { + Intent iReboot = new Intent(Intent.ACTION_REBOOT); + iReboot.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(iReboot); + } + + /** + * @param context + * @return 屏幕是否打开 + */ + public static boolean getScreenStatus(Context context) { + PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + //true为打开,false为关闭 + return powerManager.isScreenOn(); + } + + /** + * 点亮屏幕 + * + * @param timeout The timeout after which to release the wake lock, in milliseconds. + */ + @Nullable + public static PowerManager.WakeLock acquireWakeLock(@NonNull Context context, long timeout) { + PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); + if (pm == null) + return null; + PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | + PowerManager.FULL_WAKE_LOCK | + PowerManager.ON_AFTER_RELEASE, + context.getClass().getName()); + wakeLock.acquire(timeout); + return wakeLock; + } + + /** + * @param wakeLock 释放电源锁 + */ + public static void release(@Nullable PowerManager.WakeLock wakeLock) { + if (wakeLock != null && wakeLock.isHeld()) { + wakeLock.release(); + } + } + + public static void killBackgroundApp(Context context) { + List pkgList = ApkUtils.queryFilterAppList(context); + for (String pkg : pkgList) { + if (pkg.equalsIgnoreCase(BuildConfig.APPLICATION_ID) + || "com.tencent.mm".equals(pkg) + || "com.uiui.sn".equals(pkg) + ) { + continue; + } + killBackgroundProcesses(context, pkg); + } + } + + public static void killBackgroundProcesses(Context context, String packageName) { + ActivityManager activityManager; + try { + activityManager = (ActivityManager) + context.getSystemService(Context.ACTIVITY_SERVICE); + activityManager.killBackgroundProcesses(packageName); + Method forceStopPackage = activityManager.getClass() + .getDeclaredMethod("forceStopPackage", String.class); +// Log.e(TAG, "killBackgroundProcesses: " + packageName); + forceStopPackage.setAccessible(true); + forceStopPackage.invoke(activityManager, packageName); + } catch (Exception e) { + Log.e(TAG, "killBackgroundProcesses: " + e.getMessage()); + e.printStackTrace(); + } + } + + public static void killPackage(Context context, String pkg) { + Log.e(TAG, "killPackage: " + pkg); + ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + manager.killBackgroundProcesses(pkg); + CmdUtil.execute("am force-stop " + pkg); + } + + /** + * @param context + * @param className + * @return 判断服务是否存活 + */ + public static boolean isServiceAlice(Context context, String className) { + boolean isServiceRunning = false; + ActivityManager manager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + if (manager == null) { + return false; + } + for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { + if (className.equals(service.service.getClassName())) { + isServiceRunning = true; + } + } + Log.e("ServiceAliveUtils", "className isServiceAlice: " + isServiceRunning); + return isServiceRunning; + } + + + public static void setSystemControl(Context context, SnSetting snSetting) { + int is_control = snSetting.getIs_control(); + if (is_control == 0) { + setUSBstate(context, 0); + setBluetooth(context, 0); + setDeveloperOptions(context, 0); + setCanReset(context, 0); + setActionBar(context, 0); + setNavigationBar(context, 0); + setTF(context, 0); + } else { + int is_storeinstall = snSetting.getIs_storeinstall(); + int is_usb = snSetting.getIs_usb(); + setUSBstate(context, is_usb); + int is_bluetooth_file = snSetting.getIs_bluetooth_file(); + setBluetooth(context, is_bluetooth_file); + int is_developer = snSetting.getIs_developer(); + setDeveloperOptions(context, is_developer); + int is_restore = snSetting.getIs_restore(); + setCanReset(context, is_restore); + int is_topbar = snSetting.getIs_topbar(); + setActionBar(context, is_topbar); + int is_bottombar = snSetting.getIs_bottombar(); + setNavigationBar(context, is_bottombar); + int is_memory_card = snSetting.getIs_memory_card(); + setTF(context, is_memory_card); + } + } + + public static void disableSystemControl(Context context){ + setUSBstate(context, 0); + setBluetooth(context, 0); + setDeveloperOptions(context, 0); + setCanReset(context, 0); + setActionBar(context, 0); + setNavigationBar(context, 0); + setTF(context, 0); + } + /** + * usb连接模式管控 + */ + private static void setUSBstate(Context context, int status) { + //USB数据功能管控 + //仅充电:usb_charge + //MTP模式:usb_mtp + //Midi模式:usb_midi + if (!BuildConfig.DEBUG) { + try { +// boolean qch_usb_choose = Settings.System.putString(context.getContentResolver(), "qch_usb_choose", status); +// Log.e("SystemSetting", "qch_usb_choose:" + qch_usb_choose); + String usbStatus = ""; + switch (status) { + case 0: + usbStatus = CommonConfig.AOLE_ACTION_USB_USB_CHARGE; + break; + case 1: + usbStatus = CommonConfig.AOLE_ACTION_USB_USB_MTP; + break; +// case "usb_midi": +// usbStatus = CommonConfig.AOLE_ACTION_USB_USB_MIDI; +// break; + default: + usbStatus = CommonConfig.AOLE_ACTION_USB_USB_CHARGE; + break; + } + Intent usbIntent = new Intent(usbStatus).setPackage("com.android.settings"); + context.sendBroadcast(usbIntent); + } catch (Exception e) { + Log.e(TAG, "setUSBstate: " + e.getMessage()); + } + } + } + + private static void setBluetooth(Context context, int status) { + boolean aole_bht_forbid_on = Settings.System.putInt(context.getContentResolver(), CommonConfig.AOLE_ACTION_BHT_FORBID_ON, status); + } + + + public static void setDeveloperOptions(Context context, int status) { + Log.e(TAG, "setDeveloperOptions: " + status); + if (!BuildConfig.DEBUG) { + Settings.System.putInt(context.getContentResolver(), "qch_Developeroptions", status); + int old_dev_enabled = Settings.Global.getInt(context.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + Log.e(TAG, "setDeveloperOptions: " + old_dev_enabled); + int new_state = (status == 1 ? 0 : 1); + if (old_dev_enabled != new_state) { + Settings.Global.putInt(context.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, new_state); + Settings.Global.putInt(context.getContentResolver(), Settings.Global.ADB_ENABLED, new_state); + } + Settings.System.putInt(context.getContentResolver(), CommonConfig.AOLE_ACTION_DEVELOPER_OPTIONS, status); + if (status == 1) { + Intent intent = new Intent(); + intent.setAction("qch_developeroptions_close"); + intent.setPackage("com.android.settings"); + context.sendBroadcast(intent); + Log.e(TAG, "setDeveloperOptions: " + "关闭开发者模式"); + ToastUtil.debugShow("关闭开发者模式"); + } else { + Log.e(TAG, "setDeveloperOptions: " + "打开开发者模式"); + ToastUtil.debugShow("打开开发者模式"); + } + } + } + + private static void setCanReset(Context context, int status) { + if (status == 1) { + Settings.System.putInt(context.getContentResolver(), CommonConfig.AOLE_ACTION_RESTORE_FORBID_ON, 0); + } else { + Settings.System.putInt(context.getContentResolver(), CommonConfig.AOLE_ACTION_RESTORE_FORBID_ON, 1); + } + Log.e(TAG, "aole_restore_forbid_on:" + status); + } + + /** + * @param context + * @param status 系统导航条显示开关 + */ + private static void setNavigationBar(Context context, int status) { + boolean aole_hide_NavigationBar = Settings.System.putInt(context.getContentResolver(), CommonConfig.AOLE_ACTION_HIDE_NAVIGATION_BAR, status); + Log.e("SystemSetting", "aole_hide_NavigationBar:" + aole_hide_NavigationBar); + String navigationStatus = ""; + switch (status) { + case 0: + navigationStatus = CommonConfig.AOLE_ACTION_SHOW_NAVIGATION_BAR; + break; + case 1: + navigationStatus = CommonConfig.AOLE_ACTION_HIDE_NAVIGATION_BAR; + break; + default: + } + Intent navIntent = new Intent(navigationStatus).setPackage("com.android.systemui"); + context.sendBroadcast(navIntent); + } + + /** + * @param context + * @param status 状态栏显示开关 + */ + private static void setActionBar(Context context, int status) { + int oldNum = Settings.System.getInt(context.getContentResolver(), CommonConfig.AOLE_ACTION_HIDE_STATUS_BAR, 0); + if (oldNum != status) { + boolean aole_hide_statusBar = Settings.System.putInt(context.getContentResolver(), CommonConfig.AOLE_ACTION_HIDE_STATUS_BAR, status); + Log.e("SystemSetting", "aole_hide_statusBar:" + aole_hide_statusBar); + String statusbarStatus = ""; + switch (status) { + case 0: + statusbarStatus = CommonConfig.AOLE_ACTION_SHOW_STATUS_BAR; + break; + case 1: + statusbarStatus = CommonConfig.AOLE_ACTION_HIDE_STATUS_BAR; + break; + default: + } + Intent statusIntent = new Intent(statusbarStatus).setPackage("com.android.systemui"); + context.sendBroadcast(statusIntent); + } + } + + private static void setTF(Context context, int state) { + try { + //tfmedia开关 +// int setting_tfmedia = 1; + boolean qch_tfmedia_forbid = Settings.System.putInt(context.getContentResolver(), "qch_tfmedia_forbid", state); + Log.e(TAG, "setting_tfmedia---------" + qch_tfmedia_forbid); + String tfmediaStatus = ""; + switch (state) { + case 1: + tfmediaStatus = "qch_tfmedia_open"; + break; + case 0: + default: + tfmediaStatus = "qch_tfmedia_forbid"; + break; + } + Intent tfmediaIntent = new Intent(tfmediaStatus).setPackage("com.android.settings"); + context.sendBroadcast(tfmediaIntent); + if (state == 1) { + boolean qch_tfmedia_filetypes = Settings.System.putString(context.getContentResolver(), "qch_tfmedia_filetypes", "Empty");//影音管控 + Log.e(TAG, "qch_tfmedia_filetypes:" + qch_tfmedia_filetypes); + } else { + Settings.System.putInt(context.getContentResolver(), "qch_tfmedia_forbid", 0); + } + } catch (Exception e) { + Log.e(TAG, "setTF: " + e.getMessage()); + } + } +} diff --git a/app/src/main/java/com/uiuipad/find/util/FileSizeUtil.java b/app/src/main/java/com/uiuipad/find/util/FileSizeUtil.java new file mode 100644 index 0000000..c26eaa9 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/util/FileSizeUtil.java @@ -0,0 +1,136 @@ +package com.uiuipad.find.util; + +import java.io.File; +import java.io.FileInputStream; +import java.text.DecimalFormat; + +public class FileSizeUtil { + private static final String TAG = FileSizeUtil.class.getSimpleName(); + + public static final int SIZETYPE_B = 1;//获取文件大小单位为B的double值 + public static final int SIZETYPE_KB = 2;//获取文件大小单位为KB的double值 + public static final int SIZETYPE_MB = 3;//获取文件大小单位为MB的double值 + public static final int SIZETYPE_GB = 4;//获取文件大小单位为GB的double值 + + /** + * 获取文件指定文件的指定单位的大小 + * + * @param filePath 文件路径 + * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB + * @return double值的大小 + */ + public static double getFileOrFilesSize(String filePath, int sizeType) { + File file = new File(filePath); + long blockSize = 0; + try { + if (file.isDirectory()) { + blockSize = getFileSizes(file); + } else { + blockSize = getFileSize(file); + } + } catch (Exception e) { + e.printStackTrace(); + } + return FormetFileSize(blockSize, sizeType); + } + + /** + * 调用此方法自动计算指定文件或指定文件夹的大小 + * + * @param filePath 文件路径 + * @return 计算好的带B、KB、MB、GB的字符串 + */ + public static String getAutoFileOrFilesSize(String filePath) { + File file = new File(filePath); + long blockSize = 0; + try { + if (file.isDirectory()) { + blockSize = getFileSizes(file); + } else { + blockSize = getFileSize(file); + } + } catch (Exception e) { + e.printStackTrace(); + } + return formatFileSize(blockSize); + } + + /** + * 获取指定文件大小 + */ + private static long getFileSize(File file) throws Exception { + long size = 0; + if (file.exists()) { + FileInputStream fis = null; + fis = new FileInputStream(file); + size = fis.available(); + } else { + file.createNewFile(); + } + return size; + } + + /** + * 获取指定文件夹 + */ + private static long getFileSizes(File f) throws Exception { + long size = 0; + File flist[] = f.listFiles(); + assert flist != null; + for (File file : flist) { + if (file.isDirectory()) { + size = size + getFileSizes(file); + } else { + size = size + getFileSize(file); + } + } + return size; + } + + /** + * 转换文件大小 + */ + public static String formatFileSize(long fileS) { + DecimalFormat df = new DecimalFormat("#"); + String fileSizeString = ""; + String wrongSize = "0B"; + if (fileS == 0) { + return wrongSize; + } + if (fileS < 1024) { + fileSizeString = df.format((double) fileS) + "B"; + } else if (fileS < 1048576) { + fileSizeString = df.format((double) fileS / 1024) + "KB"; + } else if (fileS < 1073741824) { + fileSizeString = df.format((double) fileS / 1048576) + "MB"; + } else { + fileSizeString = df.format((double) fileS / 1073741824) + "GB"; + } + return fileSizeString; + } + + /** + * 转换文件大小,指定转换的类型 + */ + public static double FormetFileSize(long fileS, int sizeType) { + DecimalFormat df = new DecimalFormat("#.00"); + double fileSizeLong = 0; + switch (sizeType) { + case SIZETYPE_B: + fileSizeLong = Double.valueOf(df.format((double) fileS)); + break; + case SIZETYPE_KB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1024)); + break; + case SIZETYPE_MB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576)); + break; + case SIZETYPE_GB: + fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824)); + break; + default: + break; + } + return fileSizeLong; + } +} diff --git a/app/src/main/java/com/uiuipad/find/util/FileUtils.java b/app/src/main/java/com/uiuipad/find/util/FileUtils.java new file mode 100644 index 0000000..3957920 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/util/FileUtils.java @@ -0,0 +1,93 @@ +package com.uiuipad.find.util; + +import android.content.Context; +import android.os.Environment; +import android.util.Log; + +import androidx.core.content.ContextCompat; + +import com.arialyy.aria.core.Aria; +import com.google.gson.JsonObject; + +import java.io.File; +import java.io.FileInputStream; +import java.math.BigInteger; +import java.security.MessageDigest; + +public class FileUtils { + + public static String getDownLoadPath(Context context) { + String path = ContextCompat.getExternalFilesDirs(context, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath(); + return path + File.separator; +} + public static String getFileNamefromURL(String url) { + int position = url.lastIndexOf("/"); + return url.substring(position + 1); + } + + public static String getMD5fromFileName(String fileName) { + int position = fileName.lastIndexOf("/"); + return fileName.substring(position + 9, fileName.length() - 4); + } + + /** + * 获取单个文件的MD5值 + * + * @param file 文件 + * @return + */ + + public static String getFileMD5s(File file) { + if (!file.isFile()) { + return null; + } + MessageDigest digest = null; + FileInputStream in = null; + byte buffer[] = new byte[1024]; + int len; + try { + digest = MessageDigest.getInstance("MD5"); + in = new FileInputStream(file); + while ((len = in.read(buffer, 0, 1024)) != -1) { + digest.update(buffer, 0, len); + } + in.close(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + BigInteger bigInt = new BigInteger(1, digest.digest()); + return bigInt.toString(32); + } + + public static void ariaDownload(Context context, String url, JsonObject jsonObject) { + String fileName = getFileNamefromURL(url); + String urlMD5 = jsonObject.get("app_md5").getAsString(); + Log.e("ariaDownload", "urlMD5=" + urlMD5); + File file = new File(getDownLoadPath(context) + fileName); + if (file.exists() && !file.isDirectory()) { +// String filenameMD5 = getMD5fromFileName(url); + String fileMD5 = getFileMD5s(file); +// Log.e("ariaDownload", "filenameMD5=" + filenameMD5); + Log.e("ariaDownload", "fileMD5=" + fileMD5); + //后端还没有完成json字段的MD5,暂时用文件名获取 + if (fileMD5.equalsIgnoreCase(urlMD5)) { + ApkUtils.installApp(context, file.getAbsolutePath()); + } else { + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(getDownLoadPath(context) + fileName) + .ignoreFilePathOccupy() + .setExtendField(jsonObject.toString()) + .create(); //启动下载} + } + } else { + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(getDownLoadPath(context) + fileName) + .ignoreFilePathOccupy() + .setExtendField(jsonObject.toString()) + .create(); //启动下载} + } + } +} diff --git a/app/src/main/java/com/uiuipad/find/util/TimeUtils.java b/app/src/main/java/com/uiuipad/find/util/TimeUtils.java new file mode 100644 index 0000000..b41acb3 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/util/TimeUtils.java @@ -0,0 +1,675 @@ +package com.uiuipad.find.util; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.SystemClock; +import android.text.TextUtils; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +import com.tencent.mmkv.MMKV; +import com.uiuipad.find.comm.CommonConfig; +import com.uiuipad.find.service.ManagerService; + +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +public class TimeUtils { + private static final String TAG = TimeUtils.class.getSimpleName(); + + private static MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + private static DateFormat df = new SimpleDateFormat("HH:mm", Locale.CHINA); + + public static final long DAY_TIME = 60 * 60 * 24 * 1000; + public static final long MINUTE_TIME = 60 * 1000; + + public static final String START_TIME_KEY = "START_TIME"; + public static final String END_TIME_KEY = "END_TIME"; + public static final String WEEK_START_TIME_KEY = "WEEK_START_TIME"; + public static final String WEEK_END_TIME_KEY = "WEEK_END_TIME"; + + + public static String getNowTime() { + long nowTime = System.currentTimeMillis(); + DateFormat df = ContralTime.getDf(); + return df.format(nowTime); + } + +// public static boolean CurrentInTimeScope(ContralTime contralTime) { +// boolean result = true; +// final long aDayInMillis = 1000 * 60 * 60 * 24; +// long currentTimeMillis = System.currentTimeMillis(); +// +// } + + public static String transferLongToDate(Long millSec) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(millSec); + return sdf.format(date); + } + + public static String transferSecondToDate(long second) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); + Date date = new Date(second * 1000); + return sdf.format(date); + } + + public static String transferSecond(long second) { + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); + sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + Date date = new Date(second * 1000); + return sdf.format(date); + } + + public static String getPhotoDate() { + long millisecond = System.currentTimeMillis(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + Date date = new Date(millisecond); + return sdf.format(date); + } + + private static final long oneDayTimeOfSecond = 24 * 60 * 60; + + public static long timestampInterval(long nowTime, long expireTime) { + long num = expireTime - nowTime;//时间戳相差的毫秒数 + long day = num / oneDayTimeOfSecond; + return day; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public static boolean isTodayTime(long timeStamp) { + String time = transferLongToDate(timeStamp); + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + LocalDateTime localTime = LocalDateTime.parse(time, dtf); + LocalDateTime startTime = LocalDate.now().atTime(0, 0, 0); + LocalDateTime endTime = LocalDate.now().atTime(23, 59, 59); + return localTime.isAfter(startTime) && localTime.isBefore(endTime); + } + + public static ContralTime String2WorkingTime(Context context, @NonNull String timeText) { + DateFormat df = ContralTime.getDf(); + String[] time = timeText.trim().split("-"); + if (time.length != 2) { +// return null; + throw new RuntimeException("Time format error!" + Arrays.toString(time)); + } + try { + mMMKV.encode(START_TIME_KEY, time[0].trim()); + mMMKV.encode(END_TIME_KEY, time[1].trim()); + Date startDate = df.parse(time[0].trim()); + Date endDate = df.parse(time[1].trim()); + ContralTime contralTime = new ContralTime(); +// if (date1.getTime() < date2.getTime()) { + contralTime.setStartTime(df.format(startDate)); + contralTime.setEndTime(df.format(endDate)); +// } else { +// contralTime.setStartTime(df.format(date2)); +// contralTime.setEndTime(df.format(date1)); +// } + return contralTime; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + public static ContralTime String2WeekTime(Context context, @NonNull String timeText) { + DateFormat df = ContralTime.getDf(); + String[] time = timeText.trim().split("-"); + if (time.length != 2) { +// return null; + throw new RuntimeException("Time format error!" + Arrays.toString(time)); + } + try { + mMMKV.encode(WEEK_START_TIME_KEY, time[0].trim()); + mMMKV.encode(WEEK_END_TIME_KEY, time[1].trim()); + Date startDate = df.parse(time[0].trim()); + Date endDate = df.parse(time[1].trim()); + ContralTime contralTime = new ContralTime(); +// if (date1.getTime() < date2.getTime()) { + contralTime.setStartTime(df.format(startDate)); + contralTime.setEndTime(df.format(endDate)); +// } else { +// contralTime.setStartTime(df.format(date2)); +// contralTime.setEndTime(df.format(date1)); +// } + return contralTime; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + public static ContralTime getWorkingDayContralTime(Context context) { + String startTime = mMMKV.decodeString(START_TIME_KEY, "00:00"); + String endTime = mMMKV.decodeString(END_TIME_KEY, "00:00"); + return getContralTime(context, startTime, endTime); + } + + public static ContralTime getWeekDayContralTime(Context context) { + String startTime = mMMKV.decodeString(WEEK_START_TIME_KEY, "00:00"); + String endTime = mMMKV.decodeString(WEEK_END_TIME_KEY, "00:00"); + return getContralTime(context, startTime, endTime); + } + + public static boolean inContralTime(ContralTime workingTime, ContralTime weekTime) { + if (inWeekDay()) { + if (weekTime == null) { + return false; + } else { + return weekTime.inControlTime(); + } + } else { + if (workingTime == null) { + return false; + } else { + return workingTime.inControlTime(); + } + } + } + + public static ContralTime getContralTime(Context context, String startTime, String endTime) { + if (null == startTime || null == endTime || ("00:00".equals(startTime) && "00:00".equals(endTime))) { + return null; + } else { + try { + Date startDate = df.parse(startTime.trim()); + Date endDate = df.parse(endTime.trim()); + ContralTime contralTime = new ContralTime(); + contralTime.setStartTime(df.format(startDate)); + contralTime.setEndTime(df.format(endDate)); + return contralTime; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + } + + public static String getNowTimeString(Context context) { + ContralTime work = getWorkingDayContralTime(context); + ContralTime week = getWeekDayContralTime(context); + StringBuilder stringBuilder = new StringBuilder(); + if (work != null) { + stringBuilder.append("周一至周五:").append(work).append("\n"); + } + if (week != null) { + stringBuilder.append("周末:").append(week); + } + return stringBuilder.toString(); + } + + public static ContralTime String2ContralTime(Context context, @NonNull String timeText) { + DateFormat df = ContralTime.getDf(); + String[] time = timeText.trim().split("-"); + if (time.length != 2) { + throw new RuntimeException("Time format error!"); + } + try { + mMMKV.encode(START_TIME_KEY, time[0].trim()); + mMMKV.encode(END_TIME_KEY, time[1].trim()); + Date startDate = df.parse(time[0].trim()); + Date endDate = df.parse(time[1].trim()); + ContralTime contralTime = new ContralTime(); +// if (date1.getTime() < date2.getTime()) { + contralTime.setStartTime(df.format(startDate)); + contralTime.setEndTime(df.format(endDate)); +// } else { +// contralTime.setStartTime(df.format(date2)); +// contralTime.setEndTime(df.format(date1)); +// } + return contralTime; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + public static ContralTime getDefaltContralTime(Context context) { + String startTime = mMMKV.decodeString(START_TIME_KEY, "00:00"); + String endTime = mMMKV.decodeString(END_TIME_KEY, "00:00"); + if (null == startTime || null == endTime || ("00:00".equals(startTime) && "00:00".equals(endTime))) { + return null; + } else { + try { + Date startDate = df.parse(startTime.trim()); + Date endDate = df.parse(endTime.trim()); + ContralTime contralTime = new ContralTime(); + contralTime.setStartTime(df.format(startDate)); + contralTime.setEndTime(df.format(endDate)); + return contralTime; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + } + + public static void setEmpty(Context context) { + mMMKV.encode(START_TIME_KEY, "00:00"); + mMMKV.encode(END_TIME_KEY, "00:00"); + mMMKV.encode(WEEK_START_TIME_KEY, "00:00"); + mMMKV.encode(WEEK_END_TIME_KEY, "00:00"); + Intent intent = new Intent(); + intent.setAction(ManagerService.ACTION_UPDATE); + context.sendBroadcast(intent); + } + + /** + * 获取格式化后的时间 + * + * @param time 时间戳 + * @return 时间戳格式化文本 + */ + public static String getDate(long time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String finaWayDate = sdf.format(time); + Log.e(TAG, "getDate: " + finaWayDate); + return finaWayDate; + } + + /** + * 获取周几 + * + * @return 周几的数字 + */ + public static int getWeekDay() { + long time = System.currentTimeMillis(); + Log.e(TAG, "getWeekDay: " + time); + return getWeekDay(time); + } + + /** + * 获取周几 + * + * @param time 时间戳 + * @return 周几的数字 1-7 + */ + public static int getWeekDay(long time) { + getDate(time); + Calendar now = Calendar.getInstance(); + now.setTimeInMillis(time); + //一周第一天是否为星期天 + boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY); + //获取周几 + int weekDay = now.get(Calendar.DAY_OF_WEEK); + //若一周第一天为星期天,则-1 + if (isFirstSunday) { + weekDay = weekDay - 1; + if (weekDay == 0) { + weekDay = 7; + } + } + return weekDay; + } + + private String[] weekDays = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"}; + + /** + * 获取星期几 + * + * @return 星期的文本 + */ + public String getWeekDayString() { + return weekDays[getWeekDay() - 1]; + } + + /** + * 获取星期几 + * + * @param time 时间戳 + * @return 星期的文本 + */ + public String getWeekDayString(long time) { + return weekDays[getWeekDay(time) - 1]; + } + + /** + * 是否未周末 + * + * @return 周末返回ture 工作日返回false + */ + public static boolean inWeekDay() { + long time = System.currentTimeMillis(); + return inWeekDay(time); + } + + /** + * 是否未周末 + * + * @param time 时间戳 + * @return 周末返回ture 工作日返回false + */ + public static boolean inWeekDay(long time) { + int weekDay = getWeekDay(time); + if (weekDay > 5) { + return true; + } else { + return false; + } + } + + public static void setSystemTime(long time) { + SystemClock.setCurrentTimeMillis(time); + } + + public static class ContralTime { + //format HH:mm + String startTime; + String endTime; + + public ContralTime() { + + } + + public ContralTime(String startT, String endT) { + this.startTime = startT; + this.endTime = endT; + } + + public String getStartTime() { + return startTime; + } + + + public void setStartTime(String startT) { + this.startTime = startT; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endT) { + this.endTime = endT; + } + + public static DateFormat getDf() { + return df; + } + + public static void setDf(DateFormat d) { + df = d; + } + + public String getNowTimeString(long time) { + return df.format(new Date(time)); + } + + public boolean inControlTime() { + long time = System.currentTimeMillis(); + return inControlTime(time); + } + + public boolean inControlTime(long time) { + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); + return inControlTime(sdf.format(new Date(time))); + } + + public boolean inControlTime(String time) { + if (TextUtils.isEmpty(time)) { + throw new RuntimeException("Time is empty"); + } else { + if (!time.contains(":")) { + throw new RuntimeException("Time format error"); + } + } + try { + Date startDate = df.parse(startTime); + Date endDate = df.parse(endTime); + Date nowDate = df.parse(time); + if (startDate.getTime() > endDate.getTime()) { + //开始时间大于结束时间 列 16:00-01:00 + endDate.setTime(endDate.getTime() + DAY_TIME); + } + Log.e(TAG, "inControlTime: " + (startDate.getTime() - MINUTE_TIME)); + assert nowDate != null; + if (nowDate.getTime() <= startDate.getTime() - MINUTE_TIME || nowDate.getTime() >= endDate.getTime()) { + return true; + } else { + return false; + } + } catch (ParseException e) { + e.printStackTrace(); + } + return false; + } + + @NonNull + @Override + public String toString() { + return startTime + "\t-\t" + endTime; + } + } + + private static SntpClient mNtpClient; + + public static long getTimeFromNtpServer(String hostAddress) { + Log.d(TAG, "getTimeFromNtpServer()"); + if (TextUtils.isEmpty(hostAddress)) { + Log.e(TAG, "Ntp host is null."); + return -1; + } + if (mNtpClient == null) { + mNtpClient = new SntpClient(); + } + boolean isSuccessful = mNtpClient.requestTime(hostAddress, 20000); + Log.e(TAG, "requestTime:" + isSuccessful); + if (isSuccessful) { + long now = mNtpClient.getNtpTime();//now就是获取的时间 + return now; + } else { + + } + return -1; + } + + public static class SntpClient { + private static final String TAG = "SntpClient"; + + private static final int REFERENCE_TIME_OFFSET = 16; + private static final int ORIGINATE_TIME_OFFSET = 24; + private static final int RECEIVE_TIME_OFFSET = 32; + private static final int TRANSMIT_TIME_OFFSET = 40; + private static final int NTP_PACKET_SIZE = 48; + + private static final int NTP_PORT = 123; + private static final int NTP_MODE_CLIENT = 3; + private static final int NTP_VERSION = 3; + + // Number of seconds between Jan 1, 1900 and Jan 1, 1970 + // 70 years plus 17 leap days + private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L; + + // system time computed from NTP server response + private long mNtpTime; + + // value of SystemClock.elapsedRealtime() corresponding to mNtpTime + private long mNtpTimeReference; + + // round trip time in milliseconds + private long mRoundTripTime; + + /** + * Sends an SNTP request to the given host and processes the response. + * + * @param host host name of the server. + * @param timeout network timeout in milliseconds. + * @return true if the transaction was successful. + */ + public boolean requestTime(String host, int timeout) { + DatagramSocket socket = null; + try { + socket = new DatagramSocket(); + socket.setSoTimeout(timeout); + InetAddress address = InetAddress.getByName(host); + byte[] buffer = new byte[NTP_PACKET_SIZE]; + DatagramPacket request = new DatagramPacket(buffer, + buffer.length, address, NTP_PORT); + + // set mode = 3 (client) and version = 3 + // mode is in low 3 bits of first byte + // version is in bits 3-5 of first byte + buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3); + + // get current time and write it to the request packet + long requestTime = System.currentTimeMillis(); + Log.d(TAG, "RequestTime:" + new Date(requestTime)); + long requestTicks = SystemClock.elapsedRealtime(); + writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime); + + socket.send(request); + + // read the response + DatagramPacket response = new DatagramPacket(buffer, + buffer.length); + socket.receive(response); + long responseTicks = SystemClock.elapsedRealtime(); + long responseTime = requestTime + + (responseTicks - requestTicks); + + // extract the results + long originateTime = readTimeStamp(buffer, + ORIGINATE_TIME_OFFSET); + long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET); + long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET); + long roundTripTime = responseTicks - requestTicks + - (transmitTime - receiveTime); + // receiveTime = originateTime + transit + skew + // responseTime = transmitTime + transit - skew + // clockOffset = ((receiveTime - originateTime) + (transmitTime + // - responseTime))/2 + // = ((originateTime + transit + skew - originateTime) + + // (transmitTime - (transmitTime + transit - skew)))/2 + // = ((transit + skew) + (transmitTime - transmitTime - transit + // + skew))/2 + // = (transit + skew - transit + skew)/2 + // = (2 * skew)/2 = skew + long clockOffset = ((receiveTime - requestTime) + (transmitTime - System.currentTimeMillis())) / 2; + // if (false) Log.d(TAG, "round trip: " + roundTripTime + + // " ms"); + // if (false) Log.d(TAG, "clock offset: " + clockOffset + + // " ms"); + + // save our results - use the times on this side of the network + // latency + // (response rather than request time) + mNtpTime = System.currentTimeMillis() + clockOffset; +// mNtpTime = transmitTime; + mNtpTimeReference = responseTicks; + mRoundTripTime = roundTripTime; + } catch (Exception e) { + if (false) + Log.e(TAG, "request time failed:" + e); + e.printStackTrace(); + return false; + } finally { + if (socket != null) { + socket.close(); + } + } + + return true; + } + + /** + * Returns the time computed from the NTP transaction. + * + * @return time value computed from NTP server response. + */ + public long getNtpTime() { + return mNtpTime; + } + + /** + * Returns the reference clock value (value of + * SystemClock.elapsedRealtime()) corresponding to the NTP time. + * + * @return reference clock corresponding to the NTP time. + */ + public long getNtpTimeReference() { + return mNtpTimeReference; + } + + /** + * Returns the round trip time of the NTP transaction + * + * @return round trip time in milliseconds. + */ + public long getRoundTripTime() { + return mRoundTripTime; + } + + /** + * Reads an unsigned 32 bit big endian number from the given offset in + * the buffer. + */ + private long read32(byte[] buffer, int offset) { + byte b0 = buffer[offset]; + byte b1 = buffer[offset + 1]; + byte b2 = buffer[offset + 2]; + byte b3 = buffer[offset + 3]; + + // convert signed bytes to unsigned values + int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0); + int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1); + int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2); + int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3); + + return ((long) i0 << 24) + ((long) i1 << 16) + ((long) i2 << 8) + + (long) i3; + } + + /** + * Reads the NTP time stamp at the given offset in the buffer and + * returns it as a system time (milliseconds since January 1, 1970). + */ + private long readTimeStamp(byte[] buffer, int offset) { + long seconds = read32(buffer, offset); + long fraction = read32(buffer, offset + 4); + return ((seconds - OFFSET_1900_TO_1970) * 1000) + + ((fraction * 1000L) / 0x100000000L); + } + + /** + * Writes system time (milliseconds since January 1, 1970) as an NTP + * time stamp at the given offset in the buffer. + */ + private void writeTimeStamp(byte[] buffer, int offset, long time) { + long seconds = time / 1000L; + long milliseconds = time - seconds * 1000L; + seconds += OFFSET_1900_TO_1970; + + // write seconds in big endian format + buffer[offset++] = (byte) (seconds >> 24); + buffer[offset++] = (byte) (seconds >> 16); + buffer[offset++] = (byte) (seconds >> 8); + buffer[offset++] = (byte) (seconds >> 0); + + long fraction = milliseconds * 0x100000000L / 1000L; + // write fraction in big endian format + buffer[offset++] = (byte) (fraction >> 24); + buffer[offset++] = (byte) (fraction >> 16); + buffer[offset++] = (byte) (fraction >> 8); + // low order bits should be random data + buffer[offset++] = (byte) (Math.random() * 255.0); + } + } +} diff --git a/app/src/main/java/com/uiuipad/find/util/Utils.java b/app/src/main/java/com/uiuipad/find/util/Utils.java index 811bbcb..8fa2976 100644 --- a/app/src/main/java/com/uiuipad/find/util/Utils.java +++ b/app/src/main/java/com/uiuipad/find/util/Utils.java @@ -1,12 +1,28 @@ package com.uiuipad.find.util; import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.Context; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.BatteryManager; import android.os.Build; +import android.os.StatFs; +import android.text.format.Formatter; import android.util.Log; +import java.io.BufferedReader; +import java.io.FileReader; import java.lang.reflect.Method; +import java.util.Iterator; +import java.util.Set; + +import static android.content.Context.WIFI_SERVICE; public class Utils { + private static final String TAG = Utils.class.getSimpleName(); /** * 获取设备序列号 @@ -34,5 +50,165 @@ public class Utils { return serial; } + /** + * @param context + * @return 获取WiFi名 + */ + public static String getWifiSsid(Context context) { + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + if (wifiInfo != null) { + return wifiInfo.getSSID(); + } else { + return ""; + } + } + /** + * @param context + * @return 获取wifi信号 + */ + public static String getWifiRssi(Context context) { + WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE); + WifiInfo info = wifiManager.getConnectionInfo(); + return String.valueOf(info.getRssi()); + } + + /** + * @param context + * @return 获取电池电量 + */ + public static int getBattery(Context context) { + try { + BatteryManager batteryManager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE); + return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); + } catch (Exception e) { + Log.e("getBattery", "getBattery" + e.getMessage()); + } + return 0; + } + + public static String getBluetoothList() { + BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (bluetoothAdapter == null) { + return "没有蓝牙设备"; + } else { + if (!bluetoothAdapter.isEnabled())//判断蓝牙设备是否已开起 + { + return "蓝牙未开启"; +// //开起蓝牙设备 +// Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); +// context.startActivity(intent); + } else { + Set devices = bluetoothAdapter.getBondedDevices(); + StringBuilder stringBuilder = new StringBuilder(); + for (Iterator iterator = devices.iterator(); iterator.hasNext(); ) { + BluetoothDevice device = iterator.next(); + stringBuilder.append(device.getAlias()).append(";"); + } + Log.e(TAG, "getBluetoothList: " + stringBuilder.toString()); + return stringBuilder.toString(); + } + } + } + + + /** + * @param context + * @return 已经使用 + */ + public static long getUsedMemory(Context context) { + ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); + activityManager.getMemoryInfo(memoryInfo); + long freeMem = memoryInfo.totalMem - memoryInfo.availMem; +// Log.e("getHardware", "getFreeMemory: " + freeMem); + return freeMem; + } + + /** + * 描述:获取可用内存. + * + * @param context + * @return + */ + public static long getAvailMemory(Context context) { + // 获取android当前可用内存大小 + ActivityManager activityManager = (ActivityManager) context + .getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); + activityManager.getMemoryInfo(memoryInfo); + // 当前系统可用内存 ,将获得的内存大小规格化 + + return memoryInfo.availMem; + } + + /** + * 描述:总内存. + * + * @param context + * @return + */ + public static long getTotalMemory(Context context) { + // 系统内存信息文件 + String file = "/proc/meminfo"; + String memInfo; + String[] strs; + long memory = 0; + + try { + FileReader fileReader = new FileReader(file); + BufferedReader bufferedReader = new BufferedReader(fileReader, 8192); + // 读取meminfo第一行,系统内存大小 + memInfo = bufferedReader.readLine(); + strs = memInfo.split("\\s+"); +// for (String str : strs) { +// L.d(AppUtil.class, str + "\t"); +// } + // 获得系统总内存,单位KB + memory = Integer.valueOf(strs[1]).intValue(); + bufferedReader.close(); + } catch (Exception e) { + e.printStackTrace(); + } + // Byte转位KB或MB + return memory * 1024; + } + + public static float getUse_space(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long availableSize = sf.getAvailableBytes(); + Log.e(TAG, "getUse_space: availableSize = " + availableSize); + long blockSize = sf.getBlockSize(); + Log.e(TAG, "getUse_space: blockSize = " + blockSize); + long totalBlocks = sf.getBlockCount(); + Log.e(TAG, "getUse_space: totalBlocks = " + totalBlocks); + + return (float) 100.0 * ((blockSize * totalBlocks) - availableSize) / (blockSize * totalBlocks); + } + + public static String getRemnantSize(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long availableSize = sf.getAvailableBytes(); + return FileSizeUtil.formatFileSize(availableSize); + } + + public static String getUsedSize(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long availableSize = sf.getAvailableBytes(); + long blockSize = sf.getBlockSize(); + long totalBlocks = sf.getBlockCount(); + return Formatter.formatFileSize(context, blockSize * totalBlocks - availableSize); + } + + /** + * @param context + * @return 获取rom总大小 + */ + public static String getDataTotalSize(Context context) { + StatFs sf = new StatFs(context.getCacheDir().getAbsolutePath()); + long blockSize = sf.getBlockSize(); + long totalBlocks = sf.getBlockCount(); + return Formatter.formatFileSize(context, blockSize * totalBlocks); + } } diff --git a/app/src/main/java/com/uiuipad/find/util/WakeUpUtils.java b/app/src/main/java/com/uiuipad/find/util/WakeUpUtils.java new file mode 100644 index 0000000..4ff4938 --- /dev/null +++ b/app/src/main/java/com/uiuipad/find/util/WakeUpUtils.java @@ -0,0 +1,119 @@ +package com.uiuipad.find.util; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.KeyguardManager; +import android.content.Context; +import android.os.Build; +import android.os.PowerManager; +import android.util.Log; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.RequiresApi; + +public class WakeUpUtils { + + /** + * 唤醒手机屏幕并解锁 + */ + public static void wakeUpAndUnlock(Activity activity) { + // 获取电源管理器对象 + PowerManager pm = (PowerManager) activity.getApplicationContext() + .getSystemService(Context.POWER_SERVICE); + boolean screenOn = pm.isScreenOn(); + Log.d("WakeScreen0", "screenOn: " + screenOn); + if (!screenOn) { + // 获取PowerManager.WakeLock对象,后面的参数|表示同时传入两个值,最后的是LogCat里用的Tag + @SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wl = pm.newWakeLock( + PowerManager.ACQUIRE_CAUSES_WAKEUP | + PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "bright"); + wl.acquire(10000); // 点亮屏幕 + wl.release(); // 释放 + } + // 屏幕解锁 + KeyguardManager keyguardManager = (KeyguardManager) activity.getApplicationContext() + .getSystemService(Context.KEYGUARD_SERVICE); + KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock("unLock"); + // 屏幕锁定 +// keyguardLock.reenableKeyguard(); + keyguardLock.disableKeyguard(); // 解锁 + unLockScreen(activity); + } + + private static void unLockScreen(Activity activity) { + final Window win = activity.getWindow(); + win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); + + win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON); + } + + /** + * 唤醒手机屏幕并解锁 + */ + @RequiresApi(api = Build.VERSION_CODES.O) + public static void wakeUpAndUnlockScreen(Activity activity) { + + Window win = activity.getWindow(); + win.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); + + PowerManager pm = (PowerManager) activity.getSystemService(Context.POWER_SERVICE); + @SuppressLint("InvalidWakeLockTag") + PowerManager.WakeLock wakelock = pm.newWakeLock( + PowerManager.FULL_WAKE_LOCK + | PowerManager.ACQUIRE_CAUSES_WAKEUP, "xx"); + wakelock.acquire(); + wakelock.release(); + + KeyguardManager keyguardManager = (KeyguardManager) activity.getApplicationContext() + .getSystemService(Context.KEYGUARD_SERVICE); + + if (activity == null) return; + keyguardManager.requestDismissKeyguard(activity, new KeyguardManager.KeyguardDismissCallback() { + @Override + public void onDismissError() { + super.onDismissError(); + Log.d("xxx-->", "1 onDismissError"); + } + + @Override + public void onDismissSucceeded() { + super.onDismissSucceeded(); + Log.d("xxx-->", "1 onDismissSucceeded"); + } + + @Override + public void onDismissCancelled() { + super.onDismissCancelled(); + Log.d("xxx-->", "1 onDismissCancelled"); + } + }); + + if (activity == null) return; + keyguardManager.requestDismissKeyguard(activity, new KeyguardManager.KeyguardDismissCallback() { + @Override + public void onDismissError() { + super.onDismissError(); + Log.d("xxx-->", "2 onDismissError"); + } + + @Override + public void onDismissSucceeded() { + super.onDismissSucceeded(); + Log.d("xxx-->", "2 onDismissSucceeded"); + } + + @Override + public void onDismissCancelled() { + super.onDismissCancelled(); + Log.d("xxx-->", "2 onDismissCancelled"); + } + }); + + } +} diff --git a/app/src/main/res/drawable-hdpi/control_background.png b/app/src/main/res/drawable-hdpi/control_background.png new file mode 100644 index 0000000..b9b512c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/control_background.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_default_avatar.png b/app/src/main/res/drawable-hdpi/icon_default_avatar.png new file mode 100644 index 0000000..3bcf44e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_default_avatar.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_lock.png b/app/src/main/res/drawable-hdpi/icon_lock.png new file mode 100644 index 0000000..72f6fcb Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_lock.png differ diff --git a/app/src/main/res/drawable-hdpi/wechat_qrcode.jpg b/app/src/main/res/drawable-hdpi/wechat_qrcode.jpg new file mode 100644 index 0000000..4fbf9fc Binary files /dev/null and b/app/src/main/res/drawable-hdpi/wechat_qrcode.jpg differ diff --git a/app/src/main/res/drawable/bt_activation_normnl.xml b/app/src/main/res/drawable/bt_activation_normnl.xml new file mode 100644 index 0000000..d3b209b --- /dev/null +++ b/app/src/main/res/drawable/bt_activation_normnl.xml @@ -0,0 +1,15 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index 6e21235..df69e6f 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -93,12 +93,13 @@ android:background="@drawable/card_background"> + app:layout_constraintBottom_toBottomOf="@+id/iv_avatar" + app:layout_constraintStart_toEndOf="@+id/iv_avatar" + app:layout_constraintTop_toTopOf="@+id/iv_avatar"> - - -