From 7e8877a0db1f07f5f0f00901128efdf4b16f85b1 Mon Sep 17 00:00:00 2001 From: TongTongStudio Date: Fri, 21 Aug 2026 17:11:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(push):=20=E6=96=B0=E5=A2=9E=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E6=8B=8D=E7=85=A7=E6=8C=87=E4=BB=A4=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 MQTT 发布成功日志级别从 error 调整为 verbose - 修正 DEVICE_SHUTDOEN 拼写为 DEVICE_SHUTDOWN - 新增 DEVICE_TAKE_PHOTO 推送指令,支持远程拍照并上传 --- .../com/ttstd/dialer/manager/MqttManager.java | 2 +- .../com/ttstd/dialer/push/PushExecutor.java | 59 ++++++++++++++++++- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java b/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java index 3194d25..f807000 100644 --- a/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java +++ b/app/src/main/java/com/ttstd/dialer/manager/MqttManager.java @@ -371,7 +371,7 @@ public class MqttManager { if (throwable != null) { Logger.e(TAG, "publish: 发布失败 topic=" + topic + " " + throwable.getMessage()); } else { - Logger.e(TAG, "publish: 发布成功 topic=" + topic); + Logger.v(TAG, "publish: 发布成功 topic=" + topic); } }); } diff --git a/app/src/main/java/com/ttstd/dialer/push/PushExecutor.java b/app/src/main/java/com/ttstd/dialer/push/PushExecutor.java index 524ca78..cd81baf 100644 --- a/app/src/main/java/com/ttstd/dialer/push/PushExecutor.java +++ b/app/src/main/java/com/ttstd/dialer/push/PushExecutor.java @@ -3,6 +3,8 @@ package com.ttstd.dialer.push; import android.annotation.SuppressLint; import android.content.Context; import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.text.TextUtils; import android.util.Log; @@ -10,6 +12,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.ttstd.dialer.BuildConfig; +import com.ttstd.dialer.activity.settings.utils.SettingsUtilsActivity; import com.ttstd.dialer.bean.ApkInstalledInfo; import com.ttstd.dialer.bean.BaseResponse; import com.ttstd.dialer.bean.DeveloperOptions; @@ -25,6 +28,7 @@ import com.ttstd.dialer.mdm.DeviceManagerService; import com.ttstd.dialer.network.BaseObserver; import com.ttstd.dialer.network.OkHttpManager; import com.ttstd.dialer.utils.ApkUtils; +import com.ttstd.dialer.utils.CameraUtil; import com.ttstd.dialer.utils.SystemUtils; import com.ttstd.dialer.utils.CmdUtil; import com.ttstd.dialer.utils.Logger; @@ -33,7 +37,9 @@ import com.ttstd.iconloader.utils.FileUtils; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -43,6 +49,7 @@ import io.reactivex.rxjava3.core.Observer; import io.reactivex.rxjava3.disposables.Disposable; import io.reactivex.rxjava3.functions.Function; import io.reactivex.rxjava3.schedulers.Schedulers; +import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.RequestBody; @@ -58,7 +65,7 @@ public class PushExecutor { private static final String DEVICE_REFRESH = "1"; private static final String DEVICE_SCREEN_SNAPSHOT = "2"; private static final String DEVICE_REBOOT = "3"; - private static final String DEVICE_SHUTDOEN = "4"; + private static final String DEVICE_SHUTDOWN = "4"; private static final String DEVICE_LOCATE = "5"; private static final String DEVICE_RESTORE = "6"; private static final String DEVICE_DEVELOPER = "7"; @@ -66,6 +73,8 @@ public class PushExecutor { private static final String DEVICE_APP_CLEAR_DATA = "9"; private static final String DEVICE_APP_UNINSTALL = "10"; private static final String DEVICE_APP_STOP = "11"; + private static final String DEVICE_TAKE_PHOTO = "12"; + /** * 服务端业务码:图标已锁定,不可覆盖。 @@ -125,7 +134,7 @@ public class PushExecutor { case DEVICE_REBOOT: RebootUtils.rebootDevice(mContext, "push"); break; - case DEVICE_SHUTDOEN: + case DEVICE_SHUTDOWN: RebootUtils.shutdownDevice(mContext); case DEVICE_LOCATE: MapManager.getInstance().startLocation(); @@ -148,6 +157,9 @@ public class PushExecutor { case DEVICE_APP_STOP: stopApp(extra); break; + case DEVICE_TAKE_PHOTO: + takePhoto(); + break; default: Logger.e(TAG, "setPushMessage: default"); } @@ -405,6 +417,49 @@ public class PushExecutor { }); } + private void takePhoto() { + long createTime = System.currentTimeMillis() / 1000; + CameraUtil cameraUtil = new CameraUtil(mContext, new CameraUtil.CameraCallBack() { + @Override + public void onErr(String msg) { + Logger.e("CameraUtil", "onErr: " + msg); + } + + @Override + public void onTakePhotoOk(String path) { + Logger.e("CameraUtil", "onTakePhotoOk: " + path); + File file = new File(path); + + // 仿照 screenSnapshot,使用同一个上传截图接口上传拍照文件 + Observable.fromCallable(() -> file.exists() ? 0 : -1) + .subscribeOn(Schedulers.io()) + .flatMap(integer -> { + if (integer == 0) { + MultipartBody.Part part = OkHttpManager.getBodyPart("image/jpeg", "file", file); + return OkHttpManager.getInstance().getUploadScreenshotObservable(part) + .subscribeOn(Schedulers.io()); + } else { + return Observable.empty(); + } + }) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new BaseObserver() { + @Override + public void onSuccess(BaseResponse baseResponse) { + Log.e("takePhoto", "onSuccess: " + baseResponse.toString()); + } + + @Override + public void onFailure(Throwable e) { + Log.e("takePhoto", "onFailure: " + e.getMessage()); + } + }); + } + }); + cameraUtil.startTakePicture(FileUtils.getCacheDir(mContext) + File.separator + "cameracapture_" + File.separator + createTime + ".jpg"); + } + + /** * 从推送 extra 中解析 {@code package_name} 字段。 *