mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-06-05 21:49:48 +02:00
Zepp OS: Add gpx route file upload
This commit is contained in:
@@ -36,12 +36,15 @@ import de.greenrobot.dao.query.QueryBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.ZeppOsAgpsInstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.ZeppOsGpxRouteInstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuamiExtendedActivitySampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsShortcutCardsService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.services.ZeppOsConfigService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiLanguageType;
|
||||
@@ -50,8 +53,27 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.service
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
||||
public abstract AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context);
|
||||
|
||||
@Override
|
||||
public abstract InstallHandler findInstallHandler(final Uri uri, final Context context);
|
||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
if (supportsAgpsUpdates()) {
|
||||
final ZeppOsAgpsInstallHandler agpsInstallHandler = new ZeppOsAgpsInstallHandler(uri, context);
|
||||
if (agpsInstallHandler.isValid()) {
|
||||
return agpsInstallHandler;
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsGpxUploads()) {
|
||||
final ZeppOsGpxRouteInstallHandler gpxRouteInstallHandler = new ZeppOsGpxRouteInstallHandler(uri, context);
|
||||
if (gpxRouteInstallHandler.isValid()) {
|
||||
return gpxRouteInstallHandler;
|
||||
}
|
||||
}
|
||||
|
||||
final AbstractHuami2021FWInstallHandler handler = createFwInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsHeartRateMeasurement(final GBDevice device) {
|
||||
@@ -339,6 +361,14 @@ public abstract class Huami2021Coordinator extends HuamiCoordinator {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsAgpsUpdates() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsGpxUploads() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsControlCenter() {
|
||||
// TODO: Auto-detect control center?
|
||||
return false;
|
||||
|
||||
@@ -57,9 +57,8 @@ public class AmazfitBand7Coordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final AmazfitBand7FWInstallHandler handler = new AmazfitBand7FWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitBand7FWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,9 +57,8 @@ public class AmazfitGTR3Coordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final AmazfitGTR3FWInstallHandler handler = new AmazfitGTR3FWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitGTR3FWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,9 +57,8 @@ public class AmazfitGTR3ProCoordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final AmazfitGTR3ProFWInstallHandler handler = new AmazfitGTR3ProFWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitGTR3ProFWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,13 +25,12 @@ import androidx.annotation.NonNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.ZeppOsAgpsInstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||
|
||||
public class AmazfitGTR4Coordinator extends Huami2021Coordinator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTR4Coordinator.class);
|
||||
@@ -58,13 +57,8 @@ public class AmazfitGTR4Coordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final ZeppOsAgpsInstallHandler agpsInstallHandler = new ZeppOsAgpsInstallHandler(uri, context);
|
||||
if (agpsInstallHandler.isValid()) {
|
||||
return agpsInstallHandler;
|
||||
}
|
||||
final AmazfitGTR4FWInstallHandler handler = new AmazfitGTR4FWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitGTR4FWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,6 +66,16 @@ public class AmazfitGTR4Coordinator extends Huami2021Coordinator {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAgpsUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGpxUploads() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsControlCenter() {
|
||||
return true;
|
||||
|
||||
@@ -57,9 +57,8 @@ public class AmazfitGTS3Coordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final AmazfitGTS3FWInstallHandler handler = new AmazfitGTS3FWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitGTS3FWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,13 +25,12 @@ import androidx.annotation.NonNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.Huami2021Coordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos.ZeppOsAgpsInstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuami2021FWInstallHandler;
|
||||
|
||||
public class AmazfitGTS4Coordinator extends Huami2021Coordinator {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AmazfitGTS4Coordinator.class);
|
||||
@@ -58,13 +57,8 @@ public class AmazfitGTS4Coordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final ZeppOsAgpsInstallHandler agpsInstallHandler = new ZeppOsAgpsInstallHandler(uri, context);
|
||||
if (agpsInstallHandler.isValid()) {
|
||||
return agpsInstallHandler;
|
||||
}
|
||||
final AmazfitGTS4FWInstallHandler handler = new AmazfitGTS4FWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitGTS4FWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,6 +66,16 @@ public class AmazfitGTS4Coordinator extends Huami2021Coordinator {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAgpsUpdates() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsGpxUploads() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsControlCenter() {
|
||||
return true;
|
||||
|
||||
@@ -57,9 +57,8 @@ public class AmazfitGTS4MiniCoordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final AmazfitGTS4MiniFWInstallHandler handler = new AmazfitGTS4MiniFWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitGTS4MiniFWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,9 +57,8 @@ public class AmazfitTRex2Coordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final AmazfitTRex2FWInstallHandler handler = new AmazfitTRex2FWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new AmazfitTRex2FWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,9 +57,8 @@ public class MiBand7Coordinator extends Huami2021Coordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractHuami2021FWInstallHandler findInstallHandler(final Uri uri, final Context context) {
|
||||
final MiBand7FWInstallHandler handler = new MiBand7FWInstallHandler(uri, context);
|
||||
return handler.isValid() ? handler : null;
|
||||
public AbstractHuami2021FWInstallHandler createFwInstallHandler(final Uri uri, final Context context) {
|
||||
return new MiBand7FWInstallHandler(uri, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/* Copyright (C) 2023 José Rebelo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.huami.zeppos;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.zeppos.operations.ZeppOsGpxRouteFile;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.UriHelper;
|
||||
|
||||
public class ZeppOsGpxRouteInstallHandler implements InstallHandler {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ZeppOsGpxRouteInstallHandler.class);
|
||||
|
||||
protected final Context mContext;
|
||||
private ZeppOsGpxRouteFile file;
|
||||
|
||||
public ZeppOsGpxRouteInstallHandler(final Uri uri, final Context context) {
|
||||
this.mContext = context;
|
||||
|
||||
final UriHelper uriHelper;
|
||||
try {
|
||||
uriHelper = UriHelper.get(uri, context);
|
||||
} catch (final IOException e) {
|
||||
LOG.error("Failed to get uri", e);
|
||||
return;
|
||||
}
|
||||
try (InputStream in = new BufferedInputStream(uriHelper.openInputStream())) {
|
||||
final byte[] rawBytes = FileUtils.readAll(in, 1024 * 1024); // 1MB
|
||||
final ZeppOsGpxRouteFile gpxFile = new ZeppOsGpxRouteFile(rawBytes);
|
||||
if (gpxFile.isValid()) {
|
||||
this.file = gpxFile;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Failed to read file", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return file != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateInstallation(final InstallActivity installActivity, final GBDevice device) {
|
||||
if (device.isBusy()) {
|
||||
installActivity.setInfoText(device.getBusyTask());
|
||||
installActivity.setInstallEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!device.isInitialized()) {
|
||||
installActivity.setInfoText(mContext.getString(R.string.fwapp_install_device_not_ready));
|
||||
installActivity.setInstallEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final GenericItem fwItem = createInstallItem(device);
|
||||
fwItem.setIcon(device.getType().getIcon());
|
||||
|
||||
if (file == null) {
|
||||
fwItem.setDetails(mContext.getString(R.string.miband_fwinstaller_incompatible_version));
|
||||
installActivity.setInfoText(mContext.getString(R.string.fwinstaller_firmware_not_compatible_to_device));
|
||||
installActivity.setInstallEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final String gpxRoute = mContext.getString(R.string.kind_gpx_route);
|
||||
builder.append(mContext.getString(R.string.fw_upgrade_notice, gpxRoute));
|
||||
installActivity.setInfoText(builder.toString());
|
||||
installActivity.setInstallItem(fwItem);
|
||||
installActivity.setInstallEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartInstall(final GBDevice device) {
|
||||
}
|
||||
|
||||
public ZeppOsGpxRouteFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
private GenericItem createInstallItem(final GBDevice device) {
|
||||
final String firmwareName = mContext.getString(
|
||||
R.string.installhandler_firmware_name,
|
||||
mContext.getString(device.getType().getName()),
|
||||
mContext.getString(R.string.kind_gpx_route),
|
||||
file.getName()
|
||||
);
|
||||
return new GenericItem(firmwareName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user