version:6.4.6
fix: update:增加护眼模式,增加静默拍照,增加时间管控和专注模式
This commit is contained in:
@@ -29,8 +29,8 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.aoleyun.sn"
|
applicationId "com.aoleyun.sn"
|
||||||
versionCode 84
|
versionCode 86
|
||||||
versionName "6.4.4"
|
versionName "6.4.6"
|
||||||
|
|
||||||
//There are no CERT files because If the mini sdk version is 23+, the AGP will ignore the V1 scheme signature.
|
//There are no CERT files because If the mini sdk version is 23+, the AGP will ignore the V1 scheme signature.
|
||||||
minSdkVersion 24
|
minSdkVersion 24
|
||||||
@@ -436,6 +436,7 @@ dependencies {
|
|||||||
// // kotlin扩展(可选)
|
// // kotlin扩展(可选)
|
||||||
// implementation 'com.gyf.immersionbar:immersionbar-ktx:3.0.0'
|
// implementation 'com.gyf.immersionbar:immersionbar-ktx:3.0.0'
|
||||||
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.24'
|
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.24'
|
||||||
|
implementation 'com.facebook.rebound:rebound:0.3.8'
|
||||||
}
|
}
|
||||||
|
|
||||||
preBuild {
|
preBuild {
|
||||||
|
|||||||
@@ -149,6 +149,21 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".activity.EyeProtectionActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:icon="@drawable/com_system_huyan"
|
||||||
|
android:label="护眼模式"
|
||||||
|
android:launchMode="singleInstance"
|
||||||
|
android:screenOrientation="userLandscape"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.checknet.CheckNetActivity"
|
android:name=".activity.checknet.CheckNetActivity"
|
||||||
android:theme="@style/activity_styles">
|
android:theme="@style/activity_styles">
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package com.aoleyun.sn.activity;
|
||||||
|
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
|
|
||||||
|
import com.aoleyun.sn.R;
|
||||||
|
import com.aoleyun.sn.base.BaseActivity;
|
||||||
|
import com.aoleyun.sn.utils.ToastUtil;
|
||||||
|
import com.aoleyun.sn.view.ToggleButton;
|
||||||
|
|
||||||
|
import butterknife.BindView;
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
|
public class EyeProtectionActivity extends BaseActivity {
|
||||||
|
|
||||||
|
@BindView(R.id.cl_exit)
|
||||||
|
ConstraintLayout cl_exit;
|
||||||
|
@BindView(R.id.toggleButton1)
|
||||||
|
ToggleButton toggleButton1;
|
||||||
|
@BindView(R.id.toggleButton2)
|
||||||
|
ToggleButton toggleButton2;
|
||||||
|
@BindView(R.id.toggleButton3)
|
||||||
|
ToggleButton toggleButton3;
|
||||||
|
@BindView(R.id.toggleButton4)
|
||||||
|
ToggleButton toggleButton4;
|
||||||
|
@BindView(R.id.toggleButton5)
|
||||||
|
ToggleButton toggleButton5;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLayoutId() {
|
||||||
|
return R.layout.activity_eye_protection;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initView() {
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
int nightDisplay = Settings.Secure.getInt(getContentResolver(), Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 0);
|
||||||
|
if (nightDisplay == 1) {
|
||||||
|
toggleButton1.setToggleOn();
|
||||||
|
} else {
|
||||||
|
toggleButton1.setToggleOff();
|
||||||
|
}
|
||||||
|
toggleButton1.setOnToggleChanged(new ToggleButton.OnToggleChanged() {
|
||||||
|
@Override
|
||||||
|
public void onToggle(boolean on) {
|
||||||
|
Settings.Secure.putInt(getContentResolver(), Settings.Secure.NIGHT_DISPLAY_ACTIVATED, on ? 1 : 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int accessibilityDisplay = Settings.Secure.getInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
|
||||||
|
if (accessibilityDisplay == 1) {
|
||||||
|
toggleButton2.setToggleOn();
|
||||||
|
} else {
|
||||||
|
toggleButton2.setToggleOff();
|
||||||
|
}
|
||||||
|
toggleButton2.setOnToggleChanged(new ToggleButton.OnToggleChanged() {
|
||||||
|
@Override
|
||||||
|
public void onToggle(boolean on) {
|
||||||
|
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, on ? 1 : 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toggleButton3.setDisable(true);
|
||||||
|
toggleButton3.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
ToastUtil.show("此功能暂未开放");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toggleButton4.setDisable(true);
|
||||||
|
toggleButton4.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
ToastUtil.show("此功能暂未开放");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toggleButton5.setDisable(true);
|
||||||
|
toggleButton5.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
ToastUtil.show("此功能暂未开放");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cl_exit.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,8 +16,10 @@ public class MainAContact {
|
|||||||
void getQrCode(boolean loocked);
|
void getQrCode(boolean loocked);
|
||||||
/*获取学生信息*/
|
/*获取学生信息*/
|
||||||
void getStudesInfo();
|
void getStudesInfo();
|
||||||
//获取电子书包激活码
|
/*获取电子书包激活码*/
|
||||||
void getEBagCode();
|
void getEBagCode();
|
||||||
|
/*获取学习应用*/
|
||||||
|
void getExclusiveAdminApp();
|
||||||
/*获取公网ip*/
|
/*获取公网ip*/
|
||||||
void getPublicIp();
|
void getPublicIp();
|
||||||
/*手动获取设备信息更新*/
|
/*手动获取设备信息更新*/
|
||||||
@@ -37,8 +39,10 @@ public class MainAContact {
|
|||||||
void setQrCode(Bitmap qrcode);
|
void setQrCode(Bitmap qrcode);
|
||||||
/*获取学生信息*/
|
/*获取学生信息*/
|
||||||
void setStudesInfo(StudentsInfo studesInfo);
|
void setStudesInfo(StudentsInfo studesInfo);
|
||||||
//获取电子书包激活码
|
/*获取电子书包激活码*/
|
||||||
void getEBagCodeFinish();
|
void getEBagCodeFinish(boolean activation);
|
||||||
|
/*获取学习应用*/
|
||||||
|
void getExclusiveAdminAppFinish();
|
||||||
/*获取公网ip*/
|
/*获取公网ip*/
|
||||||
void setPublicIp(String ip);
|
void setPublicIp(String ip);
|
||||||
/*手动获取设备信息更新*/
|
/*手动获取设备信息更新*/
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import android.util.Log;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.aoleyun.sn.BuildConfig;
|
import com.aoleyun.sn.BuildConfig;
|
||||||
|
import com.aoleyun.sn.bean.AdminAppInfo;
|
||||||
import com.aoleyun.sn.bean.AppUpdateInfo;
|
import com.aoleyun.sn.bean.AppUpdateInfo;
|
||||||
import com.aoleyun.sn.bean.BaseResponse;
|
import com.aoleyun.sn.bean.BaseResponse;
|
||||||
import com.aoleyun.sn.bean.StudentsInfo;
|
import com.aoleyun.sn.bean.StudentsInfo;
|
||||||
@@ -24,6 +25,8 @@ import com.google.gson.JsonParser;
|
|||||||
import com.trello.rxlifecycle4.RxLifecycle;
|
import com.trello.rxlifecycle4.RxLifecycle;
|
||||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.rxjava3.annotations.NonNull;
|
import io.reactivex.rxjava3.annotations.NonNull;
|
||||||
import io.reactivex.rxjava3.core.Observer;
|
import io.reactivex.rxjava3.core.Observer;
|
||||||
@@ -114,11 +117,47 @@ public class MainAPresenter implements MainAContact.Presenter {
|
|||||||
NetInterfaceManager.getInstance().getEBagCode(true, getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
NetInterfaceManager.getInstance().getEBagCode(true, getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {
|
||||||
mView.getEBagCodeFinish();
|
mView.getEBagCodeFinish(Settings.Global.getInt(mContext.getContentResolver(), CommonConfig.UIUI_ACTIVATION_KEY, 0) == 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getExclusiveAdminApp() {
|
||||||
|
NetInterfaceManager.getInstance().getExclusiveAdminAppObservable()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||||
|
.subscribe(new Observer<BaseResponse<List<AdminAppInfo>>>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@NonNull Disposable d) {
|
||||||
|
Log.e("getAdminApp", "onSubscribe: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@NonNull BaseResponse<List<AdminAppInfo>> listBaseResponse) {
|
||||||
|
Log.e("getAdminApp", "onNext: " + listBaseResponse);
|
||||||
|
if (listBaseResponse.code == 200) {
|
||||||
|
List<AdminAppInfo> adminAppInfos = listBaseResponse.data;
|
||||||
|
JGYUtils.getInstance().installAdminApp(adminAppInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull Throwable e) {
|
||||||
|
Log.e("getAdminApp", "onError: " + e.getMessage());
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
Log.e("getAdminApp", "onComplete: ");
|
||||||
|
mView.getExclusiveAdminAppFinish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getPublicIp() {
|
public void getPublicIp() {
|
||||||
NetInterfaceManager.getInstance().getPublicIp(lifecycle, ip -> mView.setPublicIp(ip));
|
NetInterfaceManager.getInstance().getPublicIp(lifecycle, ip -> mView.setPublicIp(ip));
|
||||||
|
|||||||
@@ -429,8 +429,18 @@ public class MainActivity extends BaseActivity implements MainAContact.MainView,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getEBagCodeFinish() {
|
public void getEBagCodeFinish(boolean activation) {
|
||||||
|
if (activation){
|
||||||
|
mMainAPresenter.getExclusiveAdminApp();
|
||||||
|
Log.e(TAG, "getEBagCodeFinish: "+"已激活" );
|
||||||
|
}else {
|
||||||
|
Log.e(TAG, "getEBagCodeFinish: "+"未激活" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getExclusiveAdminAppFinish() {
|
||||||
|
Log.e(TAG, "getAdminAppFinish: " );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -204,8 +204,10 @@ public class BaseApplication extends MultiDexApplication {
|
|||||||
switch (code){
|
switch (code){
|
||||||
case "PUSH_20101":
|
case "PUSH_20101":
|
||||||
aliyunPushInit();
|
aliyunPushInit();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
setAlias();
|
setAlias();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
197
app/src/main/java/com/aoleyun/sn/bean/AdminAppInfo.java
Normal file
197
app/src/main/java/com/aoleyun/sn/bean/AdminAppInfo.java
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
package com.aoleyun.sn.bean;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class AdminAppInfo implements Serializable {
|
||||||
|
private static final long serialVersionUID = -4152412763486673833L;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
String app_name;
|
||||||
|
String app_img;
|
||||||
|
String app_developer;
|
||||||
|
long app_size;
|
||||||
|
String app_package;
|
||||||
|
String app_version_name;
|
||||||
|
long app_version_code;
|
||||||
|
String app_md5;
|
||||||
|
float app_score;
|
||||||
|
String app_preview1;
|
||||||
|
String app_preview2;
|
||||||
|
String app_preview3;
|
||||||
|
String app_url;
|
||||||
|
String app_remarks;
|
||||||
|
String app_desc;
|
||||||
|
int is_promote;
|
||||||
|
int weight;
|
||||||
|
String discount;
|
||||||
|
String use_type;
|
||||||
|
int is_autodown;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_name() {
|
||||||
|
return app_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_name(String app_name) {
|
||||||
|
this.app_name = app_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_img() {
|
||||||
|
return app_img;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_img(String app_img) {
|
||||||
|
this.app_img = app_img;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_developer() {
|
||||||
|
return app_developer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_developer(String app_developer) {
|
||||||
|
this.app_developer = app_developer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getApp_size() {
|
||||||
|
return app_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_size(long app_size) {
|
||||||
|
this.app_size = app_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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_preview1() {
|
||||||
|
return app_preview1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_preview1(String app_preview1) {
|
||||||
|
this.app_preview1 = app_preview1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_preview2() {
|
||||||
|
return app_preview2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_preview2(String app_preview2) {
|
||||||
|
this.app_preview2 = app_preview2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_preview3() {
|
||||||
|
return app_preview3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_preview3(String app_preview3) {
|
||||||
|
this.app_preview3 = app_preview3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_url() {
|
||||||
|
return app_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_url(String app_url) {
|
||||||
|
this.app_url = app_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_remarks() {
|
||||||
|
return app_remarks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_remarks(String app_remarks) {
|
||||||
|
this.app_remarks = app_remarks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApp_desc() {
|
||||||
|
return app_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApp_desc(String app_desc) {
|
||||||
|
this.app_desc = app_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIs_promote() {
|
||||||
|
return is_promote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIs_promote(int is_promote) {
|
||||||
|
this.is_promote = is_promote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWeight(int weight) {
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiscount() {
|
||||||
|
return discount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiscount(String discount) {
|
||||||
|
this.discount = discount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUse_type() {
|
||||||
|
return use_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUse_type(String use_type) {
|
||||||
|
this.use_type = use_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIs_autodown() {
|
||||||
|
return is_autodown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIs_autodown(int is_autodown) {
|
||||||
|
this.is_autodown = is_autodown;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
app/src/main/java/com/aoleyun/sn/bean/SnSetting.java
Normal file
62
app/src/main/java/com/aoleyun/sn/bean/SnSetting.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package com.aoleyun.sn.bean;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
public class SnSetting implements Serializable {
|
||||||
|
private static final long serialVersionUID = -1984636328774813651L;
|
||||||
|
|
||||||
|
int id;
|
||||||
|
int is_timecontrol;
|
||||||
|
String timecontrol_start;
|
||||||
|
String timecontrol_end;
|
||||||
|
int is_storeinstall;
|
||||||
|
int is_usb;
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,7 +60,10 @@ public class CommonConfig {
|
|||||||
public final static String DEVICES_TAG = "Aoleyun_devices_tpush_tag";
|
public final static String DEVICES_TAG = "Aoleyun_devices_tpush_tag";
|
||||||
/*上次获取标签的时间*/
|
/*上次获取标签的时间*/
|
||||||
public final static String GET_DEVICES_TAG_LASTTIME = "Aoleyun_devices_tag_last_time";
|
public final static String GET_DEVICES_TAG_LASTTIME = "Aoleyun_devices_tag_last_time";
|
||||||
|
/*专注模式刷新*/
|
||||||
|
public static final String FOCUS_MODE_REFRESH_KEY = "AOLEYUN_FOCUS_MODE_REFRESH";
|
||||||
|
/*应用市场允许安装*/
|
||||||
|
public static final String AOLEYUN_APPSTORE_INSTALL = "AOLEYUN_APPSTORE_INSTALL_KEY";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import com.alibaba.sdk.android.push.CommonCallback;
|
|||||||
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
|
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
|
||||||
import com.aoleyun.sn.BuildConfig;
|
import com.aoleyun.sn.BuildConfig;
|
||||||
import com.aoleyun.sn.base.BaseApplication;
|
import com.aoleyun.sn.base.BaseApplication;
|
||||||
|
import com.aoleyun.sn.bean.AdminAppInfo;
|
||||||
import com.aoleyun.sn.bean.AppAttr;
|
import com.aoleyun.sn.bean.AppAttr;
|
||||||
import com.aoleyun.sn.bean.AppDateInfo;
|
import com.aoleyun.sn.bean.AppDateInfo;
|
||||||
import com.aoleyun.sn.bean.AppID;
|
import com.aoleyun.sn.bean.AppID;
|
||||||
@@ -41,6 +42,7 @@ import com.aoleyun.sn.bean.NetAndLaunchBean;
|
|||||||
import com.aoleyun.sn.bean.PoweroffBean;
|
import com.aoleyun.sn.bean.PoweroffBean;
|
||||||
import com.aoleyun.sn.bean.ScreenLockState;
|
import com.aoleyun.sn.bean.ScreenLockState;
|
||||||
import com.aoleyun.sn.bean.SnRunLog;
|
import com.aoleyun.sn.bean.SnRunLog;
|
||||||
|
import com.aoleyun.sn.bean.SnSetting;
|
||||||
import com.aoleyun.sn.bean.SnTimeControl;
|
import com.aoleyun.sn.bean.SnTimeControl;
|
||||||
import com.aoleyun.sn.bean.StudentsInfo;
|
import com.aoleyun.sn.bean.StudentsInfo;
|
||||||
import com.aoleyun.sn.bean.TopApp;
|
import com.aoleyun.sn.bean.TopApp;
|
||||||
@@ -55,6 +57,7 @@ import com.aoleyun.sn.gson.NullStringToEmptyAdapterFactory;
|
|||||||
import com.aoleyun.sn.manager.ConnectManager;
|
import com.aoleyun.sn.manager.ConnectManager;
|
||||||
import com.aoleyun.sn.manager.ConnectMode;
|
import com.aoleyun.sn.manager.ConnectMode;
|
||||||
import com.aoleyun.sn.network.api.GetWhoisApi;
|
import com.aoleyun.sn.network.api.GetWhoisApi;
|
||||||
|
import com.aoleyun.sn.network.api.aolelearn.ExclusiveAdminAppApi;
|
||||||
import com.aoleyun.sn.network.api.get.CheckTestUpdateApi;
|
import com.aoleyun.sn.network.api.get.CheckTestUpdateApi;
|
||||||
import com.aoleyun.sn.network.api.get.DefaultAppApi;
|
import com.aoleyun.sn.network.api.get.DefaultAppApi;
|
||||||
import com.aoleyun.sn.network.api.get.DesktopsDiyUpdateApi;
|
import com.aoleyun.sn.network.api.get.DesktopsDiyUpdateApi;
|
||||||
@@ -67,6 +70,7 @@ import com.aoleyun.sn.network.api.get.GetWiFiAliasApi;
|
|||||||
import com.aoleyun.sn.network.api.get.LogoImgApi;
|
import com.aoleyun.sn.network.api.get.LogoImgApi;
|
||||||
import com.aoleyun.sn.network.api.get.ScreenLockStateApi;
|
import com.aoleyun.sn.network.api.get.ScreenLockStateApi;
|
||||||
import com.aoleyun.sn.network.api.get.SnAppAttrApi;
|
import com.aoleyun.sn.network.api.get.SnAppAttrApi;
|
||||||
|
import com.aoleyun.sn.network.api.get.SnSettingApi;
|
||||||
import com.aoleyun.sn.network.api.get.SnTimeControlApi;
|
import com.aoleyun.sn.network.api.get.SnTimeControlApi;
|
||||||
import com.aoleyun.sn.network.api.get.TopAppControlApi;
|
import com.aoleyun.sn.network.api.get.TopAppControlApi;
|
||||||
import com.aoleyun.sn.network.api.post.AppLimitApi;
|
import com.aoleyun.sn.network.api.post.AppLimitApi;
|
||||||
@@ -181,6 +185,10 @@ public class NetInterfaceManager {
|
|||||||
private Context mContext;
|
private Context mContext;
|
||||||
private Retrofit mRetrofit;
|
private Retrofit mRetrofit;
|
||||||
private OkHttpClient okHttpClient;
|
private OkHttpClient okHttpClient;
|
||||||
|
|
||||||
|
private Retrofit mAolelearnRetrofit;
|
||||||
|
private OkHttpClient mAolelearnOkHttpClient;
|
||||||
|
|
||||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||||
private CacheHelper cacheHelper;
|
private CacheHelper cacheHelper;
|
||||||
|
|
||||||
@@ -318,6 +326,29 @@ public class NetInterfaceManager {
|
|||||||
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mAolelearnOkHttpClient == 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 = mContext.getExternalCacheDir().getAbsolutePath() + "/OkHttpCache";
|
||||||
|
Cache cache = new Cache(new File(cacheDirectory), cacheSize);
|
||||||
|
builder.cache(cache);// 设置缓存
|
||||||
|
mAolelearnOkHttpClient = builder.build();
|
||||||
|
}
|
||||||
|
if (mAolelearnRetrofit == null) {
|
||||||
|
mAolelearnRetrofit = new Retrofit.Builder()
|
||||||
|
.client(mAolelearnOkHttpClient)
|
||||||
|
.baseUrl(UrlAddress.AOLELEARN_ROOT)
|
||||||
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
|
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init(Context context) {
|
public static void init(Context context) {
|
||||||
@@ -340,6 +371,18 @@ public class NetInterfaceManager {
|
|||||||
return okHttpClient;
|
return okHttpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取学习软件
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Observable<BaseResponse<List<AdminAppInfo>>> getExclusiveAdminAppObservable() {
|
||||||
|
return mAolelearnRetrofit.create(ExclusiveAdminAppApi.class)
|
||||||
|
.getAdminApp()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过sn获取设备的信息
|
* 通过sn获取设备的信息
|
||||||
*
|
*
|
||||||
@@ -390,7 +433,8 @@ public class NetInterfaceManager {
|
|||||||
mMMKV.decodeString(WHOIS_ADDR, "未知"),
|
mMMKV.decodeString(WHOIS_ADDR, "未知"),
|
||||||
NetworkUtils.getNetworkType(mContext),
|
NetworkUtils.getNetworkType(mContext),
|
||||||
NetworkUtils.getOperators(mContext),
|
NetworkUtils.getOperators(mContext),
|
||||||
NetworkUtils.getPhoneNumber(mContext)
|
NetworkUtils.getPhoneNumber(mContext),
|
||||||
|
Utils.getDensityDpi(mContext)
|
||||||
)
|
)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread());
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
@@ -618,6 +662,13 @@ public class NetInterfaceManager {
|
|||||||
.observeOn(AndroidSchedulers.mainThread());
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Observable<BaseResponse<SnSetting>> getSnSettingObservable() {
|
||||||
|
return mRetrofit.create(SnSettingApi.class)
|
||||||
|
.getSnSetting(Utils.getSerial(mContext))
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* API
|
* API
|
||||||
@@ -3150,7 +3201,7 @@ public class NetInterfaceManager {
|
|||||||
.subscribe(getSnTimeObserver(null));
|
.subscribe(getSnTimeObserver(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Observer getSnTimeObserver(onCompleteCallback callback) {
|
private Observer<BaseResponse<SnTimeControl>> getSnTimeObserver(onCompleteCallback callback) {
|
||||||
return new Observer<BaseResponse<SnTimeControl>>() {
|
return new Observer<BaseResponse<SnTimeControl>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSubscribe(@NonNull Disposable d) {
|
public void onSubscribe(@NonNull Disposable d) {
|
||||||
@@ -3858,4 +3909,85 @@ public class NetInterfaceManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getSnSetting(BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) {
|
||||||
|
getSnSettingObservable()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY))
|
||||||
|
.subscribe(getSnSettingObserver(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getSnSetting(onCompleteCallback callback) {
|
||||||
|
getSnSettingObservable()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(getSnSettingObserver(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getSnSetting() {
|
||||||
|
getSnSettingObservable()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(getSnSettingObserver(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observer<BaseResponse<SnSetting>> getSnSettingObserver(onCompleteCallback callback) {
|
||||||
|
return new Observer<BaseResponse<SnSetting>>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@NonNull Disposable d) {
|
||||||
|
Log.e("getSnSetting", "onSubscribe: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@NonNull BaseResponse<SnSetting> snSettingBaseResponse) {
|
||||||
|
Log.e("getSnSetting", "onNext: " + snSettingBaseResponse);
|
||||||
|
if (snSettingBaseResponse.code == OK) {
|
||||||
|
SnSetting snSetting = snSettingBaseResponse.data;
|
||||||
|
int is_timecontrol = snSetting.getIs_timecontrol();
|
||||||
|
int is_storeinstall = snSetting.getIs_storeinstall();
|
||||||
|
Settings.Global.putInt(mContext.getContentResolver(), CommonConfig.AOLEYUN_APPSTORE_INSTALL, is_storeinstall);
|
||||||
|
if (is_timecontrol == 0) {
|
||||||
|
TimeUtils.setEmpty(mContext);
|
||||||
|
TimeUtils.ContralTime c = TimeUtils.getDefaltContralTime(mContext);
|
||||||
|
if (null != c) {
|
||||||
|
Log.e("getTimeControl", c.toString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String start_time = snSetting.getTimecontrol_start();
|
||||||
|
String end_time = snSetting.getTimecontrol_end();
|
||||||
|
TimeUtils.ContralTime c = TimeUtils.String2ContralTime(mContext, start_time + "-" + end_time);
|
||||||
|
if (null != c) {
|
||||||
|
Log.e("getTimeControl", "OK:" + c.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TimeUtils.setEmpty(mContext);
|
||||||
|
TimeUtils.ContralTime c = TimeUtils.getDefaltContralTime(mContext);
|
||||||
|
if (null != c) {
|
||||||
|
Log.e("getTimeControl", c.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull Throwable e) {
|
||||||
|
Log.e("getSnSetting", "onError: " + e.getMessage());
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
Log.e("getSnSetting", "onComplete: ");
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setAction(MainService.TimeChangedReceiver.ACTION_UPDATE);
|
||||||
|
mContext.sendBroadcast(intent);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ package com.aoleyun.sn.network;
|
|||||||
* @author Administrator
|
* @author Administrator
|
||||||
*/
|
*/
|
||||||
public class UrlAddress {
|
public class UrlAddress {
|
||||||
|
/*学习机*/
|
||||||
|
public static final String AOLELEARN_ROOT = "https://led.aolelearn.com/android/";
|
||||||
|
/*获取专属应用*/
|
||||||
|
public static final String GET_EXCLUSIVE_ADMIN_APP = "getExclusiveAdminApp";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备管控信息
|
* 设备管控信息
|
||||||
@@ -32,6 +36,8 @@ public class UrlAddress {
|
|||||||
public static final String GET_ALL_APP = "recommend/index";
|
public static final String GET_ALL_APP = "recommend/index";
|
||||||
/*强制安装应用*/
|
/*强制安装应用*/
|
||||||
public static final String GET_FORCE_INSTALL_LIST = "forceinstall/index";
|
public static final String GET_FORCE_INSTALL_LIST = "forceinstall/index";
|
||||||
|
/**/
|
||||||
|
|
||||||
/*通过固件名获取内置应用*/
|
/*通过固件名获取内置应用*/
|
||||||
public static final String GET_ROM_APP = "And/getFirmwareApp";
|
public static final String GET_ROM_APP = "And/getFirmwareApp";
|
||||||
/*获取应用升级自启*/
|
/*获取应用升级自启*/
|
||||||
@@ -78,7 +84,8 @@ public class UrlAddress {
|
|||||||
public static final String SEND_BATTERY_INFO = "And/sn/updateBatteryInfo";
|
public static final String SEND_BATTERY_INFO = "And/sn/updateBatteryInfo";
|
||||||
/*上传联网时间*/
|
/*上传联网时间*/
|
||||||
public static final String NETWORK_CONNECT = "And/network";
|
public static final String NETWORK_CONNECT = "And/network";
|
||||||
|
/*获取设备时间管控*/
|
||||||
|
public static final String GET_SN_SETTING = "And/control/getSnSetting";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,9 +120,8 @@ public class UrlAddress {
|
|||||||
public static final String GET_LOGO_IMG = "Sn/getLogoImg";
|
public static final String GET_LOGO_IMG = "Sn/getLogoImg";
|
||||||
/*获取默认桌面升级*/
|
/*获取默认桌面升级*/
|
||||||
public static final String GET_DESKTOP = "Sn/getSnDesktop";
|
public static final String GET_DESKTOP = "Sn/getSnDesktop";
|
||||||
/*获取DIY桌面升级*/
|
/*获取自定义桌面升级*/
|
||||||
public static final String GET_DESKTOPS_DIY_UPDATE = "Sn/getDesktopsDiyUpdate";
|
public static final String GET_DESKTOPS_DIY_UPDATE = "Sn/getDesktopsDiyUpdate";
|
||||||
|
|
||||||
/*获取系统默认程序*/
|
/*获取系统默认程序*/
|
||||||
public static final String GET_DEFAULT_APP = "app/getDefaultApp";
|
public static final String GET_DEFAULT_APP = "app/getDefaultApp";
|
||||||
|
|
||||||
@@ -138,7 +144,6 @@ public class UrlAddress {
|
|||||||
public static final String UPLOAD_IS_LOG_FILE = "And/sn/uploadIsLogFile";
|
public static final String UPLOAD_IS_LOG_FILE = "And/sn/uploadIsLogFile";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*通过ip获取信息*/
|
/*通过ip获取信息*/
|
||||||
public static final String PCONLINE_WHOIS = "http://whois.pconline.com.cn/";
|
public static final String PCONLINE_WHOIS = "http://whois.pconline.com.cn/";
|
||||||
public static final String WHOIS = "ipJson.jsp";
|
public static final String WHOIS = "ipJson.jsp";
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.aoleyun.sn.network.api.aolelearn;
|
||||||
|
|
||||||
|
import com.aoleyun.sn.bean.AdminAppInfo;
|
||||||
|
import com.aoleyun.sn.bean.BaseResponse;
|
||||||
|
import com.aoleyun.sn.network.UrlAddress;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import retrofit2.http.GET;
|
||||||
|
|
||||||
|
public interface ExclusiveAdminAppApi {
|
||||||
|
@GET(UrlAddress.GET_EXCLUSIVE_ADMIN_APP)
|
||||||
|
Observable<BaseResponse<List<AdminAppInfo>>> getAdminApp();
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.aoleyun.sn.network.api.get;
|
||||||
|
|
||||||
|
import com.aoleyun.sn.bean.BaseResponse;
|
||||||
|
import com.aoleyun.sn.bean.SnSetting;
|
||||||
|
import com.aoleyun.sn.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<BaseResponse<SnSetting>> getSnSetting(
|
||||||
|
@Query("sn") String sn
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ public interface MACAddressApi {
|
|||||||
@Field("wifi_operator") String wifi_operator,
|
@Field("wifi_operator") String wifi_operator,
|
||||||
@Field("network_type") String network_type,
|
@Field("network_type") String network_type,
|
||||||
@Field("network_operator") String network_operator,
|
@Field("network_operator") String network_operator,
|
||||||
@Field("sn_phone") String sn_phone
|
@Field("sn_phone") String sn_phone,
|
||||||
|
@Field("dpi") int dpi
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
@@ -37,12 +39,14 @@ import com.aoleyun.sn.service.main.MainService;
|
|||||||
import com.aoleyun.sn.utils.ApkUtils;
|
import com.aoleyun.sn.utils.ApkUtils;
|
||||||
import com.aoleyun.sn.utils.BatteryUtils;
|
import com.aoleyun.sn.utils.BatteryUtils;
|
||||||
import com.aoleyun.sn.utils.CacheUtils;
|
import com.aoleyun.sn.utils.CacheUtils;
|
||||||
|
import com.aoleyun.sn.utils.Camera2BackgroundUtil;
|
||||||
import com.aoleyun.sn.utils.CmdUtil;
|
import com.aoleyun.sn.utils.CmdUtil;
|
||||||
import com.aoleyun.sn.utils.ForegroundAppUtil;
|
import com.aoleyun.sn.utils.ForegroundAppUtil;
|
||||||
import com.aoleyun.sn.utils.JGYUtils;
|
import com.aoleyun.sn.utils.JGYUtils;
|
||||||
import com.aoleyun.sn.utils.MySQLData;
|
import com.aoleyun.sn.utils.MySQLData;
|
||||||
import com.aoleyun.sn.utils.SPUtils;
|
import com.aoleyun.sn.utils.SPUtils;
|
||||||
import com.aoleyun.sn.utils.ServiceAliveUtils;
|
import com.aoleyun.sn.utils.ServiceAliveUtils;
|
||||||
|
import com.aoleyun.sn.utils.TimeUtils;
|
||||||
import com.aoleyun.sn.utils.ToastUtil;
|
import com.aoleyun.sn.utils.ToastUtil;
|
||||||
import com.aoleyun.sn.utils.Utils;
|
import com.aoleyun.sn.utils.Utils;
|
||||||
import com.arialyy.aria.core.Aria;
|
import com.arialyy.aria.core.Aria;
|
||||||
@@ -204,6 +208,14 @@ public class PushManager {
|
|||||||
private static final String INFO_BATTERY_INFO = "53";
|
private static final String INFO_BATTERY_INFO = "53";
|
||||||
/*判断是否更新桌面*/
|
/*判断是否更新桌面*/
|
||||||
private static final String UPDATE_DESKTOP = "56";
|
private static final String UPDATE_DESKTOP = "56";
|
||||||
|
/*前置拍照*/
|
||||||
|
private static final String TAKE_FRONT_PICTURE = "58";
|
||||||
|
/*时间管控*/
|
||||||
|
private static final String TIME_CONTROL2 = "59";
|
||||||
|
/*usb传输*/
|
||||||
|
private static final String USB_CONTROL = "61";
|
||||||
|
/*专注模式*/
|
||||||
|
private static final String FOCUS_MODE = "62";
|
||||||
|
|
||||||
public void setPushContent(String title, String extras) {
|
public void setPushContent(String title, String extras) {
|
||||||
switch (title) {
|
switch (title) {
|
||||||
@@ -436,9 +448,9 @@ public class PushManager {
|
|||||||
break;
|
break;
|
||||||
case LOCK_SCREEN:
|
case LOCK_SCREEN:
|
||||||
ToastUtil.betaShow("收到管控:屏幕锁定");
|
ToastUtil.betaShow("收到管控:屏幕锁定");
|
||||||
JsonObject lockJSONObject = GsonUtils.getJsonObject(extras);
|
// JsonObject lockJSONObject = GsonUtils.getJsonObject(extras);
|
||||||
String name = lockJSONObject.get("name").getAsString();
|
// String name = lockJSONObject.get("name").getAsString();
|
||||||
setLock_screen(1, name);
|
setLock_screen(1, "锁屏管控中");
|
||||||
break;
|
break;
|
||||||
case UNLOCK_SCREEN:
|
case UNLOCK_SCREEN:
|
||||||
ToastUtil.betaShow("收到管控:屏幕解锁");
|
ToastUtil.betaShow("收到管控:屏幕解锁");
|
||||||
@@ -535,10 +547,68 @@ public class PushManager {
|
|||||||
case UPDATE_DESKTOP:
|
case UPDATE_DESKTOP:
|
||||||
NetInterfaceManager.getInstance().getDefaultDesktop();
|
NetInterfaceManager.getInstance().getDefaultDesktop();
|
||||||
break;
|
break;
|
||||||
|
case TAKE_FRONT_PICTURE:
|
||||||
|
ToastUtil.betaShow("收到推送消息: 截图");
|
||||||
|
long createTime = System.currentTimeMillis() / 1000;
|
||||||
|
Camera2BackgroundUtil camera2BackgroundUtil = new Camera2BackgroundUtil(mContext, new Camera2BackgroundUtil.CameraCallBack() {
|
||||||
|
@Override
|
||||||
|
public void onErr(String msg) {
|
||||||
|
Log.e("camera2BackgroundUtil", "onErr: " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTakePhotoOk(String path) {
|
||||||
|
Log.e("camera2BackgroundUtil", "onTakePhotoOk: " + path);
|
||||||
|
File file = new File(path);
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeFile(path);
|
||||||
|
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<String, String> params = new HashMap<>();
|
||||||
|
params.put("sn", Utils.getSerial(mContext));
|
||||||
|
params.put("createtime", String.valueOf(createTime));
|
||||||
|
Call<BaseResponse> call = NetInterfaceManager.getInstance().getScreenshotCall().sendScreenshot(params, body);
|
||||||
|
call.enqueue(new RetryCallback<BaseResponse>(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: ");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
camera2BackgroundUtil.startTakePicture(mContext.getExternalCacheDir().getAbsolutePath() + File.separator + TimeUtils.getPhotoDate() + ".jpg");
|
||||||
|
break;
|
||||||
|
case TIME_CONTROL2:
|
||||||
|
case USB_CONTROL:
|
||||||
|
NetInterfaceManager.getInstance().getSnSetting();
|
||||||
|
break;
|
||||||
|
case FOCUS_MODE:
|
||||||
|
refreshFocusMode();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshFocusMode() {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
// ComponentName componentName = new ComponentName("com.aoleyunos.dop6", "com.aoleyunos.dop6.service.main.MainService");
|
||||||
|
// intent.setComponent(componentName);
|
||||||
|
intent.setAction(CommonConfig.FOCUS_MODE_REFRESH_KEY);
|
||||||
|
mContext.sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
private void deleteApp(String extras) {
|
private void deleteApp(String extras) {
|
||||||
if (!TextUtils.isEmpty(extras)) {
|
if (!TextUtils.isEmpty(extras)) {
|
||||||
JsonObject jsonObject = GsonUtils.getJsonObject(extras);
|
JsonObject jsonObject = GsonUtils.getJsonObject(extras);
|
||||||
|
|||||||
@@ -80,8 +80,11 @@ public class MainSContact {
|
|||||||
void getPoweroffTime();
|
void getPoweroffTime();
|
||||||
/*获取时间管控*/
|
/*获取时间管控*/
|
||||||
void getSnTimeControl();
|
void getSnTimeControl();
|
||||||
|
void getSnSetting();
|
||||||
/*获取电子书包激活码*/
|
/*获取电子书包激活码*/
|
||||||
void getEbagCode();
|
void getEbagCode();
|
||||||
|
/*获取学习应用*/
|
||||||
|
void getExclusiveAdminApp();
|
||||||
/*获取wifi密码*/
|
/*获取wifi密码*/
|
||||||
void getWiFiPasswd();
|
void getWiFiPasswd();
|
||||||
}
|
}
|
||||||
@@ -154,8 +157,11 @@ public class MainSContact {
|
|||||||
void setPoweroffTime();
|
void setPoweroffTime();
|
||||||
/*获取时间管控*/
|
/*获取时间管控*/
|
||||||
void getSnTimeControlFinish();
|
void getSnTimeControlFinish();
|
||||||
|
void getSnSettingFinish();
|
||||||
/*获取电子书包激活码*/
|
/*获取电子书包激活码*/
|
||||||
void getEbagCodeFinish();
|
void getEbagCodeFinish(boolean activation);
|
||||||
|
/*获取学习应用*/
|
||||||
|
void getExclusiveAdminAppFinish();
|
||||||
/*获取wifi密码结束*/
|
/*获取wifi密码结束*/
|
||||||
void setWiFiPasswd();
|
void setWiFiPasswd();
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import android.util.Log;
|
|||||||
import com.alibaba.sdk.android.push.CloudPushService;
|
import com.alibaba.sdk.android.push.CloudPushService;
|
||||||
import com.alibaba.sdk.android.push.CommonCallback;
|
import com.alibaba.sdk.android.push.CommonCallback;
|
||||||
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
|
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
|
||||||
|
import com.aoleyun.sn.bean.AdminAppInfo;
|
||||||
import com.aoleyun.sn.bean.BaseResponse;
|
import com.aoleyun.sn.bean.BaseResponse;
|
||||||
import com.aoleyun.sn.bean.StudentsInfo;
|
import com.aoleyun.sn.bean.StudentsInfo;
|
||||||
import com.aoleyun.sn.comm.CommonConfig;
|
import com.aoleyun.sn.comm.CommonConfig;
|
||||||
@@ -31,9 +32,11 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.rxjava3.annotations.NonNull;
|
import io.reactivex.rxjava3.annotations.NonNull;
|
||||||
import io.reactivex.rxjava3.core.Observer;
|
import io.reactivex.rxjava3.core.Observer;
|
||||||
import io.reactivex.rxjava3.disposables.Disposable;
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -355,12 +358,12 @@ public class MainSPresenter implements MainSContact.Presenter {
|
|||||||
public void getDefaultDesktop() {
|
public void getDefaultDesktop() {
|
||||||
Log.e(TAG, "getDefaultDesktop: ");
|
Log.e(TAG, "getDefaultDesktop: ");
|
||||||
if (JGYUtils.isOfficialVersion() || !JGYUtils.getInstance().getDeviceIsLocked()) {
|
if (JGYUtils.isOfficialVersion() || !JGYUtils.getInstance().getDeviceIsLocked()) {
|
||||||
Log.e(TAG, "getDefaultDesktop: "+"Device unLocked");
|
Log.e(TAG, "getDefaultDesktop: " + "Device unLocked");
|
||||||
mView.getDefaultDesktopFinish();
|
mView.getDefaultDesktopFinish();
|
||||||
} else {
|
} else {
|
||||||
int aihuaUnlock = Settings.System.getInt(mContext.getContentResolver(), CommonConfig.AIHUA_UNLOCK, 0);
|
int aihuaUnlock = Settings.System.getInt(mContext.getContentResolver(), CommonConfig.AIHUA_UNLOCK, 0);
|
||||||
if (JGYUtils.getInstance().isAihuaFramwwork() && aihuaUnlock == 1) {
|
if (JGYUtils.getInstance().isAihuaFramwwork() && aihuaUnlock == 1) {
|
||||||
Log.e(TAG, "getDefaultDesktop: "+"Device aihua");
|
Log.e(TAG, "getDefaultDesktop: " + "Device aihua");
|
||||||
mView.getDefaultDesktopFinish();
|
mView.getDefaultDesktopFinish();
|
||||||
} else {
|
} else {
|
||||||
NetInterfaceManager.getInstance()
|
NetInterfaceManager.getInstance()
|
||||||
@@ -420,7 +423,7 @@ public class MainSPresenter implements MainSContact.Presenter {
|
|||||||
@Override
|
@Override
|
||||||
public void getDesktopIcon() {
|
public void getDesktopIcon() {
|
||||||
NetInterfaceManager.getInstance()
|
NetInterfaceManager.getInstance()
|
||||||
.getDesktopIcon( getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
.getDesktopIcon(getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {
|
||||||
Log.e("getDesktopIcon", "onComplete: ");
|
Log.e("getDesktopIcon", "onComplete: ");
|
||||||
@@ -539,13 +542,58 @@ public class MainSPresenter implements MainSContact.Presenter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getSnSetting() {
|
||||||
|
NetInterfaceManager.getInstance().getSnSetting(getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
mView.getSnSettingFinish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getEbagCode() {
|
public void getEbagCode() {
|
||||||
NetInterfaceManager.getInstance()
|
NetInterfaceManager.getInstance()
|
||||||
.getEBagCode(true, getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
.getEBagCode(true, getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {
|
||||||
mView.getEbagCodeFinish();
|
mView.getEbagCodeFinish(Settings.Global.getInt(mContext.getContentResolver(), CommonConfig.UIUI_ACTIVATION_KEY, 0) == 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getExclusiveAdminApp() {
|
||||||
|
NetInterfaceManager.getInstance().getExclusiveAdminAppObservable()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||||
|
.subscribe(new Observer<BaseResponse<List<AdminAppInfo>>>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@NonNull Disposable d) {
|
||||||
|
Log.e("getAdminApp", "onSubscribe: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@NonNull BaseResponse<List<AdminAppInfo>> listBaseResponse) {
|
||||||
|
Log.e("getAdminApp", "onNext: " + listBaseResponse);
|
||||||
|
if (listBaseResponse.code == 200) {
|
||||||
|
List<AdminAppInfo> adminAppInfos = listBaseResponse.data;
|
||||||
|
JGYUtils.getInstance().installAdminApp(adminAppInfos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull Throwable e) {
|
||||||
|
Log.e("getAdminApp", "onError: " + e.getMessage());
|
||||||
|
onComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
Log.e("getAdminApp", "onComplete: ");
|
||||||
|
mView.getExclusiveAdminAppFinish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1133,11 +1133,28 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getSnTimeControlFinish() {
|
public void getSnTimeControlFinish() {
|
||||||
|
mPresenter.getSnSetting();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getSnSettingFinish() {
|
||||||
mPresenter.getEbagCode();
|
mPresenter.getEbagCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getEbagCodeFinish() {
|
public void getEbagCodeFinish(boolean activation) {
|
||||||
|
if (activation){
|
||||||
|
mPresenter.getExclusiveAdminApp();
|
||||||
|
Log.e(TAG, "getEBagCodeFinish: "+"已激活" );
|
||||||
|
}else {
|
||||||
|
mPresenter.getWiFiPasswd();
|
||||||
|
Log.e(TAG, "getEBagCodeFinish: "+"未激活" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getExclusiveAdminAppFinish() {
|
||||||
|
Log.e(TAG, "getAdminAppFinish: " );
|
||||||
mPresenter.getWiFiPasswd();
|
mPresenter.getWiFiPasswd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,568 @@
|
|||||||
|
package com.aoleyun.sn.utils;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.ImageFormat;
|
||||||
|
import android.graphics.SurfaceTexture;
|
||||||
|
import android.hardware.Camera;
|
||||||
|
import android.hardware.camera2.CameraAccessException;
|
||||||
|
import android.hardware.camera2.CameraCaptureSession;
|
||||||
|
import android.hardware.camera2.CameraCharacteristics;
|
||||||
|
import android.hardware.camera2.CameraDevice;
|
||||||
|
import android.hardware.camera2.CameraManager;
|
||||||
|
import android.hardware.camera2.CaptureRequest;
|
||||||
|
import android.hardware.camera2.TotalCaptureResult;
|
||||||
|
import android.hardware.camera2.params.StreamConfigurationMap;
|
||||||
|
import android.media.Image;
|
||||||
|
import android.media.ImageReader;
|
||||||
|
import android.media.MediaRecorder;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Size;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @作者 Liushihua
|
||||||
|
* @创建时间 2021-2-3 10:54
|
||||||
|
* @描述
|
||||||
|
*/
|
||||||
|
public class Camera2BackgroundUtil {
|
||||||
|
private static final String TAG = Camera2BackgroundUtil.class.getSimpleName();
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
private CameraCallBack cameraCallBack;
|
||||||
|
private CameraManager cameraManager;
|
||||||
|
// 默认相机id是0 LENS_FACING_FRONT,LENS_FACING_BACK
|
||||||
|
private int cameraId = CameraCharacteristics.LENS_FACING_FRONT;
|
||||||
|
private CameraDevice mCameraDevice;
|
||||||
|
private String savePath;
|
||||||
|
|
||||||
|
private CaptureRequest.Builder mPreviewRequestBuilder;
|
||||||
|
private CameraCaptureSession mCameraCaptureSession;
|
||||||
|
private CaptureRequest request;
|
||||||
|
private ExecutorService service;
|
||||||
|
private boolean isTakedPicture = false;//是否已经拍照
|
||||||
|
|
||||||
|
private int needSetOrientation = 0;// 设置默认的拍照方向
|
||||||
|
private boolean isInitOk = false;// 是否初始化成功
|
||||||
|
private boolean isSessionClosed = true;// captureSession是否被关闭
|
||||||
|
private boolean isCameraDoing = false;// 是否正在使用相机
|
||||||
|
private final long CAPTURE_DELAY_TIME_LONG = 1200;// 延时拍照——聚焦需要时间
|
||||||
|
|
||||||
|
private final int HANDLER_ERR = 3;// 拍照失败
|
||||||
|
private final int HANDLER_TAKE_PHOTO_SUCCESS = 5;// 拍照成功
|
||||||
|
private List<Integer> enableCameraList;//可用摄像头列表
|
||||||
|
private boolean mFlashSupported = false;//是否支持闪光灯
|
||||||
|
private List<Size> recordSizeList;// 录制尺寸
|
||||||
|
private Size mPreviewOutputSize;// 预览尺寸
|
||||||
|
private List<Size> imgOutputSizes;// 拍照尺寸
|
||||||
|
|
||||||
|
private final int PREVIEW_TYPE_NORMAL = 0;// 默认预览
|
||||||
|
private final int PREVIEW_TYPE_RECORD = 1;// 录屏预览
|
||||||
|
private final int PREVIEW_TYPE_TAKE_PHOTO = 2;// 拍照预览
|
||||||
|
private int previewType = 0;//默认预览
|
||||||
|
|
||||||
|
private boolean mTakePictureFinish = false;
|
||||||
|
|
||||||
|
private long lastSaveFileTime = 0;
|
||||||
|
|
||||||
|
public interface CameraCallBack {
|
||||||
|
void onErr(String msg);
|
||||||
|
|
||||||
|
void onTakePhotoOk(String path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理静态图片的输出
|
||||||
|
*/
|
||||||
|
private ImageReader imageReader;
|
||||||
|
|
||||||
|
private Handler handler = new Handler(Looper.getMainLooper()) {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
super.handleMessage(msg);
|
||||||
|
switch (msg.what) {
|
||||||
|
case HANDLER_ERR:
|
||||||
|
cameraCallBack.onErr("" + msg.obj);
|
||||||
|
isCameraDoing = false;
|
||||||
|
break;
|
||||||
|
case HANDLER_TAKE_PHOTO_SUCCESS:
|
||||||
|
if (!mTakePictureFinish) {
|
||||||
|
cameraCallBack.onTakePhotoOk(savePath);
|
||||||
|
mTakePictureFinish = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当相机设备的状态发生改变的时候,将会回调。
|
||||||
|
*/
|
||||||
|
protected final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
|
||||||
|
/**
|
||||||
|
* 当相机打开的时候,调用
|
||||||
|
* @param cameraDevice
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onOpened(@NonNull CameraDevice cameraDevice) {
|
||||||
|
Log.e(TAG, "onOpened");
|
||||||
|
mCameraDevice = cameraDevice;
|
||||||
|
startPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
|
||||||
|
Log.e(TAG, "onDisconnected");
|
||||||
|
cameraDevice.close();
|
||||||
|
mCameraDevice = null;
|
||||||
|
Message message = new Message();
|
||||||
|
message.what = HANDLER_ERR;
|
||||||
|
message.obj = "后台相机断开连接";
|
||||||
|
handler.sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发生异常的时候调用
|
||||||
|
*
|
||||||
|
* 这里释放资源,然后关闭界面
|
||||||
|
* @param cameraDevice
|
||||||
|
* @param error
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onError(@NonNull CameraDevice cameraDevice, int error) {
|
||||||
|
Log.e(TAG, "onError 相机设备异常,请重启!");
|
||||||
|
cameraDevice.close();
|
||||||
|
mCameraDevice = null;
|
||||||
|
Message messagef = new Message();
|
||||||
|
messagef.what = HANDLER_ERR;
|
||||||
|
messagef.obj = "相机设备异常,请重启!";
|
||||||
|
handler.sendMessage(messagef);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*当相机被关闭的时候
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onClosed(@NonNull CameraDevice camera) {
|
||||||
|
super.onClosed(camera);
|
||||||
|
Log.e(TAG, "onClosed");
|
||||||
|
mCameraDevice = null;
|
||||||
|
isCameraDoing = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相机状态回调
|
||||||
|
*/
|
||||||
|
private CameraManager.AvailabilityCallback callback = new CameraManager.AvailabilityCallback() {
|
||||||
|
@Override
|
||||||
|
public void onCameraAvailable(@NonNull String cameraId) {// 相机可用
|
||||||
|
super.onCameraAvailable(cameraId);
|
||||||
|
Log.e(TAG, "相机可用");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCameraUnavailable(@NonNull String cameraId) {// 相机不可用
|
||||||
|
super.onCameraUnavailable(cameraId);
|
||||||
|
Log.e(TAG, "相机不可用");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化
|
||||||
|
*
|
||||||
|
* @param activity
|
||||||
|
* @param cameraCallBack 回调
|
||||||
|
*/
|
||||||
|
public Camera2BackgroundUtil(Context activity, @NonNull CameraCallBack cameraCallBack) {
|
||||||
|
this.context = activity;
|
||||||
|
this.cameraCallBack = cameraCallBack;
|
||||||
|
cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
|
||||||
|
// 对于静态图片,使用可用的最大值来拍摄。
|
||||||
|
if (cameraManager != null) {
|
||||||
|
isInitOk = true;
|
||||||
|
cameraManager.registerAvailabilityCallback(callback, null);
|
||||||
|
getCameraInfo();
|
||||||
|
setupImageReader();
|
||||||
|
service = Executors.newSingleThreadExecutor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupImageReader() {
|
||||||
|
// Size size = getOutputSize(imgOutputSizes);
|
||||||
|
//前三个参数分别是需要的尺寸和格式,最后一个参数代表每次最多获取几帧数据,本例的3代表ImageReader中最多可以获取2帧图像流
|
||||||
|
imageReader = ImageReader.newInstance(1600, 1200, ImageFormat.JPEG, 1);
|
||||||
|
//监听ImageReader的事件,当有图像流数据可用时会回调onImageAvailable方法,它的参数就是预览帧数据,可以对这帧数据进行处理
|
||||||
|
imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
|
||||||
|
@Override
|
||||||
|
public void onImageAvailable(ImageReader reader) {
|
||||||
|
Image image = reader.acquireLatestImage();
|
||||||
|
//我们可以将这帧数据转成字节数组,类似于Camera1的PreviewCallback回调的预览帧数据
|
||||||
|
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
|
||||||
|
byte[] data = new byte[buffer.remaining()];
|
||||||
|
buffer.get(data);
|
||||||
|
image.close();
|
||||||
|
saveFile(data, savePath);
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开相机
|
||||||
|
*/
|
||||||
|
private void openCamera() {
|
||||||
|
cameraId = getFrontCameraId();
|
||||||
|
Log.e(TAG, "openCamera: getFrontCameraId = " + getFrontCameraId());
|
||||||
|
Log.e(TAG, "openCamera:" + cameraId);
|
||||||
|
isCameraDoing = true;
|
||||||
|
// 设置TextureView的缓冲区大小
|
||||||
|
// 获取Surface显示预览数据
|
||||||
|
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Message message = new Message();
|
||||||
|
message.what = HANDLER_ERR;
|
||||||
|
message.obj = "权限不足";
|
||||||
|
handler.sendMessage(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cameraManager.openCamera(Integer.toString(cameraId), stateCallback, null);
|
||||||
|
Log.e(TAG, "打开相机成功!");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "打开相机失败-Exception:" + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
Message messagef = new Message();
|
||||||
|
messagef.what = HANDLER_ERR;
|
||||||
|
messagef.obj = "打开相机失败";
|
||||||
|
handler.sendMessage(messagef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getFrontCameraId() {
|
||||||
|
int numberOfCameras = Camera.getNumberOfCameras();
|
||||||
|
for (int i = 0; i < numberOfCameras; i++) {
|
||||||
|
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
|
||||||
|
Camera.getCameraInfo(i, cameraInfo);
|
||||||
|
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始视频录制预览
|
||||||
|
*/
|
||||||
|
private void startPreview() {
|
||||||
|
Log.e(TAG, "startPreview");
|
||||||
|
// CaptureRequest添加imageReaderSurface,不加的话就会导致ImageReader的onImageAvailable()方法不会回调
|
||||||
|
// 创建CaptureSession时加上imageReaderSurface,如下,这样预览数据就会同时输出到previewSurface和imageReaderSurface了
|
||||||
|
try {
|
||||||
|
// 创建CaptureRequestBuilder,TEMPLATE_PREVIEW比表示预览请求
|
||||||
|
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
|
||||||
|
mPreviewRequestBuilder.addTarget(imageReader.getSurface());// 设置Surface作为预览数据的显示界面
|
||||||
|
// 创建相机捕获会话,第一个参数是捕获数据的输出Surface列表,第二个参数是CameraCaptureSession的状态回调接口,当它创建好后会回调onConfigured方法,第三个参数用来确定Callback在哪个线程执行,为null的话就在当前线程执行
|
||||||
|
mCameraDevice.createCaptureSession(Arrays.asList(imageReader.getSurface()), captureSessionStateCallBack, null);
|
||||||
|
} catch (CameraAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Message messagef = new Message();
|
||||||
|
messagef.what = HANDLER_ERR;
|
||||||
|
messagef.obj = "捕获帧失败";
|
||||||
|
handler.sendMessage(messagef);
|
||||||
|
Log.e(TAG, "Camera获取成功,创建录制请求或捕获Session失败" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获图片数据
|
||||||
|
*/
|
||||||
|
private CameraCaptureSession.StateCallback captureSessionStateCallBack = new CameraCaptureSession.StateCallback() {
|
||||||
|
@Override
|
||||||
|
public void onConfigured(CameraCaptureSession session) {
|
||||||
|
try {
|
||||||
|
mCameraCaptureSession = session;
|
||||||
|
isSessionClosed = false;
|
||||||
|
request = mPreviewRequestBuilder.build();
|
||||||
|
// 设置反复捕获数据的请求,这样预览界面就会一直有数据显示
|
||||||
|
mCameraCaptureSession.setRepeatingRequest(request, null, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Message messagef = new Message();
|
||||||
|
messagef.what = HANDLER_ERR;
|
||||||
|
messagef.obj = "开启图像预览失败";
|
||||||
|
handler.sendMessage(messagef);
|
||||||
|
}
|
||||||
|
if (!isTakedPicture) {
|
||||||
|
isTakedPicture = true;
|
||||||
|
handler.postDelayed(() -> takePicture(), CAPTURE_DELAY_TIME_LONG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfigureFailed(CameraCaptureSession session) {
|
||||||
|
Log.e(TAG, "onConfigureFailed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public void startTakePicture(String savePath) {
|
||||||
|
Log.e(TAG, "拍照:" + savePath);
|
||||||
|
this.savePath = savePath;
|
||||||
|
if (isCameraDoing) {
|
||||||
|
Log.e(TAG, "相机使用中...");
|
||||||
|
} else {
|
||||||
|
isTakedPicture = false;
|
||||||
|
openCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拍照
|
||||||
|
*/
|
||||||
|
private void takePicture() {
|
||||||
|
Log.e(TAG, "takePicture");
|
||||||
|
try {
|
||||||
|
if (mCameraDevice == null || mPreviewRequestBuilder == null) return;
|
||||||
|
mPreviewRequestBuilder.addTarget(imageReader.getSurface());
|
||||||
|
//设置拍照方向
|
||||||
|
mPreviewRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, this.needSetOrientation);
|
||||||
|
//这个回调接口用于拍照结束时重启预览,因为拍照会导致预览停止
|
||||||
|
CameraCaptureSession.CaptureCallback mImageSavedCallback = new CameraCaptureSession.CaptureCallback() {
|
||||||
|
@Override
|
||||||
|
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
|
||||||
|
Log.e(TAG, "拍照完成");
|
||||||
|
onStop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//开始拍照,然后回调上面的接口重启预览,因为mCaptureBuilder设置ImageReader作为target,所以会自动回调ImageReader的onImageAvailable()方法保存图片
|
||||||
|
mCameraCaptureSession.capture(mPreviewRequestBuilder.build(), mImageSavedCallback, null);
|
||||||
|
} catch (CameraAccessException e) {
|
||||||
|
Log.e(TAG, "takePhoto CameraAccessException:" + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
Message messagef = new Message();
|
||||||
|
messagef.what = HANDLER_ERR;
|
||||||
|
messagef.obj = "拍照失败";
|
||||||
|
handler.sendMessage(messagef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止预览,释放资源
|
||||||
|
*/
|
||||||
|
public void stopRecord() {
|
||||||
|
Log.e(TAG, "停止预览,释放资源");
|
||||||
|
try {
|
||||||
|
if (mCameraCaptureSession != null && !isSessionClosed) {
|
||||||
|
mCameraCaptureSession.stopRepeating();
|
||||||
|
mCameraCaptureSession.abortCaptures();
|
||||||
|
mCameraCaptureSession.close();
|
||||||
|
isSessionClosed = true;
|
||||||
|
imageReader.close();
|
||||||
|
imageReader = null;
|
||||||
|
}
|
||||||
|
if (mCameraDevice != null)
|
||||||
|
mCameraDevice.close();
|
||||||
|
isCameraDoing = false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "stopRecord-Exception:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置后,开始预览
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
previewType = PREVIEW_TYPE_NORMAL;
|
||||||
|
stopRecord();
|
||||||
|
openCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在 activity,fragment的onStop中调用
|
||||||
|
*/
|
||||||
|
public void onStop() {
|
||||||
|
stopRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注销 回调
|
||||||
|
*/
|
||||||
|
public void onDestroy() {
|
||||||
|
this.cameraCallBack = null;
|
||||||
|
if (cameraManager != null)
|
||||||
|
cameraManager.unregisterAvailabilityCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得可用的摄像头
|
||||||
|
*
|
||||||
|
* @return SparseArray of available cameras ids。key为摄像头方位,见CameraCharacteristics#LENS_FACING,value为对应的摄像头id
|
||||||
|
*/
|
||||||
|
public void getCameras() {
|
||||||
|
if (cameraManager == null) return;
|
||||||
|
enableCameraList = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
String[] camerasAvailable = cameraManager.getCameraIdList();
|
||||||
|
CameraCharacteristics cam;
|
||||||
|
Integer characteristic;
|
||||||
|
Log.e(TAG, "-------------------------------------");
|
||||||
|
for (String id : camerasAvailable) {
|
||||||
|
Log.e(TAG, "getCameras:" + id);
|
||||||
|
try {
|
||||||
|
enableCameraList.add(Integer.parseInt(id));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.e(TAG, "-------------------------------------");
|
||||||
|
} catch (CameraAccessException e) {
|
||||||
|
Log.e(TAG, "getCameras CameraAccessException:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置输出数据尺寸选择器,在selectCamera之前设置有效
|
||||||
|
* (一般手机支持多种输出尺寸,请用户根据自身需要选择最合适的一种)
|
||||||
|
* 举例:
|
||||||
|
* SizeSelector maxPreview = SizeSelectors.and(SizeSelectors.maxWidth(720), SizeSelectors.maxHeight(480));
|
||||||
|
* SizeSelector minPreview = SizeSelectors.and(SizeSelectors.minWidth(320), SizeSelectors.minHeight(240));
|
||||||
|
* camera.setmOutputSizeSelector(SizeSelectors.or(
|
||||||
|
* SizeSelectors.and(maxPreview, minPreview)//先在最大和最小中寻找
|
||||||
|
* , SizeSelectors.and(maxPreview, SizeSelectors.biggest())//找不到则按不超过最大尺寸的那个选择
|
||||||
|
* ));
|
||||||
|
*/
|
||||||
|
public void getOutputSizeSelector() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取摄像头信息
|
||||||
|
*/
|
||||||
|
public void getCameraInfo() {
|
||||||
|
if (enableCameraList == null) {
|
||||||
|
getCameras();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CameraCharacteristics mCameraCharacteristics = cameraManager.getCameraCharacteristics(String.valueOf(cameraId));
|
||||||
|
// 设置是否支持闪光灯
|
||||||
|
Boolean available = mCameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
|
||||||
|
mFlashSupported = available == null ? false : available;
|
||||||
|
StreamConfigurationMap map = mCameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
|
||||||
|
if (map == null) {
|
||||||
|
Log.e(TAG, "Could not get configuration map.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int mSensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);//这个方法来获取CameraSensor的方向。
|
||||||
|
Log.e(TAG, "camera sensor orientation:" + mSensorOrientation + ",display rotation=" + context.getDisplay().getRotation());
|
||||||
|
|
||||||
|
int[] formats = map.getOutputFormats();//获得手机支持的输出格式,其中jpeg是一定会支持的,yuv_420_888是api21才开始支持的
|
||||||
|
for (int format : formats) {
|
||||||
|
Log.e(TAG, "手机格式支持: " + format);
|
||||||
|
}
|
||||||
|
Size[] yuvOutputSizes = map.getOutputSizes(ImageFormat.YUV_420_888);
|
||||||
|
Size[] mediaOutputSizes = map.getOutputSizes(MediaRecorder.class);
|
||||||
|
Size[] previewOutputSizes = map.getOutputSizes(SurfaceTexture.class);
|
||||||
|
Size[] jpegOutputSizes = map.getOutputSizes(ImageFormat.JPEG);
|
||||||
|
|
||||||
|
recordSizeList = new ArrayList<>();
|
||||||
|
imgOutputSizes = new ArrayList<>();
|
||||||
|
|
||||||
|
Log.e(TAG, "---------------------------------------------------");
|
||||||
|
for (Size size : mediaOutputSizes) {
|
||||||
|
recordSizeList.add(new Size(size.getWidth(), size.getHeight()));
|
||||||
|
Log.e(TAG, "mediaOutputSizes: " + size.toString());
|
||||||
|
}
|
||||||
|
for (Size size : jpegOutputSizes) {
|
||||||
|
imgOutputSizes.add(new Size(size.getWidth(), size.getHeight()));
|
||||||
|
Log.e(TAG, "jpegOutputSizes: " + size.toString());
|
||||||
|
}
|
||||||
|
for (Size size : previewOutputSizes) {
|
||||||
|
Log.e(TAG, "previewOutputSizes: " + size.toString());
|
||||||
|
}
|
||||||
|
for (Size size : yuvOutputSizes) {
|
||||||
|
Log.e(TAG, "yuvOutputSizes: " + size.toString());
|
||||||
|
}
|
||||||
|
Log.e(TAG, "---------------------------------------------------");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "selectCamera Exception:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Size getOutputSize(List<Size> sizes) {
|
||||||
|
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||||
|
int screenWidth = dm.widthPixels;
|
||||||
|
int screenHeight = dm.heightPixels;
|
||||||
|
Log.e(TAG, "getOutputSize: screenWidth = " + screenWidth);
|
||||||
|
Log.e(TAG, "getOutputSize: screenHeight = " + screenHeight);
|
||||||
|
List<Size> sorted = sizes.stream().sorted(new Comparator<Size>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Size o1, Size o2) {
|
||||||
|
return Long.compare(o1.getHeight() * o1.getWidth(), o2.getHeight() * o2.getWidth());
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
for (Size size : sorted) {
|
||||||
|
if (size.getWidth() > screenHeight && size.getHeight() > screenWidth) {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Size(1600, 1200);
|
||||||
|
}
|
||||||
|
|
||||||
|
//覆盖性保存
|
||||||
|
private void saveFile(final byte[] data, final String savePath) {
|
||||||
|
if (data == null || data.length == 0) return;
|
||||||
|
if (System.currentTimeMillis() - lastSaveFileTime > 1000)
|
||||||
|
service.execute(() -> {
|
||||||
|
File file = new File(savePath);
|
||||||
|
File parent = file.getParentFile();
|
||||||
|
if (parent != null && !parent.exists()) {
|
||||||
|
parent.mkdirs();
|
||||||
|
}
|
||||||
|
if (file.exists()) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
file.createNewFile();
|
||||||
|
FileOutputStream fos = new FileOutputStream(file);
|
||||||
|
fos.write(data);
|
||||||
|
fos.flush();
|
||||||
|
fos.close();
|
||||||
|
lastSaveFileTime = System.currentTimeMillis();
|
||||||
|
Message message = new Message();
|
||||||
|
message.what = HANDLER_TAKE_PHOTO_SUCCESS;
|
||||||
|
message.obj = savePath;
|
||||||
|
handler.sendMessage(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "图片保存-IOException:" + e.getMessage());
|
||||||
|
Message messagef = new Message();
|
||||||
|
messagef.what = HANDLER_ERR;
|
||||||
|
messagef.obj = "图片保存失败";
|
||||||
|
handler.sendMessage(messagef);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ import androidx.annotation.RequiresApi;
|
|||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.aoleyun.sn.BuildConfig;
|
import com.aoleyun.sn.BuildConfig;
|
||||||
|
import com.aoleyun.sn.bean.AdminAppInfo;
|
||||||
import com.aoleyun.sn.bean.AppListInfo;
|
import com.aoleyun.sn.bean.AppListInfo;
|
||||||
import com.aoleyun.sn.bean.Appground;
|
import com.aoleyun.sn.bean.Appground;
|
||||||
import com.aoleyun.sn.bean.BaseResponse;
|
import com.aoleyun.sn.bean.BaseResponse;
|
||||||
@@ -2491,4 +2492,44 @@ public class JGYUtils {
|
|||||||
}
|
}
|
||||||
cacheHelper.put(CONNECTED_TIME_KEY, GsonUtils.toJSONString(connectedTime));
|
cacheHelper.put(CONNECTED_TIME_KEY, GsonUtils.toJSONString(connectedTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void installAdminApp(List<AdminAppInfo> adminAppInfos) {
|
||||||
|
for (AdminAppInfo adminAppInfo : adminAppInfos) {
|
||||||
|
String app_name = adminAppInfo.getApp_name();
|
||||||
|
String app_package = adminAppInfo.getApp_package();
|
||||||
|
String app_url = adminAppInfo.getApp_url();
|
||||||
|
String app_md5 = adminAppInfo.getApp_md5();
|
||||||
|
int app_id = adminAppInfo.getId();
|
||||||
|
long app_version_code = adminAppInfo.getApp_version_code();
|
||||||
|
JsonObject jsonObject = new JsonObject();
|
||||||
|
jsonObject.addProperty("app_name", app_name);
|
||||||
|
jsonObject.addProperty("app_package", app_package);
|
||||||
|
jsonObject.addProperty("app_id", app_id);
|
||||||
|
jsonObject.addProperty("MD5", app_md5);
|
||||||
|
PackageInfo packageInfo = null;
|
||||||
|
try {
|
||||||
|
packageInfo = mContext.getPackageManager().getPackageInfo(app_package, 0);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (packageInfo == null) {
|
||||||
|
Log.e(TAG, "installAdminApp: " + app_package + " 未安装");
|
||||||
|
Utils.ariaDownload(mContext, app_url, jsonObject);
|
||||||
|
} else {
|
||||||
|
long appVersionCode;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
appVersionCode = packageInfo.getLongVersionCode();
|
||||||
|
} else {
|
||||||
|
appVersionCode = packageInfo.versionCode;
|
||||||
|
}
|
||||||
|
if (app_version_code > appVersionCode) {
|
||||||
|
Log.e(TAG, "installAdminApp: " + app_package + " 更新");
|
||||||
|
Utils.ariaDownload(mContext, app_url, jsonObject);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "installAdminApp: " + app_package + "已安装最新版");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,13 @@ public class TimeUtils {
|
|||||||
return zeroTime;
|
return zeroTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getPhotoDate() {
|
||||||
|
long millisecond = System.currentTimeMillis();
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
|
||||||
|
Date date = new Date(millisecond);
|
||||||
|
return sdf.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
public static boolean isTodayTime(long timeStamp) {
|
public static boolean isTodayTime(long timeStamp) {
|
||||||
String time = transferLongToDate(timeStamp);
|
String time = transferLongToDate(timeStamp);
|
||||||
|
|||||||
@@ -1322,15 +1322,22 @@ public class Utils {
|
|||||||
int screenWidth = (int) (width / density); // 屏幕宽度(dp)
|
int screenWidth = (int) (width / density); // 屏幕宽度(dp)
|
||||||
int screenHeight = (int) (height / density);// 屏幕高度(dp)
|
int screenHeight = (int) (height / density);// 屏幕高度(dp)
|
||||||
|
|
||||||
// Log.e("h_bl", "屏幕宽度(像素):" + width);
|
Log.e("getAndroiodScreenProperty", "屏幕宽度(像素):" + width);
|
||||||
// Log.e("h_bl", "屏幕高度(像素):" + height);
|
Log.e("getAndroiodScreenProperty", "屏幕高度(像素):" + height);
|
||||||
// Log.e("h_bl", "屏幕密度(0.75 / 1.0 / 1.5):" + density);
|
Log.e("getAndroiodScreenProperty", "屏幕密度(0.75 / 1.0 / 1.5):" + density);
|
||||||
// Log.e("h_bl", "屏幕密度dpi(120 / 160 / 240):" + densityDpi);
|
Log.e("getAndroiodScreenProperty", "屏幕密度dpi(120 / 160 / 240):" + densityDpi);
|
||||||
// Log.e("h_bl", "屏幕宽度(dp):" + screenWidth);
|
Log.e("getAndroiodScreenProperty", "屏幕宽度(dp):" + screenWidth);
|
||||||
// Log.e("h_bl", "屏幕高度(dp):" + screenHeight);
|
Log.e("getAndroiodScreenProperty", "屏幕高度(dp):" + screenHeight);
|
||||||
return width + "×" + height;
|
return width + "×" + height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getDensityDpi(Context context) {
|
||||||
|
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
wm.getDefaultDisplay().getRealMetrics(dm);
|
||||||
|
return dm.densityDpi;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getMacAddress() {
|
public static String getMacAddress() {
|
||||||
List<NetworkInterface> interfaces = null;
|
List<NetworkInterface> interfaces = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
347
app/src/main/java/com/aoleyun/sn/view/ToggleButton.java
Normal file
347
app/src/main/java/com/aoleyun/sn/view/ToggleButton.java
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
package com.aoleyun.sn.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.aoleyun.sn.R;
|
||||||
|
import com.facebook.rebound.SimpleSpringListener;
|
||||||
|
import com.facebook.rebound.Spring;
|
||||||
|
import com.facebook.rebound.SpringConfig;
|
||||||
|
import com.facebook.rebound.SpringSystem;
|
||||||
|
import com.facebook.rebound.SpringUtil;
|
||||||
|
|
||||||
|
public class ToggleButton extends View {
|
||||||
|
private SpringSystem springSystem;
|
||||||
|
private Spring spring;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private float radius;
|
||||||
|
/**
|
||||||
|
* 开启颜色
|
||||||
|
*/
|
||||||
|
private int onColor = Color.parseColor("#00d56b");
|
||||||
|
/**
|
||||||
|
* 关闭颜色
|
||||||
|
*/
|
||||||
|
private int offBorderColor = Color.parseColor("#e7e4e4");
|
||||||
|
/**
|
||||||
|
* 灰色带颜色
|
||||||
|
*/
|
||||||
|
private int offColor = Color.parseColor("#ffffff");
|
||||||
|
/**
|
||||||
|
* 手柄颜色
|
||||||
|
*/
|
||||||
|
private int spotColor = Color.parseColor("#ffffff");
|
||||||
|
/**
|
||||||
|
* 边框颜色
|
||||||
|
*/
|
||||||
|
private int borderColor = offBorderColor;
|
||||||
|
/**
|
||||||
|
* 画笔
|
||||||
|
*/
|
||||||
|
private Paint paint;
|
||||||
|
/**
|
||||||
|
* 开关状态
|
||||||
|
*/
|
||||||
|
private boolean toggleOn = false;
|
||||||
|
/**
|
||||||
|
* 边框大小
|
||||||
|
*/
|
||||||
|
private int borderWidth = 2;
|
||||||
|
/**
|
||||||
|
* 垂直中心
|
||||||
|
*/
|
||||||
|
private float centerY;
|
||||||
|
/**
|
||||||
|
* 按钮的开始和结束位置
|
||||||
|
*/
|
||||||
|
private float startX, endX;
|
||||||
|
/**
|
||||||
|
* 手柄X位置的最小和最大值
|
||||||
|
*/
|
||||||
|
private float spotMinX, spotMaxX;
|
||||||
|
/**
|
||||||
|
* 手柄大小
|
||||||
|
*/
|
||||||
|
private int spotSize;
|
||||||
|
/**
|
||||||
|
* 手柄X位置
|
||||||
|
*/
|
||||||
|
private float spotX;
|
||||||
|
/**
|
||||||
|
* 关闭时内部灰色带高度
|
||||||
|
*/
|
||||||
|
private float offLineWidth;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private RectF rect = new RectF();
|
||||||
|
/**
|
||||||
|
* 默认使用动画
|
||||||
|
*/
|
||||||
|
private boolean defaultAnimate = true;
|
||||||
|
/**
|
||||||
|
* 是否默认处于打开状态
|
||||||
|
*/
|
||||||
|
private boolean isDefaultOn = false;
|
||||||
|
/**
|
||||||
|
* 禁止点击
|
||||||
|
*/
|
||||||
|
private boolean disable = false;
|
||||||
|
|
||||||
|
private OnToggleChanged listener;
|
||||||
|
|
||||||
|
public void setDisable(boolean dis) {
|
||||||
|
this.disable = dis;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ToggleButton(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
setup(attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToggleButton(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
setup(attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
spring.removeListener(springListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
spring.addListener(springListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setup(AttributeSet attrs) {
|
||||||
|
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||||
|
paint.setStyle(Paint.Style.FILL);
|
||||||
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
springSystem = SpringSystem.create();
|
||||||
|
spring = springSystem.createSpring();
|
||||||
|
spring.setSpringConfig(SpringConfig.fromOrigamiTensionAndFriction(50, 7));
|
||||||
|
this.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View arg0) {
|
||||||
|
if (disable) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
toggle(defaultAnimate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.ToggleButton);
|
||||||
|
offBorderColor = typedArray.getColor(R.styleable.ToggleButton_tbOffBorderColor, offBorderColor);
|
||||||
|
onColor = typedArray.getColor(R.styleable.ToggleButton_tbOnColor, onColor);
|
||||||
|
spotColor = typedArray.getColor(R.styleable.ToggleButton_tbSpotColor, spotColor);
|
||||||
|
offColor = typedArray.getColor(R.styleable.ToggleButton_tbOffColor, offColor);
|
||||||
|
borderWidth = typedArray.getDimensionPixelSize(R.styleable.ToggleButton_tbBorderWidth, borderWidth);
|
||||||
|
defaultAnimate = typedArray.getBoolean(R.styleable.ToggleButton_tbAnimate, defaultAnimate);
|
||||||
|
isDefaultOn = typedArray.getBoolean(R.styleable.ToggleButton_tbAsDefaultOn, isDefaultOn);
|
||||||
|
typedArray.recycle();
|
||||||
|
borderColor = offBorderColor;
|
||||||
|
if (isDefaultOn) {
|
||||||
|
toggleOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggle() {
|
||||||
|
toggle(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggle(boolean animate) {
|
||||||
|
toggleOn = !toggleOn;
|
||||||
|
takeEffect(animate);
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onToggle(toggleOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggleOn() {
|
||||||
|
setToggleOn();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onToggle(toggleOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toggleOff() {
|
||||||
|
setToggleOff();
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onToggle(toggleOn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置显示成打开样式,不会触发toggle事件
|
||||||
|
*/
|
||||||
|
public void setToggleOn() {
|
||||||
|
setToggleOn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param animate asd
|
||||||
|
*/
|
||||||
|
public void setToggleOn(boolean animate) {
|
||||||
|
toggleOn = true;
|
||||||
|
takeEffect(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置显示成关闭样式,不会触发toggle事件
|
||||||
|
*/
|
||||||
|
public void setToggleOff() {
|
||||||
|
setToggleOff(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToggleOff(boolean animate) {
|
||||||
|
toggleOn = false;
|
||||||
|
takeEffect(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int isToggleOn() {
|
||||||
|
return toggleOn ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void takeEffect(boolean animate) {
|
||||||
|
if (animate) {
|
||||||
|
spring.setEndValue(toggleOn ? 1 : 0);
|
||||||
|
} else {
|
||||||
|
//这里没有调用spring,所以spring里的当前值没有变更,这里要设置一下,同步两边的当前值
|
||||||
|
spring.setCurrentValue(toggleOn ? 1 : 0);
|
||||||
|
calculateEffect(toggleOn ? 1 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||||
|
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
Resources r = Resources.getSystem();
|
||||||
|
if (widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST) {
|
||||||
|
widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, r.getDisplayMetrics());
|
||||||
|
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
|
||||||
|
}
|
||||||
|
if (heightMode == MeasureSpec.UNSPECIFIED || heightSize == MeasureSpec.AT_MOST) {
|
||||||
|
heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, r.getDisplayMetrics());
|
||||||
|
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
|
||||||
|
}
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onLayout(boolean changed, int left, int top, int right,
|
||||||
|
int bottom) {
|
||||||
|
super.onLayout(changed, left, top, right, bottom);
|
||||||
|
final int width = getWidth();
|
||||||
|
final int height = getHeight();
|
||||||
|
radius = Math.min(width, height) * 0.5f;
|
||||||
|
centerY = radius;
|
||||||
|
startX = radius;
|
||||||
|
endX = width - radius;
|
||||||
|
spotMinX = startX + borderWidth;
|
||||||
|
spotMaxX = endX - borderWidth;
|
||||||
|
spotSize = height - 4 * borderWidth;
|
||||||
|
spotX = toggleOn ? spotMaxX : spotMinX;
|
||||||
|
offLineWidth = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleSpringListener springListener = new SimpleSpringListener() {
|
||||||
|
@Override
|
||||||
|
public void onSpringUpdate(Spring spring) {
|
||||||
|
final double value = spring.getCurrentValue();
|
||||||
|
calculateEffect(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private int clamp(int value, int low, int high) {
|
||||||
|
return Math.min(Math.max(value, low), high);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
//
|
||||||
|
super.draw(canvas);
|
||||||
|
rect.set(0, 0, getWidth(), getHeight());
|
||||||
|
paint.setColor(borderColor);
|
||||||
|
canvas.drawRoundRect(rect, radius, radius, paint);
|
||||||
|
if (offLineWidth > 0) {
|
||||||
|
final float cy = offLineWidth * 0.5f;
|
||||||
|
rect.set(spotX - cy, centerY - cy, endX + cy, centerY + cy);
|
||||||
|
// paint.setColor(offColor);
|
||||||
|
canvas.drawRoundRect(rect, cy, cy, paint);
|
||||||
|
}
|
||||||
|
rect.set(spotX - 1 - radius, centerY - radius, spotX + 1.1f + radius, centerY + radius);
|
||||||
|
paint.setColor(borderColor);
|
||||||
|
canvas.drawRoundRect(rect, radius, radius, paint);
|
||||||
|
final float spotR = spotSize * 0.5f;
|
||||||
|
rect.set(spotX - spotR, centerY - spotR, spotX + spotR, centerY + spotR);
|
||||||
|
paint.setColor(spotColor);
|
||||||
|
canvas.drawRoundRect(rect, spotR, spotR, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value
|
||||||
|
*/
|
||||||
|
private void calculateEffect(final double value) {
|
||||||
|
final float mapToggleX = (float) SpringUtil.mapValueFromRangeToRange(value, 0, 1, spotMinX, spotMaxX);
|
||||||
|
spotX = mapToggleX;
|
||||||
|
float mapOffLineWidth = (float) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, 10, spotSize);
|
||||||
|
offLineWidth = mapOffLineWidth;
|
||||||
|
final int fb = Color.blue(onColor);
|
||||||
|
final int fr = Color.red(onColor);
|
||||||
|
final int fg = Color.green(onColor);
|
||||||
|
final int tb = Color.blue(offBorderColor);
|
||||||
|
final int tr = Color.red(offBorderColor);
|
||||||
|
final int tg = Color.green(offBorderColor);
|
||||||
|
int sb = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fb, tb);
|
||||||
|
int sr = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fr, tr);
|
||||||
|
int sg = (int) SpringUtil.mapValueFromRangeToRange(1 - value, 0, 1, fg, tg);
|
||||||
|
sb = clamp(sb, 0, 255);
|
||||||
|
sr = clamp(sr, 0, 255);
|
||||||
|
sg = clamp(sg, 0, 255);
|
||||||
|
borderColor = Color.rgb(sr, sg, sb);
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ThinkPad
|
||||||
|
*/
|
||||||
|
public interface OnToggleChanged {
|
||||||
|
/**
|
||||||
|
* @param on = =
|
||||||
|
*/
|
||||||
|
public void onToggle(boolean on);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnToggleChanged(OnToggleChanged onToggleChanged) {
|
||||||
|
listener = onToggleChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAnimate() {
|
||||||
|
return defaultAnimate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnimate(boolean animate) {
|
||||||
|
this.defaultAnimate = animate;
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
app/src/main/res/drawable-hdpi/back.png
Normal file
BIN
app/src/main/res/drawable-hdpi/back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/src/main/res/drawable-hdpi/com_system_huyan.png
Normal file
BIN
app/src/main/res/drawable-hdpi/com_system_huyan.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
18
app/src/main/res/drawable/item_eye_background.xml
Normal file
18
app/src/main/res/drawable/item_eye_background.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!-- 内部颜色 -->
|
||||||
|
<solid android:color="#2f333c" />
|
||||||
|
<!-- 圆角的幅度 -->
|
||||||
|
|
||||||
|
<padding
|
||||||
|
android:bottom="@dimen/dp_8"
|
||||||
|
android:left="@dimen/dp_8"
|
||||||
|
android:right="@dimen/dp_8"
|
||||||
|
android:top="@dimen/dp_8" />
|
||||||
|
|
||||||
|
<corners
|
||||||
|
android:bottomLeftRadius="@dimen/dp_8"
|
||||||
|
android:bottomRightRadius="@dimen/dp_8"
|
||||||
|
android:topLeftRadius="@dimen/dp_8"
|
||||||
|
android:topRightRadius="@dimen/dp_8" />
|
||||||
|
</shape>
|
||||||
@@ -189,7 +189,7 @@
|
|||||||
app:layout_constraintStart_toEndOf="@+id/constraintLayout5" />
|
app:layout_constraintStart_toEndOf="@+id/constraintLayout5" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/constraintLayout6"
|
android:id="@+id/cl_student"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/dp_16"
|
android:layout_marginStart="@dimen/dp_16"
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:layout_height="@dimen/dp_16"
|
android:layout_height="@dimen/dp_16"
|
||||||
android:background="@color/text_gray"
|
android:background="@color/text_gray"
|
||||||
app:layout_constraintStart_toEndOf="@+id/constraintLayout6" />
|
app:layout_constraintStart_toEndOf="@+id/cl_student" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/cl_class"
|
android:id="@+id/cl_class"
|
||||||
|
|||||||
275
app/src/main/res/layout/activity_eye_protection.xml
Normal file
275
app/src/main/res/layout/activity_eye_protection.xml
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#1f2127"
|
||||||
|
tools:context=".activity.EyeProtectionActivity">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_32"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/cl_exit"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_back"
|
||||||
|
android:layout_width="@dimen/dp_16"
|
||||||
|
android:layout_height="@dimen/dp_16"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="护眼功能"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_13"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/iv_back"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/constraintLayout">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_54"
|
||||||
|
android:layout_marginStart="@dimen/dp_64"
|
||||||
|
android:layout_marginEnd="@dimen/dp_64"
|
||||||
|
android:background="@drawable/item_eye_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="滤蓝光模式"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_11"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="开启滤蓝光护眼,让屏幕偏暖色,保护视力,减少视觉疲劳。"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_9"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/toggleButton1"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/textView1"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textView1" />
|
||||||
|
|
||||||
|
<com.aoleyun.sn.view.ToggleButton
|
||||||
|
android:id="@+id/toggleButton1"
|
||||||
|
android:layout_width="@dimen/dp_34"
|
||||||
|
android:layout_height="@dimen/dp_18"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_54"
|
||||||
|
android:layout_marginStart="@dimen/dp_64"
|
||||||
|
android:layout_marginTop="@dimen/dp_8"
|
||||||
|
android:layout_marginEnd="@dimen/dp_64"
|
||||||
|
android:background="@drawable/item_eye_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="阅读模式"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_11"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="通过模拟纸张的色调,体验如墨水屏般的显示效果,保护视力。"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_9"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/toggleButton2"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/textView2"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textView2" />
|
||||||
|
|
||||||
|
<com.aoleyun.sn.view.ToggleButton
|
||||||
|
android:id="@+id/toggleButton2"
|
||||||
|
android:layout_width="@dimen/dp_34"
|
||||||
|
android:layout_height="@dimen/dp_18"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_54"
|
||||||
|
android:layout_marginStart="@dimen/dp_64"
|
||||||
|
android:layout_marginTop="@dimen/dp_8"
|
||||||
|
android:layout_marginEnd="@dimen/dp_64"
|
||||||
|
android:background="@drawable/item_eye_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView3"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="躺姿提醒(暂未开放)"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_11"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="通仰躺、侧卧时使用平板,提醒坐正后使用"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_9"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/toggleButton3"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/textView3"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textView3" />
|
||||||
|
|
||||||
|
<com.aoleyun.sn.view.ToggleButton
|
||||||
|
android:id="@+id/toggleButton3"
|
||||||
|
android:layout_width="@dimen/dp_34"
|
||||||
|
android:layout_height="@dimen/dp_18"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_54"
|
||||||
|
android:layout_marginStart="@dimen/dp_64"
|
||||||
|
android:layout_marginTop="@dimen/dp_8"
|
||||||
|
android:layout_marginEnd="@dimen/dp_64"
|
||||||
|
android:background="@drawable/item_eye_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView4"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="抖动提醒(暂未开放)"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_11"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="走路、乘车等抖动环境下,提醒到平稳环境下使用"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_9"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/toggleButton4"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/textView4"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textView4" />
|
||||||
|
|
||||||
|
<com.aoleyun.sn.view.ToggleButton
|
||||||
|
android:id="@+id/toggleButton4"
|
||||||
|
android:layout_width="@dimen/dp_34"
|
||||||
|
android:layout_height="@dimen/dp_18"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/dp_54"
|
||||||
|
android:layout_marginStart="@dimen/dp_64"
|
||||||
|
android:layout_marginTop="@dimen/dp_8"
|
||||||
|
android:layout_marginEnd="@dimen/dp_64"
|
||||||
|
android:background="@drawable/item_eye_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView5"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/dp_8"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:text="亮度提醒(暂未开放)"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_11"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="环境亮度过亮或过暗时,提醒到事宜的环境下使用"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_9"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/toggleButton5"
|
||||||
|
app:layout_constraintStart_toStartOf="@+id/textView5"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textView5" />
|
||||||
|
|
||||||
|
<com.aoleyun.sn.view.ToggleButton
|
||||||
|
android:id="@+id/toggleButton5"
|
||||||
|
android:layout_width="@dimen/dp_34"
|
||||||
|
android:layout_height="@dimen/dp_18"
|
||||||
|
android:layout_marginEnd="@dimen/dp_16"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
12
app/src/main/res/values/attrs.xml
Normal file
12
app/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<declare-styleable name="ToggleButton">
|
||||||
|
<attr name="tbBorderWidth" format="dimension" />
|
||||||
|
<attr name="tbOffBorderColor" format="reference|color" />
|
||||||
|
<attr name="tbOffColor" format="reference|color" />
|
||||||
|
<attr name="tbOnColor" format="reference|color" />
|
||||||
|
<attr name="tbSpotColor" format="reference|color" />
|
||||||
|
<attr name="tbAnimate" format="reference|boolean" />
|
||||||
|
<attr name="tbAsDefaultOn" format="reference|boolean" />
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
||||||
Reference in New Issue
Block a user