1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-26 15:00:13 +02:00

Needed fixes and updates after rebasing

This commit is contained in:
Arjan Schrijver 2023-12-23 23:36:21 +01:00
parent 346ad353a7
commit e2d09957b8
6 changed files with 180 additions and 121 deletions

View File

@ -600,11 +600,11 @@
<activity
android:name=".activities.ConfigureContacts"
android:label="@string/title_activity_set_contacts"
android:parentActivityName=".activities.ControlCenterv2" />
android:parentActivityName=".activities.MainActivity" />
<activity
android:name=".activities.widgets.WidgetScreensListActivity"
android:label="@string/menuitem_widgets"
android:parentActivityName=".activities.ControlCenterv2" />
android:parentActivityName=".activities.MainActivity" />
<activity
android:name=".activities.ConfigureWorldClocks"
android:label="@string/pref_world_clocks_title"

View File

@ -20,69 +20,27 @@
package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.toast;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.TypedValue;
import android.view.MenuItem;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.view.menu.MenuItemImpl;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.DialogFragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.discovery.DiscoveryActivityV2;
@ -93,9 +51,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GBChangeLog;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
@ -178,7 +133,7 @@ public class ControlCenterv2 extends Fragment {
refreshPairedDevices();
if (GB.isBluetoothEnabled() && deviceList.isEmpty() && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
startActivity(new Intent(getActivity(), DiscoveryActivity.class));
startActivity(new Intent(getActivity(), DiscoveryActivityV2.class));
} else {
GBApplication.deviceService().requestDeviceInfo();
}
@ -187,7 +142,7 @@ public class ControlCenterv2 extends Fragment {
}
private void launchDiscoveryActivity() {
startActivity(new Intent(getActivity(), DiscoveryActivity.class));
startActivity(new Intent(getActivity(), DiscoveryActivityV2.class));
}
private void showFabIfNeccessary() {
@ -216,8 +171,10 @@ public class ControlCenterv2 extends Fragment {
}
public void refreshPairedDevices() {
mGBDeviceAdapter.notifyDataSetChanged();
mGBDeviceAdapter.rebuildFolders();
if (mGBDeviceAdapter != null) {
mGBDeviceAdapter.notifyDataSetChanged();
mGBDeviceAdapter.rebuildFolders();
}
}
public RefreshTask createRefreshTask(String task, Context context) {
@ -228,7 +185,7 @@ public class ControlCenterv2 extends Fragment {
if(ACTION_CONNECT.equals(intent.getAction())) {
String btDeviceAddress = intent.getStringExtra("device");
if(btDeviceAddress!=null){
GBDevice candidate = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, this);
GBDevice candidate = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, getActivity());
if (candidate != null && !candidate.isConnected()) {
GBApplication.deviceService(candidate).connect();
}

View File

@ -19,7 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
@ -31,6 +30,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.MenuItem;
@ -48,7 +48,10 @@ import androidx.fragment.app.DialogFragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.color.DynamicColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
@ -66,18 +69,24 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBChangeLog;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class MainActivity extends AbstractGBActivity implements BottomNavigationView.OnNavigationItemSelectedListener, GBActivity {
private static final Logger LOG = LoggerFactory.getLogger(MainActivity.class);
public static final String ACTION_REQUEST_PERMISSIONS
= "nodomain.freeyourgadget.gadgetbridge.activities.controlcenter.requestpermissions";
public static final String ACTION_REQUEST_LOCATION_PERMISSIONS
= "nodomain.freeyourgadget.gadgetbridge.activities.controlcenter.requestlocationpermissions";
private boolean isLanguageInvalid = false;
private boolean isThemeInvalid = false;
private static PhoneStateListener fakeStateListener;
BottomNavigationView bottomNavigationView;
DashboardFragment dashboardFragment = new DashboardFragment();
ControlCenterv2 devicesFragment = new ControlCenterv2();
MainMenuFragment mainMenuFragment = new MainMenuFragment();
private BottomNavigationView bottomNavigationView;
private int activeFragment;
private DashboardFragment dashboardFragment = new DashboardFragment();
private ControlCenterv2 devicesFragment = new ControlCenterv2();
private MainMenuFragment mainMenuFragment = new MainMenuFragment();
//needed for KK compatibility
static {
@ -92,22 +101,26 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
case GBApplication.ACTION_LANGUAGE_CHANGE:
setLanguage(GBApplication.getLanguage(), true);
break;
case GBApplication.ACTION_THEME_CHANGE:
isThemeInvalid = true;
break;
case GBApplication.ACTION_QUIT:
finish();
break;
case DeviceManager.ACTION_DEVICES_CHANGED:
case GBApplication.ACTION_NEW_DATA:
if (devicesFragment.isResumed()) {
devicesFragment.createRefreshTask("get activity data", getApplication()).execute();
// mGBDeviceAdapter.rebuildFolders();
devicesFragment.refreshPairedDevices();
}
devicesFragment.createRefreshTask("get activity data", getApplication()).execute();
// mGBDeviceAdapter.rebuildFolders();
devicesFragment.refreshPairedDevices();
break;
case DeviceService.ACTION_REALTIME_SAMPLES:
handleRealtimeSample(intent.getSerializableExtra(DeviceService.EXTRA_REALTIME_SAMPLE));
break;
case ACTION_REQUEST_PERMISSIONS:
checkAndRequestPermissions(false);
checkAndRequestPermissions();
break;
case ACTION_REQUEST_LOCATION_PERMISSIONS:
checkAndRequestLocationPermissions();
break;
}
}
@ -139,21 +152,22 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
DynamicColors.applyToActivitiesIfAvailable(getApplication());
setContentView(R.layout.activity_main);
bottomNavigationView = findViewById(R.id.bottom_nav_bar);
bottomNavigationView.setOnNavigationItemSelectedListener(this);
// TODO: read last view from savedInstanceState
bottomNavigationView.setSelectedItemId(R.id.bottom_nav_dashboard);
activeFragment = R.id.bottom_nav_dashboard;
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(GBApplication.ACTION_LANGUAGE_CHANGE);
filterLocal.addAction(GBApplication.ACTION_THEME_CHANGE);
filterLocal.addAction(GBApplication.ACTION_QUIT);
filterLocal.addAction(GBApplication.ACTION_NEW_DATA);
filterLocal.addAction(DeviceManager.ACTION_DEVICES_CHANGED);
filterLocal.addAction(DeviceService.ACTION_REALTIME_SAMPLES);
filterLocal.addAction(ACTION_REQUEST_PERMISSIONS);
filterLocal.addAction(ACTION_REQUEST_LOCATION_PERMISSIONS);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
/*
@ -162,16 +176,27 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
Prefs prefs = GBApplication.getPrefs();
pesterWithPermissions = prefs.getBoolean("permission_pestering", true);
boolean displayPermissionDialog = !prefs.getBoolean("permission_dialog_displayed", false);
prefs.getPreferences().edit().putBoolean("permission_dialog_displayed", true).apply();
Set<String> set = NotificationManagerCompat.getEnabledListenerPackages(this);
if (pesterWithPermissions) {
if (!set.contains(this.getPackageName())) { // If notification listener access hasn't been granted
// Put up a dialog explaining why we need permissions (Polite, but also Play Store policy)
// When accepted, we open the Activity for Notification access
DialogFragment dialog = new MainActivity.NotifyListenerPermissionsDialogFragment();
DialogFragment dialog = new NotifyListenerPermissionsDialogFragment();
dialog.show(getSupportFragmentManager(), "NotifyListenerPermissionsDialogFragment");
}
}
/* We not put up dialogs explaining why we need permissions (Polite, but also Play Store policy).
Rather than chaining the calls, we just open a bunch of dialogs. Last in this list = first
on the page, and as they are accepted the permissions are requested in turn.
When accepted, we request it or open the Activity for permission to display over other apps. */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
/* In order to be able to set ringer mode to silent in GB's PhoneCallReceiver
the permission to access notifications is needed above Android M
@ -180,34 +205,72 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
if (!((NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE)).isNotificationPolicyAccessGranted()) {
// Put up a dialog explaining why we need permissions (Polite, but also Play Store policy)
// When accepted, we open the Activity for Notification access
DialogFragment dialog = new MainActivity.NotifyPolicyPermissionsDialogFragment();
DialogFragment dialog = new NotifyPolicyPermissionsDialogFragment();
dialog.show(getSupportFragmentManager(), "NotifyPolicyPermissionsDialogFragment");
}
}
if (!android.provider.Settings.canDrawOverlays(getApplicationContext())) {
if (!Settings.canDrawOverlays(getApplicationContext())) {
// If diplay over other apps access hasn't been granted
// Put up a dialog explaining why we need permissions (Polite, but also Play Store policy)
// When accepted, we open the Activity for permission to display over other apps.
if (pesterWithPermissions) {
DialogFragment dialog = new MainActivity.DisplayOverOthersPermissionsDialogFragment();
DialogFragment dialog = new DisplayOverOthersPermissionsDialogFragment();
dialog.show(getSupportFragmentManager(), "DisplayOverOthersPermissionsDialogFragment");
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_DENIED) {
if (pesterWithPermissions) {
DialogFragment dialog = new LocationPermissionsDialogFragment();
dialog.show(getSupportFragmentManager(), "LocationPermissionsDialogFragment");
}
}
// Check all the other permissions that we need to for Android M + later
checkAndRequestPermissions(true);
if (getWantedPermissions().isEmpty())
displayPermissionDialog = false;
if (displayPermissionDialog && pesterWithPermissions) {
DialogFragment dialog = new PermissionsDialogFragment();
dialog.show(getSupportFragmentManager(), "PermissionsDialogFragment");
// when 'ok' clicked, checkAndRequestPermissions() is called
} else
checkAndRequestPermissions();
}
GBChangeLog cl = GBChangeLog.createChangeLog(this);
boolean showChangelog = prefs.getBoolean("show_changelog", true);
if (showChangelog && cl.isFirstRun() && cl.hasChanges(cl.isFirstRunEver())) {
try {
cl.getMaterialLogDialog().show();
} catch (Exception ignored) {
GB.toast(this, "Error showing Changelog", Toast.LENGTH_LONG, GB.ERROR);
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("activeFragment", activeFragment); // Save variables into the Bundle
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
activeFragment = savedInstanceState.getInt("activeFragment"); // Retrieve variables from the Bundle
}
@Override
protected void onResume() {
super.onResume();
if (isLanguageInvalid) {
if (isLanguageInvalid || isThemeInvalid) {
isLanguageInvalid = false;
isThemeInvalid = false;
recreate();
}
updateFragment();
}
@Override
@ -218,36 +281,45 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
@Override
public boolean
onNavigationItemSelected(@NonNull MenuItem item)
{
// TODO: save current view so we can restore it in onCreate()
switch (item.getItemId()) {
onNavigationItemSelected(@NonNull MenuItem item) {
activeFragment = item.getItemId();
updateFragment();
return true;
}
private void updateFragment() {
switch (activeFragment) {
case R.id.bottom_nav_dashboard:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, dashboardFragment)
.commit();
return true;
break;
case R.id.bottom_nav_devices:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, devicesFragment)
.commit();
return true;
break;
case R.id.bottom_nav_menu:
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, mainMenuFragment)
.commit();
return true;
break;
}
}
private void checkAndRequestLocationPermissions() {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
LOG.error("No permission to access background location!");
GB.toast(getString(R.string.error_no_location_access), Toast.LENGTH_SHORT, GB.ERROR);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 0);
}
return false;
}
@TargetApi(Build.VERSION_CODES.M)
private void checkAndRequestPermissions(boolean showDialogFirst) {
private List<String> getWantedPermissions() {
List<String> wantedPermissions = new ArrayList<>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_DENIED)
@ -297,6 +369,9 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
}
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@ -314,12 +389,25 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.POST_NOTIFICATIONS);
}
}
if (BuildConfig.INTERNET_ACCESS) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.INTERNET) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.INTERNET);
}
}
return wantedPermissions;
}
@TargetApi(Build.VERSION_CODES.M)
private void checkAndRequestPermissions() {
List<String> wantedPermissions = getWantedPermissions();
if (!wantedPermissions.isEmpty()) {
Prefs prefs = GBApplication.getPrefs();
// If this is not the first run, we can rely on
@ -335,25 +423,17 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
}
}
wantedPermissions.removeAll(shouldNotAsk);
} else if (!showDialogFirst) {
} else {
// Permissions have not been asked yet, but now will be
prefs.getPreferences().edit().putBoolean("permissions_asked", true).apply();
}
if (!wantedPermissions.isEmpty()) {
if (showDialogFirst) {
// Show a dialog - this will then call checkAndRequestPermissions(false)
DialogFragment dialog = new LocationPermissionsDialogFragment();
dialog.show(getSupportFragmentManager(), "LocationPermissionsDialogFragment");
//requestMultiplePermissionsLauncher.launch(wantedPermissions.toArray(new String[0]));
GB.toast(this, getString(R.string.permission_granting_mandatory), Toast.LENGTH_LONG, GB.ERROR);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[0]), 0);
} else {
GB.toast(this, getString(R.string.permission_granting_mandatory), Toast.LENGTH_LONG, GB.ERROR);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[0]), 0);
} else {
requestMultiplePermissionsLauncher.launch(wantedPermissions.toArray(new String[0]));
//ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[0]), 0); //Actually this still works if I test it, not sure if the new way is more reliable or not...
}
requestMultiplePermissionsLauncher.launch(wantedPermissions.toArray(new String[0]));
}
}
}
@ -376,13 +456,12 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
AndroidUtils.setLanguage(this, language);
}
/// Called from onCreate - this puts up a dialog explaining we need permissions, and goes to the correct Activity
public static class NotifyPolicyPermissionsDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
final Context context = getContext();
builder.setMessage(context.getString(R.string.permission_notification_policy_access,
getContext().getString(R.string.app_name),
@ -406,7 +485,7 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
final Context context = getContext();
builder.setMessage(context.getString(R.string.permission_notification_listener,
getContext().getString(R.string.app_name),
@ -429,7 +508,7 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
Context context = getContext();
builder.setMessage(context.getString(R.string.permission_display_over_other_apps,
getContext().getString(R.string.app_name),
@ -448,21 +527,19 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
}
/// Called from checkAndRequestPermissions - this puts up a dialog explaining we need permissions, and then calls checkAndRequestPermissions (via an intent) when 'ok' pressed
/// Called from onCreate - this puts up a dialog explaining we need backgound location permissions, and then requests permissions when 'ok' pressed
public static class LocationPermissionsDialogFragment extends DialogFragment {
ControlCenterv2 controlCenter;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
Context context = getContext();
builder.setMessage(context.getString(R.string.permission_location,
getContext().getString(R.string.app_name),
getContext().getString(R.string.ok)))
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);
Intent intent = new Intent(ACTION_REQUEST_LOCATION_PERMISSIONS);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
});
@ -473,6 +550,8 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
// This is required here rather than where it is used because it'll cause a
// "LifecycleOwners must call register before they are STARTED" if not called from onCreate
public ActivityResultLauncher<String[]> requestMultiplePermissionsLauncher =
registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), isGranted -> {
if (isGranted.containsValue(true)) {
@ -487,4 +566,24 @@ public class MainActivity extends AbstractGBActivity implements BottomNavigation
GB.toast(this, getString(R.string.permission_granting_mandatory), Toast.LENGTH_LONG, GB.ERROR);
}
});
/// Called from onCreate - this puts up a dialog explaining we need permissions, and then requests permissions when 'ok' pressed
public static class PermissionsDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
Context context = getContext();
builder.setMessage(context.getString(R.string.permission_request,
getContext().getString(R.string.app_name),
getContext().getString(R.string.ok)))
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
});
return builder.create();
}
}
}

View File

@ -15,12 +15,12 @@ import androidx.fragment.app.Fragment;
import com.google.android.material.navigation.NavigationView;
import de.cketti.library.changelog.ChangeLog;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.activities.discovery.DiscoveryActivityV2;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBChangeLog;
public class MainMenuFragment extends Fragment implements NavigationView.OnNavigationItemSelectedListener {
public static final int MENU_REFRESH_CODE = 1;
@ -76,11 +76,15 @@ public class MainMenuFragment extends Fragment implements NavigationView.OnNavig
startActivity(i);
return false;
case R.id.external_changelog:
ChangeLog cl = createChangeLog();
GBChangeLog cl = GBChangeLog.createChangeLog(getActivity());
try {
cl.getLogDialog().show();
if (cl.hasChanges(false)) {
cl.getMaterialLogDialog().show();
} else {
cl.getMaterialFullLogDialog().show();
}
} catch (Exception ignored) {
GB.toast(getActivity().getBaseContext(), "Error showing Changelog", Toast.LENGTH_LONG, GB.ERROR);
GB.toast(getActivity(), "Error showing Changelog", Toast.LENGTH_LONG, GB.ERROR);
}
return false;
case R.id.about:
@ -92,16 +96,7 @@ public class MainMenuFragment extends Fragment implements NavigationView.OnNavig
return false;
}
private ChangeLog createChangeLog() {
String css = ChangeLog.DEFAULT_CSS;
css += "body { "
+ "color: " + AndroidUtils.getTextColorHex(getActivity().getBaseContext()) + "; "
+ "background-color: " + AndroidUtils.getBackgroundColorHex(getActivity().getBaseContext()) + ";" +
"}";
return new ChangeLog(getContext(), css);
}
private void launchDiscoveryActivity() {
startActivity(new Intent(getActivity(), DiscoveryActivity.class));
startActivity(new Intent(getActivity(), DiscoveryActivityV2.class));
}
}

View File

@ -1437,7 +1437,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
@RequiresApi(api = Build.VERSION_CODES.R)
void createDynamicShortcut(GBDevice device) {
Intent intent = new Intent(context, ControlCenterv2.class)
Intent intent = new Intent(context, MainActivity.class)
.setAction(ACTION_CONNECT)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.putExtra("device", device.getAddress());

View File

@ -104,4 +104,12 @@ public class GBChangeLog extends ChangeLog {
return builder.create();
}
public static GBChangeLog createChangeLog(Context context) {
String css = GBChangeLog.DEFAULT_CSS;
css += "body { "
+ "color: " + AndroidUtils.getTextColorHex(context) + "; "
+ "}";
return new GBChangeLog(context, css);
}
}