1.1.6 增加图标上传,修改主页
This commit is contained in:
@@ -16,8 +16,8 @@ android {
|
||||
applicationId "com.uiuipad.find"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 29
|
||||
versionCode 11
|
||||
versionName "1.1.0"
|
||||
versionCode 17
|
||||
versionName "1.1.6"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package="com.uiuipad.find"
|
||||
android:sharedUserId="android.uid.system">
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.MASTER_CLEAR" />
|
||||
|
||||
@@ -6,10 +6,10 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.Settings;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
@@ -38,6 +38,7 @@ import com.uiuipad.find.network.api.jxw.JxwUtils;
|
||||
import com.uiuipad.find.network.api.kuxin.app.GetAppApi;
|
||||
import com.uiuipad.find.network.api.kuxin.app.GetSelfAppApi;
|
||||
import com.uiuipad.find.network.api.kuxin.app.UpdateAppInstallApi;
|
||||
import com.uiuipad.find.network.api.kuxin.app.UploadAppImgApi;
|
||||
import com.uiuipad.find.network.api.kuxin.manage.RemoveLockScreenApi;
|
||||
import com.uiuipad.find.network.api.kuxin.manage.SnSettingApi;
|
||||
import com.uiuipad.find.network.api.kuxin.manage.UpdateSnLocationApi;
|
||||
@@ -48,7 +49,7 @@ import com.uiuipad.find.network.api.kuxin.sn.UpdateSnInfoApi;
|
||||
import com.uiuipad.find.network.interceptor.RepeatRequestInterceptor;
|
||||
import com.uiuipad.find.service.ManagerService;
|
||||
import com.uiuipad.find.util.ApkUtils;
|
||||
import com.uiuipad.find.util.CacheUtils;
|
||||
import com.uiuipad.find.util.BitmapUtils;
|
||||
import com.uiuipad.find.util.ControlUtils;
|
||||
import com.uiuipad.find.util.FileUtils;
|
||||
import com.uiuipad.find.util.TimeUtils;
|
||||
@@ -64,6 +65,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
@@ -76,8 +79,11 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.RequestBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
@@ -91,6 +97,7 @@ public class NetInterfaceManager {
|
||||
private Context mContext;
|
||||
private ContentResolver mCrv;
|
||||
private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE);
|
||||
|
||||
private Retrofit mRetrofit;
|
||||
private OkHttpClient mOkHttpClient;
|
||||
|
||||
@@ -100,6 +107,9 @@ public class NetInterfaceManager {
|
||||
private Retrofit mJxwRetrofit;
|
||||
private OkHttpClient mJxwOkHttpClient;
|
||||
|
||||
private Set<String> mUploadIconPkgs;
|
||||
private static final String uploadIconPkgsKey = "UPLOAD_ICON_PACKAGE_KEY";
|
||||
|
||||
//超时时间
|
||||
private static final int TIME_OUT = 5;
|
||||
// 缓存文件最大限制大小20M
|
||||
@@ -186,6 +196,9 @@ public class NetInterfaceManager {
|
||||
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
|
||||
.build();
|
||||
}
|
||||
|
||||
mUploadIconPkgs = mMMKV.decodeStringSet(uploadIconPkgsKey, new HashSet<>());
|
||||
Log.e("init", "NetInterfaceManager: mUploadIconPkgs = "+mUploadIconPkgs );
|
||||
}
|
||||
|
||||
private String getCacheDir() {
|
||||
@@ -278,6 +291,17 @@ public class NetInterfaceManager {
|
||||
params.put("memory_use", NetInterfaceManager.convertToRequestBody(Utils.getUsedMemoryString(mContext)));
|
||||
params.put("storage_use", NetInterfaceManager.convertToRequestBody(Utils.getUsedSize(mContext)));
|
||||
params.put("sn", NetInterfaceManager.convertToRequestBody(Utils.getSerial()));
|
||||
params.put("xiaoku_version", NetInterfaceManager.convertToRequestBody(BuildConfig.VERSION_NAME));
|
||||
params.put("xiaoku_version_time", NetInterfaceManager.convertToRequestBody(ApkUtils.getAppLastUpdateTime(mContext, BuildConfig.APPLICATION_ID)));
|
||||
params.put("desktop_version", NetInterfaceManager.convertToRequestBody(ApkUtils.getAPPVersionName(mContext, "com.uiuipad.os")));
|
||||
params.put("desktop_version_time", NetInterfaceManager.convertToRequestBody(ApkUtils.getAppLastUpdateTime(mContext, "com.uiuipad.os")));
|
||||
params.put("browser_version", NetInterfaceManager.convertToRequestBody(ApkUtils.getAPPVersionName(mContext, "com.uiuipad.browser")));
|
||||
params.put("browser_version_time", NetInterfaceManager.convertToRequestBody(ApkUtils.getAppLastUpdateTime(mContext, "com.uiuipad.browser")));
|
||||
params.put("imei", NetInterfaceManager.convertToRequestBody(Utils.getIMEI(mContext)));
|
||||
params.put("model", NetInterfaceManager.convertToRequestBody(Build.MODEL));
|
||||
params.put("system", NetInterfaceManager.convertToRequestBody(Build.VERSION.RELEASE));
|
||||
params.put("rom", NetInterfaceManager.convertToRequestBody(Utils.getCustomVersion()));
|
||||
|
||||
return mRetrofit.create(UpdateSnInfoApi.class)
|
||||
.updateSnInfo(params)
|
||||
.subscribeOn(Schedulers.io())
|
||||
@@ -356,8 +380,6 @@ public class NetInterfaceManager {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* API
|
||||
@@ -372,6 +394,10 @@ public class NetInterfaceManager {
|
||||
return mRetrofit.create(UploadSnScreenshotApi.class);
|
||||
}
|
||||
|
||||
public UploadAppImgApi getUploadAppImgApi() {
|
||||
return mRetrofit.create(UploadAppImgApi.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -506,8 +532,79 @@ public class NetInterfaceManager {
|
||||
Log.e("updateAppInstall", "onComplete: ");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
|
||||
List<PackageInfo> filter = packageInfos.stream().filter(new Predicate<PackageInfo>() {
|
||||
@Override
|
||||
public boolean test(PackageInfo packageInfo) {
|
||||
if (ApkUtils.isSystemApp(mContext, packageInfo.packageName)) {
|
||||
if (ApkUtils.systemApps.contains(packageInfo.packageName)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
List<PackageInfo> filterJxwApp = filter.stream().filter(packageInfo -> !ApkUtils.jxwApkNames.contains(packageInfo.packageName)).collect(Collectors.toList());
|
||||
for (PackageInfo packageInfo : filterJxwApp) {
|
||||
if ("com.uiuipad.find".equals(packageInfo.packageName)
|
||||
|| "com.uiuipad.os".equals(packageInfo.packageName)
|
||||
|| "com.uiui.zybrowser".equals(packageInfo.packageName)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mUploadIconPkgs.contains(packageInfo.packageName)) {
|
||||
Drawable drawable = packageInfo.applicationInfo.loadIcon(pm);
|
||||
File file = BitmapUtils.drawableToFile(mContext, drawable, packageInfo.packageName);
|
||||
//File转RequestBody
|
||||
MediaType mediaType = MediaType.Companion.parse("image/png");
|
||||
RequestBody fileBody = RequestBody.Companion.create(file, mediaType);
|
||||
//设置一个file文件
|
||||
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
|
||||
Map<String, RequestBody> params = new HashMap<>();
|
||||
params.put("package", NetInterfaceManager.convertToRequestBody(packageInfo.packageName));
|
||||
Call<BaseResponse> call = getUploadAppImgApi().uploadAppImg(params, body);
|
||||
call.enqueue(new RetryCallback<BaseResponse>(call, 10, 30 * 1000) {
|
||||
@Override
|
||||
public void onRequestResponse(Call call, Response response) {
|
||||
BaseResponse baseResponse = (BaseResponse) response.body();
|
||||
Log.e(TAG, "onRequestResponse: " + baseResponse);
|
||||
if (baseResponse.code == 200 || baseResponse.code == 401) {
|
||||
addIcon(packageInfo.packageName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestFail(Call call, Throwable t) {
|
||||
Log.e(TAG, "onRequestFail: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartRetry() {
|
||||
Log.e(TAG, "onStartRetry: ");
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
Log.e(TAG, "updateAppInstall: upload " + packageInfo.packageName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addIcon(String pkg) {
|
||||
mUploadIconPkgs.add(pkg);
|
||||
mMMKV.encode(uploadIconPkgsKey, mUploadIconPkgs);
|
||||
}
|
||||
|
||||
|
||||
public interface SnIsActivationCallback {
|
||||
void isActivation(ActivationBean activationBean);
|
||||
}
|
||||
|
||||
@@ -67,6 +67,12 @@ public class UrlAddress {
|
||||
public static final String UPDATE_APP_INSTALL = "app/app/updateAppInstall";
|
||||
/*上传应用使用记录*/
|
||||
public static final String UPLOAD_APP_USE_LOG = "app/app/uploadAppUseLog";
|
||||
/*上传应用图标*/
|
||||
public static final String UPLOAD_APP_IMG = "app/app/uploadAppImg";
|
||||
/*获取应用是否有图标*/
|
||||
public static final String GET_IS_APP_IMG = "app/app/getIsAppImg";
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 闹钟
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.uiuipad.find.network.api.kuxin.app;
|
||||
|
||||
import com.uiuipad.find.bean.kuxin.BaseResponse;
|
||||
import com.uiuipad.find.network.UrlAddress;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.Query;
|
||||
|
||||
public interface AppImgApi {
|
||||
@GET(UrlAddress.GET_IS_APP_IMG)
|
||||
Observable<BaseResponse> getIsAppImg(
|
||||
@Query("package") String pkg
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.uiuipad.find.network.api.kuxin.app;
|
||||
|
||||
import com.uiuipad.find.bean.kuxin.BaseResponse;
|
||||
import com.uiuipad.find.network.UrlAddress;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.RequestBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Multipart;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.Part;
|
||||
import retrofit2.http.PartMap;
|
||||
|
||||
public interface UploadAppImgApi {
|
||||
@Multipart
|
||||
@POST(UrlAddress.UPLOAD_APP_IMG)
|
||||
Call<BaseResponse> uploadAppImg(
|
||||
@PartMap Map<String, RequestBody> params,
|
||||
@Part MultipartBody.Part body
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import android.annotation.SuppressLint;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.util.Log;
|
||||
@@ -30,8 +32,10 @@ import com.uiuipad.find.network.RetryCallback;
|
||||
import com.uiuipad.find.service.ManagerService;
|
||||
import com.uiuipad.find.service.main.MainService;
|
||||
import com.uiuipad.find.util.ApkUtils;
|
||||
import com.uiuipad.find.util.Camera2BackgroundUtil;
|
||||
import com.uiuipad.find.util.CmdUtil;
|
||||
import com.uiuipad.find.util.ControlUtils;
|
||||
import com.uiuipad.find.util.TimeUtils;
|
||||
import com.uiuipad.find.util.ToastUtil;
|
||||
import com.uiuipad.find.util.Utils;
|
||||
|
||||
@@ -229,11 +233,14 @@ public class PushManager {
|
||||
|
||||
break;
|
||||
case FRONT_CAMERA:
|
||||
ToastUtil.debugShow("收到管控:行为查看");
|
||||
getFrontCamera();
|
||||
break;
|
||||
case UNBIND_DEVICES:
|
||||
ToastUtil.debugShow("收到管控:解除绑定");
|
||||
mMMKV.clearAll();
|
||||
ControlUtils.disableSystemControl(mContext);
|
||||
mContext.sendBroadcast(new Intent(MainService.OS_REFRESH_ACTION));
|
||||
break;
|
||||
case RESTORE_FACTORY:
|
||||
ToastUtil.debugShow("收到管控:恢复出厂");
|
||||
@@ -430,7 +437,7 @@ public class PushManager {
|
||||
if (code == 200) {
|
||||
ToastUtil.show("绑定成功");
|
||||
mContext.sendBroadcast(new Intent(MainService.REFRESH_ACTION));
|
||||
} else if (code == 301) {
|
||||
} else {
|
||||
ToastUtil.show(msg);
|
||||
}
|
||||
}
|
||||
@@ -439,6 +446,7 @@ public class PushManager {
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("snConfirmBind", "onError: " + e.getMessage());
|
||||
onComplete();
|
||||
ToastUtil.show("接口请求失败,请联系管理员");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -566,18 +574,59 @@ public class PushManager {
|
||||
call.enqueue(new RetryCallback<BaseResponse>(call, 10, 30 * 1000) {
|
||||
@Override
|
||||
public void onRequestResponse(Call call, Response response) {
|
||||
Log.e(TAG, "onRequestResponse: " + response.body().toString());
|
||||
Log.e("uplaodImage", "onRequestResponse: " + response.body().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestFail(Call call, Throwable t) {
|
||||
Log.e(TAG, "onRequestFail: ");
|
||||
Log.e("uplaodImage", "onRequestFail: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartRetry() {
|
||||
Log.e(TAG, "onStartRetry: ");
|
||||
Log.e("uplaodImage", "onStartRetry: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getFrontCamera() {
|
||||
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 requestBody = RequestBody.Companion.create(file, mediaType);
|
||||
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
|
||||
Map<String, RequestBody> params = new HashMap<>();
|
||||
params.put("sn", NetInterfaceManager.convertToRequestBody(Utils.getSerial()));
|
||||
params.put("type", NetInterfaceManager.convertToRequestBody("2"));
|
||||
Call<BaseResponse> call = NetInterfaceManager.getInstance().getUploadSnScreenshotApi().uploadSnScreenshot(params, body);
|
||||
call.enqueue(new RetryCallback<BaseResponse>(call, 10, 30 * 1000) {
|
||||
@Override
|
||||
public void onRequestResponse(Call call, Response response) {
|
||||
Log.e("getFrontCamera", "onRequestResponse: " + response.body().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestFail(Call call, Throwable t) {
|
||||
Log.e("getFrontCamera", "onRequestFail: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartRetry() {
|
||||
Log.e("getFrontCamera", "onStartRetry: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
camera2BackgroundUtil.startTakePicture(mContext.getExternalCacheDir().getAbsolutePath() + File.separator + TimeUtils.getPhotoDate() + ".jpg");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import java.util.List;
|
||||
public class MainSContact {
|
||||
interface Presenter extends BasePresenter<MainView> {
|
||||
void updateSnInfo();
|
||||
void startLocation();
|
||||
void getSnSetting();
|
||||
void getApp();
|
||||
void getSelfApp();
|
||||
@@ -29,6 +30,7 @@ public class MainSContact {
|
||||
|
||||
public interface MainView extends BaseView {
|
||||
void updateSnInfoFinish();
|
||||
void sendLocation();
|
||||
void getSnSettingFinish();
|
||||
void getAppFinish();
|
||||
void getSelfAppFinish();
|
||||
|
||||
@@ -3,6 +3,9 @@ package com.uiuipad.find.service.main;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.baidu.location.BDAbstractLocationListener;
|
||||
import com.baidu.location.BDLocation;
|
||||
import com.baidu.location.LocationClient;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
@@ -12,6 +15,7 @@ import com.uiuipad.find.bean.jxw.JxwResponse;
|
||||
import com.uiuipad.find.bean.kuxin.AppInfo;
|
||||
import com.uiuipad.find.bean.kuxin.BaseResponse;
|
||||
import com.uiuipad.find.comm.CommonConfig;
|
||||
import com.uiuipad.find.manager.MapManager;
|
||||
import com.uiuipad.find.network.NetInterfaceManager;
|
||||
import com.uiuipad.find.util.ApkUtils;
|
||||
|
||||
@@ -86,6 +90,51 @@ public class MainSPresenter implements MainSContact.Presenter {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startLocation() {
|
||||
LocationClient locationClient = MapManager.getInstance().getLocationClient();
|
||||
locationClient.stop();
|
||||
locationClient.start();
|
||||
locationClient.registerLocationListener(new BDAbstractLocationListener() {
|
||||
@Override
|
||||
public void onReceiveLocation(BDLocation bdLocation) {
|
||||
Log.e(TAG, "onReceiveLocation: ");
|
||||
if (bdLocation != null) {
|
||||
double longitude = bdLocation.getLongitude();
|
||||
double latitude = bdLocation.getLatitude();
|
||||
Log.e(TAG, "onReceiveLocation: longitude = " + longitude);
|
||||
Log.e(TAG, "onReceiveLocation: latitude = " + latitude);
|
||||
NetInterfaceManager.getInstance().getUpdateSnLocationControl(mMMKV.decodeString(CommonConfig.MAP_ADDRESS_KEY, "-"),
|
||||
Double.toString(longitude),
|
||||
Double.toString(latitude))
|
||||
.subscribe(new Observer<BaseResponse>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("startLocation", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseResponse baseResponse) {
|
||||
Log.e("startLocation", "onSubscribe: " + baseResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("startLocation", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("startLocation", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
locationClient.stop();
|
||||
}
|
||||
});
|
||||
mView.sendLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSnSetting() {
|
||||
NetInterfaceManager.getInstance().getSnSetting();
|
||||
|
||||
@@ -11,6 +11,7 @@ import android.content.IntentFilter;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -37,12 +38,18 @@ import com.uiuipad.find.comm.CommonConfig;
|
||||
import com.uiuipad.find.gson.GsonUtils;
|
||||
import com.uiuipad.find.network.NetInterfaceManager;
|
||||
import com.uiuipad.find.util.ApkUtils;
|
||||
import com.uiuipad.find.util.AppUtil;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject;
|
||||
|
||||
/**
|
||||
@@ -97,6 +104,53 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
|
||||
}
|
||||
}
|
||||
|
||||
private static KillAppListener killAppListener;
|
||||
|
||||
public interface KillAppListener {
|
||||
void killApp(String action);
|
||||
}
|
||||
|
||||
private final ObservableOnSubscribe<String> killSubscribe = new ObservableOnSubscribe<String>() {
|
||||
@Override
|
||||
public void subscribe(ObservableEmitter emitter) throws Exception {
|
||||
killAppListener = new KillAppListener() {
|
||||
@Override
|
||||
public void killApp(String action) {
|
||||
emitter.onNext(action);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
private Observer<String> killObserver = new Observer<String>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
Log.e("killObserver", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(String action) {
|
||||
Log.e("killObserver", "onNext: " + action);
|
||||
AppUtil.killPackage(MainService.this, "com.jxw.mskt.video");
|
||||
AppUtil.killPackage(MainService.this, "com.jxw.teacher.video");
|
||||
AppUtil.killPackage(MainService.this, "com.jxw.newyouer.video");
|
||||
AppUtil.killPackage(MainService.this, "com.jxw.question");
|
||||
AppUtil.killPackage(MainService.this, "com.jxw.launcher");
|
||||
AppUtil.killPackage(MainService.this, "com.uiui.zyappstore");
|
||||
AppUtil.killPackage(MainService.this, "com.uiui.zysn");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
Log.e("killObserver", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("killObserver", "onComplete: ");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
@@ -106,6 +160,11 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
|
||||
mPresenter.attachView(this);
|
||||
Aria.download(this).register();
|
||||
|
||||
Observable.create(killSubscribe)
|
||||
.throttleLast(3, TimeUnit.MINUTES)
|
||||
// .throttleLast(3, TimeUnit.SECONDS)
|
||||
.subscribe(killObserver);
|
||||
|
||||
registerReceivers();
|
||||
mPresenter.updateSnInfo();
|
||||
}
|
||||
@@ -149,12 +208,16 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
|
||||
|
||||
private void registerReceivers() {
|
||||
registerRefreshReceiver();
|
||||
registerScreenLockReceiver();
|
||||
}
|
||||
|
||||
private void unregisterReceivers() {
|
||||
if (mRefreshReceiver != null) {
|
||||
unregisterReceiver(mRefreshReceiver);
|
||||
}
|
||||
if (null != screenLockReceiver) {
|
||||
unregisterReceiver(screenLockReceiver);
|
||||
}
|
||||
}
|
||||
|
||||
public static final String REFRESH_ACTION = "uiui.find.main.action.refresh";
|
||||
@@ -182,6 +245,49 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
|
||||
}
|
||||
}
|
||||
|
||||
private ScreenLockReceiver screenLockReceiver;
|
||||
|
||||
private void registerScreenLockReceiver() {
|
||||
if (null == screenLockReceiver) {
|
||||
screenLockReceiver = new ScreenLockReceiver();
|
||||
}
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
|
||||
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
filter.addAction(Intent.ACTION_SCREEN_ON);
|
||||
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
|
||||
filter.addAction(Intent.ACTION_USER_PRESENT);
|
||||
filter.addAction(Intent.ACTION_SHUTDOWN);
|
||||
filter.addAction(Intent.ACTION_FACTORY_RESET);
|
||||
filter.addAction(Intent.ACTION_MASTER_CLEAR);
|
||||
registerReceiver(screenLockReceiver, filter);
|
||||
}
|
||||
|
||||
private class ScreenLockReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
Log.e("ScreenLockReceiver", "onReceive:" + action);
|
||||
if (TextUtils.isEmpty(action)) {
|
||||
Log.e("ScreenLockReceiver", "onReceive: is NULL");
|
||||
return;
|
||||
}
|
||||
switch (action) {
|
||||
case Intent.ACTION_USER_PRESENT:
|
||||
case Intent.ACTION_SCREEN_ON:
|
||||
break;
|
||||
case Intent.ACTION_SCREEN_OFF:
|
||||
case Intent.ACTION_SHUTDOWN:
|
||||
case Intent.ACTION_FACTORY_RESET:
|
||||
case Intent.ACTION_MASTER_CLEAR:
|
||||
killAppListener.killApp(action);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String CHANNEL_ID = "CHANNEL_ID";
|
||||
private static final String channel_name = "系统通知";
|
||||
private static final String channel_description = "我的设备系统通知";
|
||||
@@ -239,6 +345,11 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
|
||||
|
||||
@Override
|
||||
public void updateSnInfoFinish() {
|
||||
mPresenter.startLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendLocation() {
|
||||
mPresenter.getSnSetting();
|
||||
}
|
||||
|
||||
|
||||
@@ -412,7 +412,7 @@ public class ApkUtils {
|
||||
this.add("com.iflytek.speechcloud");
|
||||
}};
|
||||
|
||||
private static final Set<String> systemApps = new HashSet<String>() {{
|
||||
public static final Set<String> systemApps = new HashSet<String>() {{
|
||||
this.add("com.android.deskclock");
|
||||
this.add("com.android.music");
|
||||
this.add("com.android.documentsui");
|
||||
@@ -453,6 +453,7 @@ public class ApkUtils {
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<PackageInfo> filterJxwApp = filter.stream().filter(packageInfo -> !jxwApkNames.contains(packageInfo.packageName)).collect(Collectors.toList());
|
||||
|
||||
List<InstallAppInfo> installAppInfos = new ArrayList<>();
|
||||
for (PackageInfo packageInfo : filterJxwApp) {
|
||||
if ("com.uiuipad.find".equals(packageInfo.packageName)
|
||||
@@ -467,6 +468,8 @@ public class ApkUtils {
|
||||
return GsonUtils.toJSONString(installAppInfos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static InstallAppInfo packageInfo2AppInfo(PackageManager packageManager, PackageInfo packageInfo) {
|
||||
InstallAppInfo appInfo = new InstallAppInfo();
|
||||
appInfo.setApp_name(packageInfo.applicationInfo.loadLabel(packageManager).toString());
|
||||
@@ -572,4 +575,40 @@ public class ApkUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//通过包名获取版本号
|
||||
public static String getAPPVersionName(Context context, String packageName) {
|
||||
String versionName = "0";
|
||||
|
||||
if (TextUtils.isEmpty(packageName)) {
|
||||
return versionName;
|
||||
}
|
||||
PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
|
||||
versionName = packageInfo.versionName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return versionName;
|
||||
}
|
||||
|
||||
public static long getAppLastUpdateTime(Context context, String pkg) {
|
||||
if (TextUtils.isEmpty(pkg)) {
|
||||
return 0;
|
||||
}
|
||||
PackageManager pm = context.getPackageManager();
|
||||
PackageInfo packageInfo = null;
|
||||
try {
|
||||
packageInfo = pm.getPackageInfo(pkg, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (packageInfo == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return packageInfo.lastUpdateTime / 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
16
app/src/main/java/com/uiuipad/find/util/AppUtil.java
Normal file
16
app/src/main/java/com/uiuipad/find/util/AppUtil.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.uiuipad.find.util;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
public class AppUtil {
|
||||
private static final String TAG = AppUtil.class.getSimpleName();
|
||||
|
||||
public static void killPackage(Context context,String pkg) {
|
||||
Log.e(TAG, "killPackage: " + pkg);
|
||||
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
manager.killBackgroundProcesses(pkg);
|
||||
CmdUtil.execute("am force-stop " + pkg);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
package com.uiuipad.find.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
@@ -9,6 +14,9 @@ import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.qrcode.QRCodeWriter;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -65,4 +73,52 @@ public class BitmapUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drawable转换成一个Bitmap
|
||||
*
|
||||
* @param drawable drawable对象
|
||||
* @return
|
||||
*/
|
||||
public static final Bitmap drawableToBitmap(Drawable drawable) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
|
||||
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* drawable转为file
|
||||
*
|
||||
* @param mContext
|
||||
* @param drawable drawable
|
||||
* @param fileName 转换后的文件名
|
||||
* @return
|
||||
*/
|
||||
public static File drawableToFile(Context mContext, Drawable drawable, String fileName) {
|
||||
// InputStream is = view.getContext().getResources().openRawResource(R.drawable.logo);
|
||||
Bitmap bitmap = drawableToBitmap(drawable);
|
||||
// Bitmap bitmap = BitmapFactory.decodeStream(is);
|
||||
String defaultPath = Utils.getCacheDir(mContext) + "/iconCache";
|
||||
File file = new File(defaultPath);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
String defaultImgPath = defaultPath + "/" + fileName;
|
||||
File iconFile = new File(defaultImgPath);
|
||||
try {
|
||||
iconFile.createNewFile();
|
||||
FileOutputStream fOut = new FileOutputStream(iconFile);
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 20, fOut);
|
||||
// is.close();
|
||||
fOut.flush();
|
||||
fOut.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return iconFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,569 @@
|
||||
package com.uiuipad.find.util;
|
||||
|
||||
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();
|
||||
if (image == null) return;
|
||||
//我们可以将这帧数据转成字节数组,类似于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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public class ControlUtils {
|
||||
setActionBar(context, 1);
|
||||
// setNavigationBar(context, 0);
|
||||
setStatusBar(context);
|
||||
setTF(context, 0);
|
||||
setTF(context, 1);
|
||||
} else {
|
||||
int is_storeinstall = snSetting.getIs_storeinstall();
|
||||
int is_usb = snSetting.getIs_usb();
|
||||
|
||||
@@ -9,7 +9,11 @@ import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.PowerManager;
|
||||
import android.os.StatFs;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -31,7 +35,6 @@ public class Utils {
|
||||
*/
|
||||
@SuppressLint({"MissingPermission", "NewApi"})
|
||||
public static String getSerial() {
|
||||
// return JGYUtils.getInstance().getIMEI();
|
||||
String serial = "unknown";
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
|
||||
@@ -50,6 +53,36 @@ public class Utils {
|
||||
return serial;
|
||||
}
|
||||
|
||||
|
||||
public static String getIMEI(Context context) {
|
||||
String IMEI = "unknown";
|
||||
String IMEI1, IMEI2, IMEI3;
|
||||
//获取手机设备号
|
||||
TelephonyManager TelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
//8.0及以后版本获取
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
IMEI = TelephonyMgr.getDeviceId();
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// try {
|
||||
// Method method = TelephonyMgr.getClass().getMethod("getImei");
|
||||
// IMEI = (String) method.invoke(TelephonyMgr);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// Log.e("getIMEI", e.getMessage());
|
||||
// }
|
||||
// IMEI = TelephonyMgr.getDeviceId();
|
||||
|
||||
// } else {//9.0到10.0获取
|
||||
IMEI = Settings.System.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
}
|
||||
// Log.e("IMEI:", "IMEI: " + IMEI);
|
||||
if (null == IMEI) {
|
||||
return "-";
|
||||
} else {
|
||||
return IMEI.toUpperCase();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @return 获取WiFi名
|
||||
@@ -254,4 +287,27 @@ public class Utils {
|
||||
return getProperty("ro.build.display.id", "获取失败");
|
||||
// return Utils.getProperty("ro.custom.build.version", "获取失败");
|
||||
}
|
||||
|
||||
public static String getCacheDir(Context context) {
|
||||
String cachePath;
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|
||||
|| !Environment.isExternalStorageRemovable()) {
|
||||
if (context.getExternalCacheDir() != null) {
|
||||
cachePath = context.getExternalCacheDir().getPath();
|
||||
} else if (context.getExternalFilesDir("cache") != null) {
|
||||
cachePath = context.getExternalFilesDir("cache").getPath();
|
||||
} else {
|
||||
cachePath = context.getCacheDir().getPath();
|
||||
}
|
||||
} else {
|
||||
cachePath = context.getCacheDir().getPath();
|
||||
}
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
public static boolean isScreenOn(Context context) {
|
||||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
//true为打开,false为关闭
|
||||
return powerManager.isInteractive();
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 712 B |
Binary file not shown.
|
Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 1.3 KiB |
@@ -128,10 +128,10 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_20"
|
||||
android:layout_marginBottom="@dimen/dp_16"
|
||||
android:layout_marginBottom="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_8"
|
||||
android:textSize="@dimen/sp_6"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="绑定时间" />
|
||||
@@ -160,13 +160,13 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_serial1"
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:text="SN"
|
||||
android:text="设备SN"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -180,6 +180,7 @@
|
||||
android:text="序列号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_serial1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@@ -194,90 +195,11 @@
|
||||
android:singleLine="true"
|
||||
android:text="@string/unknown"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_10"
|
||||
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="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version1"
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:text="固件"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:text="版本号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_system_version1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:text="@string/unknown"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_9"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_ota"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_ota"
|
||||
android:layout_width="@dimen/dp_24"
|
||||
android:layout_height="@dimen/dp_24"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:src="@drawable/icon_upgrade"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_ota"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dp_20"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:background="@drawable/bt_default_normnl"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="检查更新"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_8"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -287,13 +209,13 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_app_version1"
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:text="软件"
|
||||
android:text="软件版本"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -307,6 +229,7 @@
|
||||
android:text="版本号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_app_version1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@@ -325,8 +248,8 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_app"
|
||||
android:layout_width="@dimen/dp_24"
|
||||
android:layout_height="@dimen/dp_24"
|
||||
android:layout_width="@dimen/dp_18"
|
||||
android:layout_height="@dimen/dp_18"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:src="@drawable/icon_upgrade"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
@@ -360,6 +283,86 @@
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:text="系统版本"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:text="版本号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_system_version1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:text="@string/unknown"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_9"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_ota"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_ota"
|
||||
android:layout_width="@dimen/dp_18"
|
||||
android:layout_height="@dimen/dp_18"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:src="@drawable/icon_upgrade"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_ota"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dp_20"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:background="@drawable/bt_default_normnl"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="检查更新"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_8"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -374,11 +377,11 @@
|
||||
android:id="@+id/tv_bind_statu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:layout_marginTop="@dimen/dp_8"
|
||||
android:text="设备绑定"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
@@ -128,10 +128,10 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_20"
|
||||
android:layout_marginBottom="@dimen/dp_16"
|
||||
android:layout_marginBottom="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_8"
|
||||
android:textSize="@dimen/sp_6"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:text="绑定时间" />
|
||||
@@ -160,13 +160,13 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_serial1"
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:text="SN"
|
||||
android:text="设备SN"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -180,6 +180,7 @@
|
||||
android:text="序列号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_serial1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@@ -194,90 +195,11 @@
|
||||
android:singleLine="true"
|
||||
android:text="@string/unknown"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_10"
|
||||
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="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version1"
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:maxLines="1"
|
||||
android:text="固件"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:text="版本号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_system_version1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:text="@string/unknown"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_9"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_ota"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_ota"
|
||||
android:layout_width="@dimen/dp_24"
|
||||
android:layout_height="@dimen/dp_24"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:src="@drawable/icon_upgrade"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_ota"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dp_20"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:background="@drawable/bt_default_normnl"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="检查更新"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_8"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@@ -287,13 +209,13 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_app_version1"
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:text="软件"
|
||||
android:text="软件版本"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -307,6 +229,7 @@
|
||||
android:text="版本号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_app_version1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@@ -325,8 +248,8 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_app"
|
||||
android:layout_width="@dimen/dp_24"
|
||||
android:layout_height="@dimen/dp_24"
|
||||
android:layout_width="@dimen/dp_18"
|
||||
android:layout_height="@dimen/dp_18"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:src="@drawable/icon_upgrade"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
@@ -360,6 +283,86 @@
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:maxLines="1"
|
||||
android:text="系统版本"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:text="版本号"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/tv_system_version1"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_system_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:text="@string/unknown"
|
||||
android:textColor="@color/text_gray"
|
||||
android:textSize="@dimen/sp_9"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iv_ota"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_ota"
|
||||
android:layout_width="@dimen/dp_18"
|
||||
android:layout_height="@dimen/dp_18"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:src="@drawable/icon_upgrade"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/cl_ota"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dp_20"
|
||||
android:layout_marginEnd="@dimen/dp_16"
|
||||
android:background="@drawable/bt_default_normnl"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="检查更新"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_8"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@@ -374,11 +377,11 @@
|
||||
android:id="@+id/tv_bind_statu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:layout_marginTop="@dimen/dp_8"
|
||||
android:text="设备绑定"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="@dimen/sp_10"
|
||||
android:textSize="@dimen/sp_9"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#efefef</color>
|
||||
<color name="colorPrimary">#f3f3f3</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#0480FF</color>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user