1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-15 09:30:30 +02:00
Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java

672 lines
34 KiB
Java
Raw Normal View History

/* Copyright (C) 2016-2024 Andreas Shimokawa, Andrzej Surowiec, Arjan
Schrijver, Carsten Pfeiffer, Daniel Dakhno, Daniele Gobbetti, Ganblejs,
gfwilliams, Gordon Williams, Johannes Tysiak, José Rebelo, marco.altomonte,
Petr Vaněk, Taavi Eomäe
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 <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
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.DialogInterface;
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;
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
import android.provider.Settings;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
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.navigation.NavController;
import androidx.navigation.NavGraph;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.NavigationUI;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.navigation.NavigationView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
2020-07-31 14:05:45 +02:00
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
2023-08-31 23:23:10 +02:00
import nodomain.freeyourgadget.gadgetbridge.activities.discovery.DiscoveryActivityV2;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBChangeLog;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
//TODO: extend AbstractGBActivity, but it requires actionbar that is not available
public class ControlCenterv2 extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, GBActivity {
private static final Logger LOG = LoggerFactory.getLogger(ControlCenterv2.class);
public static final int MENU_REFRESH_CODE = 1;
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;
//needed for KK compatibility
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (Objects.requireNonNull(action)) {
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 DeviceService.ACTION_REALTIME_SAMPLES:
handleRealtimeSample(intent.getSerializableExtra(DeviceService.EXTRA_REALTIME_SAMPLE));
break;
case ACTION_REQUEST_PERMISSIONS:
checkAndRequestPermissions();
break;
case ACTION_REQUEST_LOCATION_PERMISSIONS:
checkAndRequestLocationPermissions();
break;
}
}
};
private boolean pesterWithPermissions = true;
private ActivitySample currentHRSample;
public ActivitySample getCurrentHRSample() {
return currentHRSample;
}
private void setCurrentHRSample(ActivitySample sample) {
if (HeartRateUtils.getInstance().isValidHeartRateValue(sample.getHeartRate())) {
currentHRSample = sample;
}
}
private void handleRealtimeSample(Serializable extra) {
if (extra instanceof ActivitySample) {
ActivitySample sample = (ActivitySample) extra;
setCurrentHRSample(sample);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
AbstractGBActivity.init(this, AbstractGBActivity.NO_ACTIONBAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Prefs prefs = GBApplication.getPrefs();
boolean activityTrackerAvailable = false;
List<GBDevice> devices = GBApplication.app().getDeviceManager().getDevices();
for (GBDevice dev : devices) {
if (dev.getDeviceCoordinator().supportsActivityTracking()) {
activityTrackerAvailable = true;
break;
}
}
NavHostFragment navHostFragment = (NavHostFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
NavController navController = navHostFragment.getNavController();
if (!prefs.getBoolean("dashboard_as_default_view", true) || !activityTrackerAvailable) {
NavGraph navGraph = navController.getNavInflater().inflate(R.navigation.main);
navGraph.setStartDestination(R.id.bottom_nav_devices);
navController.setGraph(navGraph);
}
BottomNavigationView navigationView = findViewById(R.id.bottom_nav_bar);
NavigationUI.setupWithNavController(navigationView, navController);
navigationView.setVisibility(activityTrackerAvailable ? View.VISIBLE : View.GONE);
NavigationView drawerNavigationView = findViewById(R.id.nav_view);
drawerNavigationView.setNavigationItemSelectedListener(this);
MaterialToolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.controlcenter_navigation_drawer_open, R.string.controlcenter_navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
if (GBApplication.areDynamicColorsEnabled()) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getTheme();
theme.resolveAttribute(R.attr.colorSurface, typedValue, true);
@ColorInt int toolbarBackground = typedValue.data;
toolbar.setBackgroundColor(toolbarBackground);
} else {
toolbar.setBackgroundColor(getResources().getColor(R.color.primarydark_light));
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
}
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(GBApplication.ACTION_LANGUAGE_CHANGE);
filterLocal.addAction(GBApplication.ACTION_THEME_CHANGE);
filterLocal.addAction(GBApplication.ACTION_QUIT);
filterLocal.addAction(DeviceService.ACTION_REALTIME_SAMPLES);
filterLocal.addAction(ACTION_REQUEST_PERMISSIONS);
filterLocal.addAction(ACTION_REQUEST_LOCATION_PERMISSIONS);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
/*
* Ask for permission to intercept notifications on first run.
*/
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 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
ACCESS_NOTIFICATION_POLICY is also needed in the manifest */
if (pesterWithPermissions) {
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 NotifyPolicyPermissionsDialogFragment();
dialog.show(getSupportFragmentManager(), "NotifyPolicyPermissionsDialogFragment");
}
}
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
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 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");
}
}
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
// Check all the other permissions that we need to for Android M + later
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, getString(R.string.error_showing_changelog), Toast.LENGTH_LONG, GB.ERROR);
}
}
}
@Override
protected void onResume() {
super.onResume();
handleShortcut(getIntent());
if (isLanguageInvalid || isThemeInvalid) {
isLanguageInvalid = false;
isThemeInvalid = false;
recreate();
}
}
@Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
super.onDestroy();
}
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
switch (item.getItemId()) {
case R.id.action_settings:
Intent settingsIntent = new Intent(this, SettingsActivity.class);
2019-09-16 17:44:59 +02:00
startActivityForResult(settingsIntent, MENU_REFRESH_CODE);
return false; //we do not want the drawer menu item to get selected
case R.id.action_debug:
Intent debugIntent = new Intent(this, DebugActivity.class);
startActivity(debugIntent);
return false;
case R.id.action_data_management:
Intent dbIntent = new Intent(this, DataManagementActivity.class);
startActivity(dbIntent);
return false;
case R.id.action_notification_management:
Intent blIntent = new Intent(this, NotificationManagementActivity.class);
startActivity(blIntent);
return false;
case R.id.device_action_discover:
launchDiscoveryActivity();
return false;
case R.id.action_quit:
GBApplication.quit();
return false;
case R.id.donation_link:
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("https://liberapay.com/Gadgetbridge")); //TODO: centralize if ever used somewhere else
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
return false;
case R.id.external_changelog:
2023-08-09 20:37:27 +02:00
GBChangeLog cl = createChangeLog();
try {
2023-08-09 20:37:27 +02:00
if (cl.hasChanges(false)) {
cl.getMaterialLogDialog().show();
} else {
cl.getMaterialFullLogDialog().show();
}
} catch (Exception ignored) {
GB.toast(getBaseContext(), getString(R.string.error_showing_changelog), Toast.LENGTH_LONG, GB.ERROR);
}
return false;
2020-07-11 17:04:29 +02:00
case R.id.about:
Intent aboutIntent = new Intent(this, AboutActivity.class);
startActivity(aboutIntent);
return false;
}
return false;
}
2023-08-09 20:37:27 +02:00
private GBChangeLog createChangeLog() {
String css = GBChangeLog.DEFAULT_CSS;
css += "body { "
+ "color: " + AndroidUtils.getTextColorHex(getBaseContext()) + "; "
+ "}";
2023-08-09 20:37:27 +02:00
return new GBChangeLog(this, css);
}
private void launchDiscoveryActivity() {
startActivity(new Intent(this, DiscoveryActivityV2.class));
}
private void handleShortcut(Intent intent) {
if(ACTION_CONNECT.equals(intent.getAction())) {
String btDeviceAddress = intent.getStringExtra("device");
if(btDeviceAddress!=null){
GBDevice candidate = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, this);
if (candidate != null && !candidate.isConnected()) {
GBApplication.deviceService(candidate).connect();
}
}
}
}
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);
}
}
@TargetApi(Build.VERSION_CODES.M)
private List<String> getWantedPermissions() {
List<String> wantedPermissions = new ArrayList<>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.BLUETOOTH);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.BLUETOOTH_ADMIN);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.READ_CONTACTS);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.CALL_PHONE);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.READ_CALL_LOG);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.READ_PHONE_STATE);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.RECEIVE_SMS);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.READ_SMS);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.SEND_SMS);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.READ_CALENDAR);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.MEDIA_CONTENT_CONTROL) == PackageManager.PERMISSION_DENIED)
wantedPermissions.add(Manifest.permission.MEDIA_CONTENT_CONTROL);
} catch (Exception ignored) {
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (pesterWithPermissions) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.ANSWER_PHONE_CALLS);
}
}
}
2023-06-02 17:57:44 +02:00
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && Build.VERSION.SDK_INT <= Build.VERSION_CODES.S) {
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);
}
}
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.QUERY_ALL_PACKAGES) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.QUERY_ALL_PACKAGES);
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.BLUETOOTH_SCAN);
}
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED) {
wantedPermissions.add(Manifest.permission.BLUETOOTH_CONNECT);
}
}
2023-06-02 17:57:44 +02:00
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);
}
}
2022-03-31 11:36:26 +02:00
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
// shouldShowRequestPermissionRationale(String permission)
// and ignore permissions that shouldn't or can't be requested again
if (prefs.getBoolean("permissions_asked", false)) {
// Don't request permissions that we shouldn't show a prompt for
// e.g. permissions that are "Never" granted by the user or never granted by the system
Set<String> shouldNotAsk = new HashSet<>();
for (String wantedPermission : wantedPermissions) {
if (!shouldShowRequestPermissionRationale(wantedPermission)) {
shouldNotAsk.add(wantedPermission);
}
}
wantedPermissions.removeAll(shouldNotAsk);
} else {
// Permissions have not been asked yet, but now will be
prefs.getPreferences().edit().putBoolean("permissions_asked", true).apply();
}
if (!wantedPermissions.isEmpty()) {
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]));
}
}
}
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { // The enclosed hack in it's current state cause crash on Banglejs builds tarkgetSDK=31 on a Android 13 device.
// HACK: On Lineage we have to do this so that the permission dialog pops up
if (fakeStateListener == null) {
fakeStateListener = new PhoneStateListener();
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(fakeStateListener, PhoneStateListener.LISTEN_CALL_STATE);
telephonyManager.listen(fakeStateListener, PhoneStateListener.LISTEN_NONE);
}
}
}
public void setLanguage(Locale language, boolean invalidateLanguage) {
if (invalidateLanguage) {
isLanguageInvalid = true;
}
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
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),
getContext().getString(R.string.ok)))
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
@RequiresApi(api = Build.VERSION_CODES.M)
public void onClick(DialogInterface dialog, int id) {
try {
startActivity(new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS));
} catch (ActivityNotFoundException e) {
GB.toast(context, "'Notification Policy' activity not found", Toast.LENGTH_LONG, GB.ERROR);
}
}
});
return builder.create();
}
}
/// Called from onCreate - this puts up a dialog explaining we need permissions, and goes to the correct Activity
public static class NotifyListenerPermissionsDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
final Context context = getContext();
builder.setMessage(context.getString(R.string.permission_notification_listener,
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) {
try {
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
} catch (ActivityNotFoundException e) {
GB.toast(context, "'Notification Listener Settings' activity not found", Toast.LENGTH_LONG, GB.ERROR);
}
}
});
return builder.create();
}
}
/// Called from onCreate - this puts up a dialog explaining we need permissions, and goes to the correct Activity
public static class DisplayOverOthersPermissionsDialogFragment 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_display_over_other_apps,
getContext().getString(R.string.app_name),
getContext().getString(R.string.ok)))
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
@RequiresApi(api = Build.VERSION_CODES.M)
public void onClick(DialogInterface dialog, int id) {
Intent enableIntent = new Intent(android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(enableIntent);
}
}).setNegativeButton(R.string.dismiss, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {}
});
return builder.create();
}
}
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
/// 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 {
@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_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_LOCATION_PERMISSIONS);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
});
return builder.create();
}
}
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
// 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
Bangle.js: Bump flavor targetSdkVersion to 31 This also touches parts of the app not only used for bangle.js. E.g. pending intents gets new flags from SDK 23 inclusive. Bluetooth permissions are updated to work on SDK 31. Permission handling is updated to the new way for doing it with introduction of a new function. This is called for newer sdk versions. bump Bangle.js flavor targetSdkVersion to 31 update comments re SDK 31 set the 'exported=true' I introduced to false instead - except for three places add uses-permission for handling bluetooth in order to work on api >30 add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30 add link to bluetooth documentation Add comment to banglejs manifest. Add requirement annotation to ControlCenterv bump compileSdkVersion to 31 add "OpenAppSettings" permission popup while working out individual permission popups on android 13 if SDK < 31 do permissions one by one, else send user to app info page to switch permissions manually working solution, but needs cleaning do some cleaning, not done though remove some logging remove import Log tweak and remove toasts in new permissions handling Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else Revert "Change conditions `> Build.VERSION_CODES.Q` to `>= Build.VERSION_CODES.R` matching the style used everywhere else" This reverts commit 2929629ff43fbb685eb3d15e42459f321f68fa11. Revert "add if-blocks adding FLAG_IMMUTABLE to PendingIntents on api >30" This reverts commit ed8e1df7bb8b71fee745fbf9d10747d47c8f6cb8. Pending intents gets `PendingIntent.FLAG_IMMUTABLE` if `(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)`. Bangle.js: undo `@RequiresApi` code R ... to remove error in Android Studio where declared required api was higher then minSDK version. Use FLAG_MUTABLE for reply to test notification This should fix Gadgetbridge crashing when replying to the test notification from the debug activity. As reported here: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/2924#issuecomment-917282 Change to use FLAG_IMMUTABLE/_MUTABLE from SDK 23 ... as suggested by Android Studio. This is supposed to make the app more secure by not allowing certain changes to pending intents where they are not expected. If I understood correctly. Add PendingIntentUtils class to manage mutability
2022-10-09 14:53:04 +02:00
public ActivityResultLauncher<String[]> requestMultiplePermissionsLauncher =
registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), isGranted -> {
if (isGranted.containsValue(true)) {
// Permission is granted. Continue the action or workflow in your
// app.
} else {
// Explain to the user that the feature is unavailable because the
// feature requires a permission that the user has denied. At the
// same time, respect the user's decision. Don't link to system
// settings in an effort to convince the user to change their
// decision.
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();
}
}
}