mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Made sure to check if location permission has been given by the user for scanning
This commit is contained in:
+16
-9
@@ -72,24 +72,19 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
|||||||
public class ControlCenterv2 extends AppCompatActivity
|
public class ControlCenterv2 extends AppCompatActivity
|
||||||
implements NavigationView.OnNavigationItemSelectedListener, GBActivity {
|
implements NavigationView.OnNavigationItemSelectedListener, GBActivity {
|
||||||
|
|
||||||
|
public static final int MENU_REFRESH_CODE = 1;
|
||||||
|
private static PhoneStateListener fakeStateListener;
|
||||||
|
|
||||||
//needed for KK compatibility
|
//needed for KK compatibility
|
||||||
static {
|
static {
|
||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeviceManager deviceManager;
|
private DeviceManager deviceManager;
|
||||||
|
|
||||||
private GBDeviceAdapterv2 mGBDeviceAdapter;
|
private GBDeviceAdapterv2 mGBDeviceAdapter;
|
||||||
private RecyclerView deviceListView;
|
private RecyclerView deviceListView;
|
||||||
private FloatingActionButton fab;
|
private FloatingActionButton fab;
|
||||||
|
|
||||||
private boolean isLanguageInvalid = false;
|
private boolean isLanguageInvalid = false;
|
||||||
private boolean pesterWithPermissions = true;
|
|
||||||
|
|
||||||
public static final int MENU_REFRESH_CODE = 1;
|
|
||||||
|
|
||||||
private static PhoneStateListener fakeStateListener;
|
|
||||||
|
|
||||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@@ -107,6 +102,7 @@ public class ControlCenterv2 extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private boolean pesterWithPermissions = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -373,6 +369,10 @@ public class ControlCenterv2 extends AppCompatActivity
|
|||||||
wantedPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
wantedPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)
|
||||||
wantedPermissions.add(Manifest.permission.READ_CALENDAR);
|
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 {
|
try {
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.MEDIA_CONTENT_CONTROL) == PackageManager.PERMISSION_DENIED)
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.MEDIA_CONTENT_CONTROL) == PackageManager.PERMISSION_DENIED)
|
||||||
@@ -388,6 +388,12 @@ public class ControlCenterv2 extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_DENIED) {
|
||||||
|
wantedPermissions.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!wantedPermissions.isEmpty()) {
|
if (!wantedPermissions.isEmpty()) {
|
||||||
Prefs prefs = GBApplication.getPrefs();
|
Prefs prefs = GBApplication.getPrefs();
|
||||||
// If this is not the first run, we can rely on
|
// If this is not the first run, we can rely on
|
||||||
@@ -411,10 +417,11 @@ public class ControlCenterv2 extends AppCompatActivity
|
|||||||
if (!wantedPermissions.isEmpty()) {
|
if (!wantedPermissions.isEmpty()) {
|
||||||
GB.toast(this, getString(R.string.permission_granting_mandatory), Toast.LENGTH_LONG, GB.ERROR);
|
GB.toast(this, getString(R.string.permission_granting_mandatory), Toast.LENGTH_LONG, GB.ERROR);
|
||||||
ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[0]), 0);
|
ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[0]), 0);
|
||||||
|
GB.toast(this, getString(R.string.permission_granting_mandatory), Toast.LENGTH_LONG, GB.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In order to be able to set ringer mode to silent in PhoneCallReceiver
|
/* 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
|
the permission to access notifications is needed above Android M
|
||||||
ACCESS_NOTIFICATION_POLICY is also needed in the manifest */
|
ACCESS_NOTIFICATION_POLICY is also needed in the manifest */
|
||||||
if (pesterWithPermissions) {
|
if (pesterWithPermissions) {
|
||||||
|
|||||||
+58
-51
@@ -59,7 +59,6 @@ import android.widget.Toast;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -88,19 +87,34 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
|
|||||||
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryActivity.class);
|
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryActivity.class);
|
||||||
private static final long SCAN_DURATION = 30000; // 30s
|
private static final long SCAN_DURATION = 30000; // 30s
|
||||||
private static final int REQUEST_CODE = 1;
|
private static final int REQUEST_CODE = 1;
|
||||||
private ScanCallback newBLEScanCallback = null;
|
|
||||||
|
|
||||||
/** Use old BLE scanning **/
|
|
||||||
private boolean oldBleScanning = false;
|
|
||||||
/** If already bonded devices are to be ignored when scanning */
|
|
||||||
private boolean ignoreBonded = true;
|
|
||||||
/** If new CompanionDevice-type pairing is enabled on newer Androids **/
|
|
||||||
private boolean enableCompanionDevicePairing = false;
|
|
||||||
|
|
||||||
private final Handler handler = new Handler();
|
private final Handler handler = new Handler();
|
||||||
|
private final ArrayList<GBDeviceCandidate> deviceCandidates = new ArrayList<>();
|
||||||
|
private ScanCallback newBLEScanCallback = null;
|
||||||
|
/**
|
||||||
|
* Use old BLE scanning
|
||||||
|
**/
|
||||||
|
private boolean oldBleScanning = false;
|
||||||
|
/**
|
||||||
|
* If already bonded devices are to be ignored when scanning
|
||||||
|
*/
|
||||||
|
private boolean ignoreBonded = true;
|
||||||
|
/**
|
||||||
|
* If new CompanionDevice-type pairing is enabled on newer Androids
|
||||||
|
**/
|
||||||
|
private boolean enableCompanionDevicePairing = false;
|
||||||
private ProgressBar bluetoothProgress;
|
private ProgressBar bluetoothProgress;
|
||||||
private ProgressBar bluetoothLEProgress;
|
private ProgressBar bluetoothLEProgress;
|
||||||
|
private DeviceCandidateAdapter deviceCandidateAdapter;
|
||||||
|
private final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
|
||||||
|
@Override
|
||||||
|
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
||||||
|
//logMessageContent(scanRecord);
|
||||||
|
handleDeviceFound(device, (short) rssi);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private BluetoothAdapter adapter;
|
||||||
|
private Button startButton;
|
||||||
|
private Scanning isScanning = Scanning.SCANNING_OFF;
|
||||||
private final Runnable stopRunnable = new Runnable() {
|
private final Runnable stopRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -113,7 +127,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private DeviceCandidateAdapter deviceCandidateAdapter;
|
private GBDeviceCandidate bondingDevice;
|
||||||
private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@@ -216,14 +230,6 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
|
|
||||||
@Override
|
|
||||||
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
|
|
||||||
//logMessageContent(scanRecord);
|
|
||||||
handleDeviceFound(device, (short) rssi);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void deviceBond(GBDeviceCandidate deviceCandidate) {
|
private void deviceBond(GBDeviceCandidate deviceCandidate) {
|
||||||
if (deviceCandidate.getDevice().createBond()) {
|
if (deviceCandidate.getDevice().createBond()) {
|
||||||
// Async, wait for bonding event to finish this activity
|
// Async, wait for bonding event to finish this activity
|
||||||
@@ -302,9 +308,6 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
|
|||||||
connectAndFinish(device);
|
connectAndFinish(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BluetoothAdapter adapter;
|
|
||||||
private final ArrayList<GBDeviceCandidate> deviceCandidates = new ArrayList<>();
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
private ScanCallback getScanCallback() {
|
private ScanCallback getScanCallback() {
|
||||||
if (newBLEScanCallback != null) {
|
if (newBLEScanCallback != null) {
|
||||||
@@ -338,10 +341,6 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
|
|||||||
return newBLEScanCallback;
|
return newBLEScanCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button startButton;
|
|
||||||
private Scanning isScanning = Scanning.SCANNING_OFF;
|
|
||||||
private GBDeviceCandidate bondingDevice;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -394,35 +393,13 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
|
|||||||
|
|
||||||
registerReceiver(bluetoothReceiver, bluetoothIntents);
|
registerReceiver(bluetoothReceiver, bluetoothIntents);
|
||||||
|
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
checkAndRequestLocationPermission();
|
||||||
toast(DiscoveryActivity.this, getString(R.string.error_no_location_access), Toast.LENGTH_SHORT, GB.ERROR);
|
|
||||||
LOG.error("No permission to access coarse location!");
|
|
||||||
checkAndRequestLocationPermission();
|
|
||||||
|
|
||||||
// We can't be sure location was granted, cancel scan start and wait for user action
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LocationManager locationManager = (LocationManager) DiscoveryActivity.this.getSystemService(Context.LOCATION_SERVICE);
|
|
||||||
try {
|
|
||||||
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
|
|
||||||
// Do nothing
|
|
||||||
LOG.debug("Some location provider is enabled, assuming location is enabled");
|
|
||||||
} else {
|
|
||||||
toast(DiscoveryActivity.this, getString(R.string.require_location_provider), Toast.LENGTH_LONG, GB.ERROR);
|
|
||||||
DiscoveryActivity.this.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
|
||||||
// We can't be sure location was enabled, cancel scan start and wait for new user action
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
LOG.error("Exception when checking location status: ", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
startDiscovery(Scanning.SCANNING_BT_NEXT_BLE);
|
startDiscovery(Scanning.SCANNING_BT_NEXT_BLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStartButtonClick(View button) {
|
public void onStartButtonClick(View button) {
|
||||||
LOG.debug("Start Button clicked");
|
LOG.debug("Start button clicked");
|
||||||
if (isScanning()) {
|
if (isScanning()) {
|
||||||
stopDiscovery();
|
stopDiscovery();
|
||||||
} else {
|
} else {
|
||||||
@@ -751,8 +728,38 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
|
|||||||
|
|
||||||
private void checkAndRequestLocationPermission() {
|
private void checkAndRequestLocationPermission() {
|
||||||
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
LOG.error("No permission to access coarse location!");
|
||||||
|
toast(DiscoveryActivity.this, getString(R.string.error_no_location_access), Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
|
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 0);
|
||||||
}
|
}
|
||||||
|
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
LOG.error("No permission to access fine location!");
|
||||||
|
toast(DiscoveryActivity.this, getString(R.string.error_no_location_access), Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
|
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
LOG.error("No permission to access background location!");
|
||||||
|
toast(DiscoveryActivity.this, getString(R.string.error_no_location_access), Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
|
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationManager locationManager = (LocationManager) DiscoveryActivity.this.getSystemService(Context.LOCATION_SERVICE);
|
||||||
|
try {
|
||||||
|
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
|
||||||
|
// Do nothing
|
||||||
|
LOG.debug("Some location provider is enabled, assuming location is enabled");
|
||||||
|
} else {
|
||||||
|
toast(DiscoveryActivity.this, getString(R.string.require_location_provider), Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
DiscoveryActivity.this.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
||||||
|
// We can't be sure location was enabled, cancel scan start and wait for new user action
|
||||||
|
toast(DiscoveryActivity.this, getString(R.string.error_location_enabled_mandatory), Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LOG.error("Exception when checking location status: ", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -901,6 +901,7 @@
|
|||||||
<string name="error_retrieving_devices_database">Error retrieving devices from database</string>
|
<string name="error_retrieving_devices_database">Error retrieving devices from database</string>
|
||||||
<string name="ignore_bonded_devices">Ignore bonded devices</string>
|
<string name="ignore_bonded_devices">Ignore bonded devices</string>
|
||||||
<string name="ignore_bonded_devices_description">Enabling this option will ignore devices that have been bonded/paired already when scanning</string>
|
<string name="ignore_bonded_devices_description">Enabling this option will ignore devices that have been bonded/paired already when scanning</string>
|
||||||
|
<string name="error_location_enabled_mandatory">Location must be turned on to scan for devices</string>
|
||||||
|
|
||||||
<plurals name="widget_alarm_target_hours">
|
<plurals name="widget_alarm_target_hours">
|
||||||
<item quantity="one">%d hour</item>
|
<item quantity="one">%d hour</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user