1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-07-22 06:41:06 +02:00

Add device menu item to get to the FW/App Installer via an explanation activity

This commit is contained in:
vanous 2022-07-06 23:09:36 +02:00
parent d051a6ed50
commit c77521f975
17 changed files with 248 additions and 5 deletions

View File

@ -32,6 +32,7 @@
* Support folders in device list
* Separate device settings which are specific to the application into Set preferences in device card
* When pairing devices with auth key requirements, only show Auth key menu related items on long press
* Provide access to the FW/App Installer via Set preferences in device card
* Animate card movement in device list
* Make transliteration configurable per-language
* Widget: do not show sleep if not recorded

View File

@ -435,6 +435,11 @@
android:label="@string/about_activity_title"
android:parentActivityName=".activities.ControlCenterv2"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".activities.OpenFwAppInstallerActivity"
android:label="@string/open_fw_installer_info_text_title"
android:parentActivityName=".activities.ControlCenterv2"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".activities.BatteryInfoActivity"
android:label="@string/battery_detail_activity_title"

View File

@ -216,12 +216,12 @@ public class FwAppInstallerActivity extends AbstractGBActivity implements Instal
List<GBDevice> selectedDevices = GBApplication.app().getDeviceManager().getSelectedDevices();
if(selectedDevices.size() == 0){
GB.toast("please connect the device you want to send to", Toast.LENGTH_LONG, GB.ERROR);
GB.toast(getString(R.string.open_fw_installer_connect_minimum_one_device), Toast.LENGTH_LONG, GB.ERROR);
finish();
return;
}
if(selectedDevices.size() != 1){
GB.toast("please connect ONLY the device you want to send to", Toast.LENGTH_LONG, GB.ERROR);
GB.toast(getString(R.string.open_fw_installer_connect_maximum_one_device), Toast.LENGTH_LONG, GB.ERROR);
finish();
return;
}

View File

@ -0,0 +1,93 @@
/* Copyright (C) 2015-2020 vanous,
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.activities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AppManagerActivity;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class OpenFwAppInstallerActivity extends AbstractGBActivity {
private static final Logger LOG = LoggerFactory.getLogger(AppManagerActivity.class);
private int READ_REQUEST_CODE = 42;
private GBDevice device;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if (extras != null) {
device = extras.getParcelable(GBDevice.EXTRA_DEVICE);
} else {
throw new IllegalArgumentException("Must provide a device when invoking this activity");
}
setContentView(R.layout.activity_open_fw_app_installer);
Button pickFileButton = findViewById(R.id.open_fw_installer_pick_button);
TextView label = findViewById(R.id.open_fw_installer_no_device);
label.setText(String.format(getString(R.string.open_fw_installer_select_file), device.getAliasOrName()));
final List<GBDevice> devices = ((GBApplication) getApplicationContext()).getDeviceManager().getSelectedDevices();
switch (devices.size()) {
case 0:
label.setText(R.string.open_fw_installer_connect_minimum_one_device);
pickFileButton.setEnabled(false);
break;
case 1:
label.setText(String.format(getString(R.string.open_fw_installer_select_file), device.getAliasOrName()));
pickFileButton.setEnabled(true);
break;
default:
label.setText(R.string.open_fw_installer_connect_maximum_one_device);
pickFileButton.setEnabled(false);
}
pickFileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Intent startIntent = new Intent(OpenFwAppInstallerActivity.this, FwAppInstallerActivity.class);
startIntent.putExtra(GBDevice.EXTRA_DEVICE, device);
startIntent.setAction(Intent.ACTION_VIEW);
startIntent.setDataAndType(resultData.getData(), null);
startActivity(startIntent);
}
}
}

View File

@ -75,6 +75,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
@ -92,6 +93,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureReminders;
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateDialog;
import nodomain.freeyourgadget.gadgetbridge.activities.OpenFwAppInstallerActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.VibrationActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsActivity;
@ -811,6 +813,11 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
}
}
private boolean showInstallerItem(GBDevice device) {
final DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
return coordinator.supportsAppsManagement() || coordinator.supportsFlashing();
}
private void showDeviceSubmenu(final View v, final GBDevice device) {
boolean deviceConnected = device.getState() != GBDevice.State.NOT_CONNECTED;
@ -823,6 +830,8 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
menu.getMenu().findItem(R.id.controlcenter_device_submenu_connect).setVisible(!deviceConnected);
menu.getMenu().findItem(R.id.controlcenter_device_submenu_disconnect).setVisible(deviceConnected);
menu.getMenu().findItem(R.id.controlcenter_device_submenu_show_details).setEnabled(showInfoIcon);
menu.getMenu().findItem(R.id.controlcenter_device_submenu_installer).setEnabled(deviceConnected);
menu.getMenu().findItem(R.id.controlcenter_device_submenu_installer).setVisible(showInstallerItem(device));
menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
@ -870,6 +879,11 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
case R.id.controlcenter_device_submenu_set_parent_folder:
showSetParentFolderDialog(device);
return true;
case R.id.controlcenter_device_submenu_installer:
Intent openFwIntent = new Intent(context, OpenFwAppInstallerActivity.class);
openFwIntent.putExtra(GBDevice.EXTRA_DEVICE, device);
context.startActivity(openFwIntent);
return false;
}
return false;
}

View File

@ -189,6 +189,9 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
return false;
}
@Override
public boolean supportsFlashing() { return false; }
@Override
public boolean supportsAppReordering() {
return false;

View File

@ -214,6 +214,14 @@ public interface DeviceCoordinator {
*/
SampleProvider<? extends ActivitySample> getSampleProvider(GBDevice device, DaoSession session);
/**
* Returns true if this device/coordinator supports installing files like firmware,
* watchfaces, gps, resources, fonts...
*
* @return
*/
boolean supportsFlashing();
/**
* Finds an install handler for the given uri that can install the given
* uri on the device being managed.

View File

@ -96,6 +96,9 @@ public abstract class HuamiCoordinator extends AbstractBLEDeviceCoordinator {
return false;
}
@Override
public boolean supportsFlashing() { return true; }
@Override
public Class<? extends Activity> getAppsManagementActivity() {
return null;

View File

@ -67,6 +67,9 @@ public class MiBand2HRXCoordinator extends HuamiCoordinator {
return null;
}
@Override
public boolean supportsFlashing() { return false; }
@Override
public boolean supportsAlarmSnoozing() {
return true;

View File

@ -107,6 +107,9 @@ public class PebbleCoordinator extends AbstractBLClassicDeviceCoordinator {
return installHandler.isValid() ? installHandler : null;
}
@Override
public boolean supportsFlashing() { return true; }
@Override
public boolean supportsActivityDataFetching() {
return false;

View File

@ -61,6 +61,9 @@ public class PineTimeJFCoordinator extends AbstractBLEDeviceCoordinator {
return handler.isValid() ? handler : null;
}
@Override
public boolean supportsFlashing() { return true; }
@Override
public boolean supportsActivityDataFetching() {
return false;

View File

@ -72,7 +72,7 @@ public class FossilHRInstallHandler implements InstallHandler {
return;
}
if (device.getType() != DeviceType.FOSSILQHYBRID || !device.isConnected() || !fossilFile.isValid()) {
installActivity.setInfoText("Element cannot be installed");
installActivity.setInfoText("Element cannot be installed 1, type: " + device.getType() + " device: "+ device + " is connected" + device.isConnected() + " is valid file:" + fossilFile.isValid());
installActivity.setInstallEnabled(false);
return;
}
@ -89,7 +89,7 @@ public class FossilHRInstallHandler implements InstallHandler {
installItem.setIcon(R.drawable.ic_watchface);
installActivity.setInfoText(mContext.getString(R.string.watchface_install_info, installItem.getName(), fossilFile.getVersion(), "(unknown)"));
} else {
installActivity.setInfoText("Element cannot be installed");
installActivity.setInfoText("Element cannot be installed 2");
installActivity.setInstallEnabled(false);
return;
}

View File

@ -85,7 +85,7 @@ public class FossilInstallHandler implements InstallHandler {
return;
}
if (device.getType() != DeviceType.FOSSILQHYBRID || !device.isConnected()) {
installActivity.setInfoText("Element cannot be installed");
installActivity.setInfoText("Element cannot be installed 3");
installActivity.setInstallEnabled(false);
return;
}

View File

@ -129,6 +129,9 @@ public class QHybridCoordinator extends AbstractBLEDeviceCoordinator {
return installHandler.isValid() ? installHandler : null;
}
@Override
public boolean supportsFlashing() { return false; }
@Override
public boolean supportsScreenshots() {
return false;

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/about_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/about_margin"
android:paddingRight="@dimen/about_margin"
tools:context="nodomain.freeyourgadget.gadgetbridge.activities.OpenFwAppInstallerActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/open_fw_installer_info_text_title"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textColor="@color/accent" />
<TextView
android:id="@+id/open_fw_desc_with_link"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:autoLink="web"
android:text="@string/open_fw_installer_info_text" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/open_fw_installer_warning_title"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@color/accent" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="@string/open_fw_installer_warning_text" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/open_fw_installer_getting_files_title"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textColor="@color/accent" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="@string/open_fw_installer_getting_files_text" />
<TextView
android:id="@+id/open_fw_installer_no_device"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingLeft="@dimen/about_margin"
android:paddingRight="@dimen/about_margin">
<Button
android:id="@+id/open_fw_installer_pick_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/open_fw_installer_pick_file" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@ -18,6 +18,10 @@
<item
android:id="@+id/controlcenter_device_submenu_show_details"
android:title="@string/controlcenter_toggle_details" />
<item
android:id="@+id/controlcenter_device_submenu_installer"
android:title="@string/open_fw_installer_info_text_title" />
<item
android:id="@+id/controlcenter_device_submenu_remove"
android:title="@string/controlcenter_delete_device" />

View File

@ -137,6 +137,18 @@
<string name="miband_firmware_known">This firmware has been tested and is known to be compatible with Gadgetbridge.</string>
<string name="miband_firmware_unknown_warning">"This firmware is untested and may not be compatible with Gadgetbridge.\n\nYou are DISCOURAGED from flashing it!"</string>
<string name="miband_firmware_suggest_whitelist">If you still want to proceed and things continue to work properly afterwards, please tell the Gadgetbridge developers to whitelist the %s firmware version.</string>
<!-- Strings related to the FwAppInstaller opener activity -->
<string name="open_fw_installer_info_text">The Firmware/Watchface/App/File Installer allows you to upload/install supported files (firmware, watchfaces, applications, GPS, resources, fonts...) to the device. See some more information in the wiki: https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Firmware-Update</string>
<string name="open_fw_installer_warning_title">Warning</string>
<string name="open_fw_installer_warning_text">This feature has the potential to brick your device. That said, this has never happened to any of the developers through flashing, but remember that you are doing this at your own risk.</string>
<string name="open_fw_installer_getting_files_title">Getting the firmware/app file</string>
<string name="open_fw_installer_getting_files_text">Since we may not distribute the firmware files, you will have to get the files yourself. This means that you will need to search for the files in apk files, online, in forums, on Amazfitwatchfaces (for Miband/Amazfit devices) and so on.</string>
<string name="open_fw_installer_pick_file">Select file</string>
<string name="open_fw_installer_info_text_title">File Installer</string>
<string name="open_fw_installer_select_file">Select a file you want to upload to device: %s</string>
<string name="open_fw_installer_connect_minimum_one_device">Please connect AT LEAST ONE device you want to send the file to.</string>
<string name="open_fw_installer_connect_maximum_one_device">Please connect ONLY ONE device you want to send the file to.</string>
<string name="open_fw_installer_ensure_device_connected">Make sure that the device %s is connected</string>
<!-- Strings related to Settings -->
<string name="title_activity_settings">Settings</string>
<string name="pref_header_general">General settings</string>