mirror of
https://github.com/oliexdev/openScale.git
synced 2025-08-16 13:44:26 +02:00
update request runtime permissions to new Android methods
This commit is contained in:
@@ -2,12 +2,12 @@ apply plugin: 'com.android.application'
|
||||
apply plugin: "androidx.navigation.safeargs"
|
||||
|
||||
android {
|
||||
compileSdkVersion 32
|
||||
compileSdkVersion 33
|
||||
defaultConfig {
|
||||
applicationId "com.health.openscale"
|
||||
testApplicationId "com.health.openscale.test"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 32
|
||||
targetSdkVersion 33
|
||||
versionCode 61
|
||||
versionName "2.4.6"
|
||||
|
||||
@@ -139,9 +139,9 @@ android {
|
||||
dependencies {
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
implementation 'com.google.android.material:material:1.8.0-alpha03'
|
||||
implementation 'com.google.android.material:material:1.8.0-rc01'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.preference:preference:1.2.0'
|
||||
|
@@ -18,6 +18,7 @@ package com.health.openscale.gui;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
@@ -28,12 +29,14 @@ import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Typeface;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.InputFilter;
|
||||
@@ -51,10 +54,13 @@ import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.core.view.GravityCompat;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
@@ -77,7 +83,6 @@ import com.health.openscale.gui.measurement.MeasurementEntryFragment;
|
||||
import com.health.openscale.gui.preferences.BluetoothSettingsFragment;
|
||||
import com.health.openscale.gui.preferences.UserSettingsFragment;
|
||||
import com.health.openscale.gui.slides.AppIntroActivity;
|
||||
import com.health.openscale.gui.utils.PermissionHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -100,7 +105,6 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
private static final int IMPORT_DATA_REQUEST = 100;
|
||||
private static final int EXPORT_DATA_REQUEST = 101;
|
||||
private static final int ENABLE_BLUETOOTH_REQUEST = 102;
|
||||
private static final int APPINTRO_REQUEST = 103;
|
||||
|
||||
private AppBarConfiguration mAppBarConfiguration;
|
||||
@@ -532,7 +536,6 @@ public class MainActivity extends AppCompatActivity
|
||||
boolean hasBluetooth = bluetoothManager.getAdapter() != null;
|
||||
|
||||
if (!hasBluetooth) {
|
||||
bluetoothStatus.setEnabled(false);
|
||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_disabled);
|
||||
}
|
||||
// Just search for a bluetooth device just once at the start of the app and if start preference enabled
|
||||
@@ -571,6 +574,54 @@ public class MainActivity extends AppCompatActivity
|
||||
return;
|
||||
}
|
||||
|
||||
Timber.d("Main Activity Bluetooth permission check");
|
||||
|
||||
int targetSdkVersion = getApplicationInfo().targetSdkVersion;
|
||||
|
||||
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
BluetoothAdapter btAdapter = bluetoothManager.getAdapter();
|
||||
|
||||
// Check if Bluetooth is enabled
|
||||
if (btAdapter == null || !btAdapter.isEnabled()) {
|
||||
Timber.d("Bluetooth is not enabled");
|
||||
Toast.makeText(this, "Bluetooth " + getResources().getString(R.string.info_is_not_enable), Toast.LENGTH_SHORT).show();
|
||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_disabled);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if Bluetooth 4.x is available
|
||||
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||
Timber.d("No Bluetooth 4.x available");
|
||||
Toast.makeText(this, "Bluetooth 4.x " + getResources().getString(R.string.info_is_not_available), Toast.LENGTH_SHORT).show();
|
||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_disabled);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if GPS or Network location service is enabled
|
||||
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
|
||||
if (!(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
|
||||
Timber.d("No GPS or Network location service is enabled, ask user for permission");
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.permission_bluetooth_info_title);
|
||||
builder.setIcon(R.drawable.ic_preferences_about);
|
||||
builder.setMessage(R.string.permission_location_service_info);
|
||||
builder.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
// Show location settings when the user acknowledges the alert dialog
|
||||
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
|
||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_disabled);
|
||||
return;
|
||||
}
|
||||
|
||||
String deviceName = prefs.getString(
|
||||
BluetoothSettingsFragment.PREFERENCE_KEY_BLUETOOTH_DEVICE_NAME, "");
|
||||
String hwAddress = prefs.getString(
|
||||
@@ -582,21 +633,58 @@ public class MainActivity extends AppCompatActivity
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
|
||||
if (!bluetoothManager.getAdapter().isEnabled()) {
|
||||
setBluetoothStatusIcon(R.drawable.ic_bluetooth_connection_lost);
|
||||
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||
startActivityForResult(enableBtIntent, ENABLE_BLUETOOTH_REQUEST);
|
||||
return;
|
||||
}
|
||||
String[] requiredPermissions;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.S) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && targetSdkVersion >= Build.VERSION_CODES.S) {
|
||||
Timber.d("SDK >= 31 request for Bluetooth Scan and Bluetooth connect permissions");
|
||||
requestPermissions(new String[]{Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT}, PermissionHelper.PERMISSIONS_REQUEST_ACCESS_BLUETOOTH);
|
||||
return;
|
||||
requiredPermissions = new String[]{Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT};
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) {
|
||||
Timber.d("SDK >= 29 request for Access fine location permission");
|
||||
requiredPermissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
|
||||
} else {
|
||||
Timber.d("SDK < 29 request for coarse location permission");
|
||||
requiredPermissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
|
||||
}
|
||||
|
||||
connectToBluetooth();
|
||||
if (hasPermissions(requiredPermissions)) {
|
||||
connectToBluetooth();
|
||||
} else if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
Timber.d("No access fine location permission granted");
|
||||
|
||||
builder.setMessage(R.string.permission_bluetooth_info)
|
||||
.setTitle(R.string.permission_bluetooth_info_title)
|
||||
.setIcon(R.drawable.ic_preferences_about)
|
||||
.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.dismiss();
|
||||
requestPermissionBluetoothLauncher.launch(requiredPermissions);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
} else if (shouldShowRequestPermissionRationale(Manifest.permission.BLUETOOTH_SCAN)) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
Timber.d("No access Bluetooth scan permission granted");
|
||||
|
||||
builder.setMessage(R.string.permission_bluetooth_info)
|
||||
.setTitle(R.string.permission_bluetooth_info_title)
|
||||
.setIcon(R.drawable.ic_preferences_about)
|
||||
.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.dismiss();
|
||||
requestPermissionBluetoothLauncher.launch(requiredPermissions);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
} else {
|
||||
requestPermissionBluetoothLauncher.launch(requiredPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
private void connectToBluetooth() {
|
||||
@@ -900,48 +988,12 @@ public class MainActivity extends AppCompatActivity
|
||||
startActivity(Intent.createChooser(intent, getResources().getString(R.string.label_share)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
switch (requestCode) {
|
||||
case PermissionHelper.PERMISSIONS_REQUEST_ACCESS_BLUETOOTH: {
|
||||
boolean allGranted = true;
|
||||
for (int result : grantResults) {
|
||||
if (result != PackageManager.PERMISSION_GRANTED) {
|
||||
allGranted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allGranted) {
|
||||
Timber.d("All Bluetooth permissions granted");
|
||||
connectToBluetooth();
|
||||
} else {
|
||||
Timber.d("At least one Bluetooth permission was not granted");
|
||||
Toast.makeText(this, R.string.permission_not_granted, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
OpenScale openScale = OpenScale.getInstance();
|
||||
|
||||
if (requestCode == ENABLE_BLUETOOTH_REQUEST) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
invokeConnectToBluetoothDevice();
|
||||
}
|
||||
else {
|
||||
Toast.makeText(this, "Bluetooth " + getResources().getString(R.string.info_is_not_enable), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestCode == APPINTRO_REQUEST) {
|
||||
if (openScale.getSelectedScaleUserId() == -1) {
|
||||
MobileNavigationDirections.ActionNavMobileNavigationToNavUsersettings action = MobileNavigationDirections.actionNavMobileNavigationToNavUsersettings();
|
||||
@@ -992,4 +1044,29 @@ public class MainActivity extends AppCompatActivity
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasPermissions(String[] permissions) {
|
||||
if (permissions != null) {
|
||||
for (String permission : permissions) {
|
||||
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
Timber.d("Permission is not granted: " + permission);
|
||||
return false;
|
||||
}
|
||||
Timber.d("Permission already granted: " + permission);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ActivityResultLauncher<String[]> requestPermissionBluetoothLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), isGranted -> {
|
||||
if (isGranted.containsValue(false)) {
|
||||
Timber.d("At least one Bluetooth permission was not granted");
|
||||
Toast.makeText(this, getString(R.string.label_bluetooth_title) + ": " + getString(R.string.permission_not_granted), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
else {
|
||||
connectToBluetooth();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ package com.health.openscale.gui.preferences;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@@ -28,6 +29,9 @@ import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.CheckBoxPreference;
|
||||
import androidx.preference.Preference;
|
||||
@@ -37,7 +41,6 @@ import com.health.openscale.R;
|
||||
import com.health.openscale.core.OpenScale;
|
||||
import com.health.openscale.core.alarm.AlarmBackupHandler;
|
||||
import com.health.openscale.core.alarm.ReminderBootReceiver;
|
||||
import com.health.openscale.gui.utils.PermissionHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -138,7 +141,12 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share
|
||||
if (autoBackup.isChecked()) {
|
||||
isAutoBackupAskForPermission = true;
|
||||
|
||||
PermissionHelper.requestWritePermission(fragment);
|
||||
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
exportBackup();
|
||||
} else {
|
||||
requestPermissionExportLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -148,10 +156,16 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share
|
||||
private class onClickListenerImportBackup implements Preference.OnPreferenceClickListener {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
if (PermissionHelper.requestReadPermission(fragment)) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
importBackup();
|
||||
} else {
|
||||
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
importBackup();
|
||||
} else {
|
||||
requestPermissionImportLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -161,8 +175,13 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
exportBackup();
|
||||
} else if (PermissionHelper.requestWritePermission(fragment)) {
|
||||
exportBackup();
|
||||
} else {
|
||||
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
== PackageManager.PERMISSION_GRANTED) {
|
||||
exportBackup();
|
||||
} else {
|
||||
requestPermissionExportLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -232,36 +251,35 @@ public class BackupPreferences extends PreferenceFragmentCompat implements Share
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case PermissionHelper.PERMISSIONS_REQUEST_ACCESS_READ_STORAGE:
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
menu.clear();
|
||||
}
|
||||
|
||||
private ActivityResultLauncher<String> requestPermissionImportLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
|
||||
if (isGranted) {
|
||||
importBackup();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Toast.makeText(getContext(), getResources().getString(R.string.permission_not_granted), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
case PermissionHelper.PERMISSIONS_REQUEST_ACCESS_WRITE_STORAGE:
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
});
|
||||
|
||||
private ActivityResultLauncher<String> requestPermissionExportLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
|
||||
if (isGranted) {
|
||||
if (isAutoBackupAskForPermission) {
|
||||
autoBackup.setChecked(true);
|
||||
} else {
|
||||
exportBackup();
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (isAutoBackupAskForPermission) {
|
||||
autoBackup.setChecked(false);
|
||||
}
|
||||
|
||||
Toast.makeText(getContext(), getResources().getString(R.string.permission_not_granted), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
menu.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -15,9 +15,14 @@
|
||||
*/
|
||||
package com.health.openscale.gui.preferences;
|
||||
|
||||
import android.app.Activity;
|
||||
import static android.content.Context.LOCATION_SERVICE;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -26,12 +31,15 @@ import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
@@ -48,6 +56,9 @@ import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
|
||||
@@ -56,7 +67,6 @@ import com.health.openscale.core.OpenScale;
|
||||
import com.health.openscale.core.bluetooth.BluetoothCommunication;
|
||||
import com.health.openscale.core.bluetooth.BluetoothFactory;
|
||||
import com.health.openscale.gui.utils.ColorUtil;
|
||||
import com.health.openscale.gui.utils.PermissionHelper;
|
||||
import com.welie.blessed.BluetoothCentralManager;
|
||||
import com.welie.blessed.BluetoothCentralManagerCallback;
|
||||
import com.welie.blessed.BluetoothPeripheral;
|
||||
@@ -99,11 +109,110 @@ public class BluetoothSettingsFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
if (PermissionHelper.requestBluetoothPermission(this)) {
|
||||
startBluetoothDiscovery();
|
||||
super.onResume();
|
||||
|
||||
Timber.d("Bluetooth settings Bluetooth permission check");
|
||||
|
||||
int targetSdkVersion = getActivity().getApplicationInfo().targetSdkVersion;
|
||||
|
||||
final BluetoothManager bluetoothManager = (BluetoothManager) getActivity().getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
BluetoothAdapter btAdapter = bluetoothManager.getAdapter();
|
||||
|
||||
// Check if Bluetooth is enabled
|
||||
if (btAdapter == null || !btAdapter.isEnabled()) {
|
||||
Timber.d("Bluetooth is not enabled");
|
||||
Toast.makeText(getContext(), "Bluetooth " + getContext().getResources().getString(R.string.info_is_not_enable), Toast.LENGTH_SHORT).show();
|
||||
stepNavigationBack();
|
||||
return;
|
||||
}
|
||||
|
||||
super.onResume();
|
||||
// Check if Bluetooth 4.x is available
|
||||
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||
Timber.d("No Bluetooth 4.x available");
|
||||
Toast.makeText(getContext(), "Bluetooth 4.x " + getContext().getResources().getString(R.string.info_is_not_available), Toast.LENGTH_SHORT).show();
|
||||
stepNavigationBack();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if GPS or Network location service is enabled
|
||||
LocationManager locationManager = (LocationManager) getActivity().getSystemService(LOCATION_SERVICE);
|
||||
if (!(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
|
||||
Timber.d("No GPS or Network location service is enabled, ask user for permission");
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle(R.string.permission_bluetooth_info_title);
|
||||
builder.setIcon(R.drawable.ic_preferences_about);
|
||||
builder.setMessage(R.string.permission_location_service_info);
|
||||
builder.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
// Show location settings when the user acknowledges the alert dialog
|
||||
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
|
||||
stepNavigationBack();
|
||||
return;
|
||||
}
|
||||
|
||||
String[] requiredPermissions;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && targetSdkVersion >= Build.VERSION_CODES.S) {
|
||||
Timber.d("SDK >= 31 request for Bluetooth Scan and Bluetooth connect permissions");
|
||||
requiredPermissions = new String[]{Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT};
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) {
|
||||
Timber.d("SDK >= 29 request for Access fine location permission");
|
||||
requiredPermissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
|
||||
} else {
|
||||
Timber.d("SDK < 29 request for coarse location permission");
|
||||
requiredPermissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
|
||||
}
|
||||
|
||||
if (hasPermissions(requiredPermissions)) {
|
||||
startBluetoothDiscovery();
|
||||
} else if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
Timber.d("No access fine location permission granted");
|
||||
|
||||
builder.setMessage(R.string.permission_bluetooth_info)
|
||||
.setTitle(R.string.permission_bluetooth_info_title)
|
||||
.setIcon(R.drawable.ic_preferences_about)
|
||||
.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.dismiss();
|
||||
requestPermissionBluetoothLauncher.launch(requiredPermissions);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
|
||||
} else if (shouldShowRequestPermissionRationale(Manifest.permission.BLUETOOTH_SCAN)) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
Timber.d("No access Bluetooth scan permission granted");
|
||||
|
||||
builder.setMessage(R.string.permission_bluetooth_info)
|
||||
.setTitle(R.string.permission_bluetooth_info_title)
|
||||
.setIcon(R.drawable.ic_preferences_about)
|
||||
.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.dismiss();
|
||||
requestPermissionBluetoothLauncher.launch(requiredPermissions);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
|
||||
} else {
|
||||
requestPermissionBluetoothLauncher.launch(requiredPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -375,47 +484,38 @@ public class BluetoothSettingsFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == PermissionHelper.ENABLE_BLUETOOTH_REQUEST) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
if (PermissionHelper.requestBluetoothPermission(this)) {
|
||||
startBluetoothDiscovery();
|
||||
}
|
||||
}
|
||||
private void stepNavigationBack() {
|
||||
if (getActivity().findViewById(R.id.nav_host_fragment) != null) {
|
||||
Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).getPreviousBackStackEntry().getSavedStateHandle().set("update", true);
|
||||
Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).navigateUp();
|
||||
} else {
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case PermissionHelper.PERMISSIONS_REQUEST_ACCESS_BLUETOOTH: {
|
||||
boolean allGranted = true;
|
||||
for (int result : grantResults) {
|
||||
if (result != PackageManager.PERMISSION_GRANTED) {
|
||||
allGranted = false;
|
||||
break;
|
||||
}
|
||||
private boolean hasPermissions(String[] permissions) {
|
||||
if (permissions != null) {
|
||||
for (String permission : permissions) {
|
||||
if (ContextCompat.checkSelfPermission(getContext(), permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
Timber.d("Permission is not granted: " + permission);
|
||||
return false;
|
||||
}
|
||||
Timber.d("Permission already granted: " + permission);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (allGranted) {
|
||||
Timber.d("All Bluetooth permissions granted");
|
||||
startBluetoothDiscovery();
|
||||
} else {
|
||||
private ActivityResultLauncher<String[]> requestPermissionBluetoothLauncher =
|
||||
registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), isGranted -> {
|
||||
if (isGranted.containsValue(false)) {
|
||||
Timber.d("At least one Bluetooth permission was not granted");
|
||||
Toast.makeText(requireContext(), R.string.permission_not_granted, Toast.LENGTH_SHORT).show();
|
||||
|
||||
if (getActivity().findViewById(R.id.nav_host_fragment) != null){
|
||||
Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).getPreviousBackStackEntry().getSavedStateHandle().set("update", true);
|
||||
Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).navigateUp();
|
||||
} else {
|
||||
getActivity().finish();
|
||||
}
|
||||
Toast.makeText(requireContext(), getString(R.string.label_bluetooth_title) + ": " + getString(R.string.permission_not_granted), Toast.LENGTH_SHORT).show();
|
||||
stepNavigationBack();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
startBluetoothDiscovery();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -1,156 +0,0 @@
|
||||
/* Copyright (C) 2018 olie.xdev <olie.xdev@googlemail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package com.health.openscale.gui.utils;
|
||||
|
||||
import static android.content.Context.LOCATION_SERVICE;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.health.openscale.R;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class PermissionHelper {
|
||||
public final static int PERMISSIONS_REQUEST_ACCESS_BLUETOOTH = 1;
|
||||
public final static int PERMISSIONS_REQUEST_ACCESS_READ_STORAGE = 2;
|
||||
public final static int PERMISSIONS_REQUEST_ACCESS_WRITE_STORAGE = 3;
|
||||
|
||||
public final static int ENABLE_BLUETOOTH_REQUEST = 5;
|
||||
|
||||
public static boolean requestBluetoothPermission(final Fragment fragment) {
|
||||
final BluetoothManager bluetoothManager = (BluetoothManager) fragment.getActivity().getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
BluetoothAdapter btAdapter = bluetoothManager.getAdapter();
|
||||
|
||||
if (btAdapter == null || !btAdapter.isEnabled()) {
|
||||
Toast.makeText(fragment.getContext(), "Bluetooth " + fragment.getContext().getResources().getString(R.string.info_is_not_enable), Toast.LENGTH_SHORT).show();
|
||||
|
||||
if (btAdapter != null) {
|
||||
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||
fragment.getActivity().startActivityForResult(enableBtIntent, ENABLE_BLUETOOTH_REQUEST);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if Bluetooth 4.x is available
|
||||
if (!fragment.getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
|
||||
Toast.makeText(fragment.getContext(), "Bluetooth 4.x " + fragment.getContext().getResources().getString(R.string.info_is_not_available), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
int targetSdkVersion = fragment.getActivity().getApplicationInfo().targetSdkVersion;
|
||||
|
||||
String[] requiredPermissions;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && targetSdkVersion >= Build.VERSION_CODES.S) {
|
||||
Timber.d("SDK >= 31 request for Bluetooth Scan and Bluetooth connect permissions");
|
||||
requiredPermissions = new String[]{Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT};
|
||||
fragment.requestPermissions(requiredPermissions, PERMISSIONS_REQUEST_ACCESS_BLUETOOTH);
|
||||
return false;
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) {
|
||||
Timber.d("SDK >= 29 request for Access fine location permission");
|
||||
return requestLocationPermission(fragment, new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
|
||||
} else {
|
||||
Timber.d("SDK < 29 request for coarse location permission");
|
||||
return requestLocationPermission(fragment, new String[]{Manifest.permission.ACCESS_FINE_LOCATION});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean requestLocationPermission(final Fragment fragment, String[] requiredPermissions) {
|
||||
if (requestLocationServicePermission(fragment)) {
|
||||
if (fragment.getContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getActivity());
|
||||
Timber.d("No access fine location permission granted");
|
||||
|
||||
builder.setMessage(R.string.permission_bluetooth_info)
|
||||
.setTitle(R.string.permission_bluetooth_info_title)
|
||||
.setIcon(R.drawable.ic_preferences_about)
|
||||
.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.dismiss();
|
||||
fragment.requestPermissions(requiredPermissions, PERMISSIONS_REQUEST_ACCESS_BLUETOOTH);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean requestLocationServicePermission(final Fragment fragment) {
|
||||
LocationManager locationManager = (LocationManager) fragment.getActivity().getSystemService(LOCATION_SERVICE);
|
||||
if (!(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
|
||||
Timber.d("No GPS or Network location service is enabled, ask user for permission");
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getContext());
|
||||
builder.setTitle(R.string.permission_bluetooth_info_title);
|
||||
builder.setIcon(R.drawable.ic_preferences_about);
|
||||
builder.setMessage(R.string.permission_location_service_info);
|
||||
builder.setPositiveButton(R.string.label_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
// Show location settings when the user acknowledges the alert dialog
|
||||
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
fragment.getActivity().startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
Dialog alertDialog = builder.create();
|
||||
alertDialog.setCanceledOnTouchOutside(false);
|
||||
alertDialog.show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean requestReadPermission(final Fragment fragment) {
|
||||
if (fragment.getContext().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
fragment.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST_ACCESS_READ_STORAGE);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean requestWritePermission(final Fragment fragment) {
|
||||
if (fragment.getContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||
fragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST_ACCESS_WRITE_STORAGE);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user