Skip to content

Commit

Permalink
Update to SDK 29. Check for ACCESS_FINE_LOCATION for SDK 29 and highe…
Browse files Browse the repository at this point in the history
…r but leave it to ACCESS_COARSE_LOCATION for lower ones.
  • Loading branch information
martijnvanwelie committed Oct 21, 2019
1 parent f7ead17 commit d00ba14
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 31 deletions.
14 changes: 7 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
applicationId "com.welie.blessedexample"
minSdkVersion 21
targetSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
Expand All @@ -20,11 +20,11 @@ android {

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.jakewharton.timber:timber:4.7.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation project(':blessed')
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.welie.blessedexample;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application
Expand Down
18 changes: 12 additions & 6 deletions app/src/main/java/com/welie/blessedexample/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
Expand All @@ -25,7 +25,7 @@ public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
private TextView bloodpressureValue;
private static final int REQUEST_ENABLE_BT = 1;
private static final int ACCESS_COARSE_LOCATION_REQUEST = 2;
private static final int ACCESS_LOCATION_REQUEST = 2;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand Down Expand Up @@ -74,9 +74,15 @@ public void onReceive(Context context, Intent intent) {
};

private boolean hasPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int targetSdkVersion = getApplicationInfo().targetSdkVersion;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) {
if (getApplicationContext().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_LOCATION_REQUEST);
return false;
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (getApplicationContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] { Manifest.permission.ACCESS_COARSE_LOCATION }, ACCESS_COARSE_LOCATION_REQUEST);
requestPermissions(new String[] { Manifest.permission.ACCESS_COARSE_LOCATION }, ACCESS_LOCATION_REQUEST);
return false;
}
}
Expand All @@ -86,7 +92,7 @@ private boolean hasPermissions() {
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case ACCESS_COARSE_LOCATION_REQUEST:
case ACCESS_LOCATION_REQUEST:
if(grantResults.length > 0) {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
initBluetoothHandler();
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
Expand All @@ -18,4 +18,4 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
11 changes: 5 additions & 6 deletions blessed/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
apply plugin: 'com.android.library'

android {
compileSdkVersion 28
compileSdkVersion 29

defaultConfig {
minSdkVersion 21
targetSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

}

Expand All @@ -25,12 +25,11 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.jakewharton.timber:timber:4.7.1'
testImplementation 'junit:junit:4.12'
testImplementation "org.robolectric:robolectric:3.8"
testImplementation "org.mockito:mockito-core:1.10.19"

androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.welie.blessed;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down
2 changes: 1 addition & 1 deletion blessed/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

</manifest>
15 changes: 11 additions & 4 deletions blessed/src/main/java/com/welie/blessed/BluetoothCentral.java
Original file line number Diff line number Diff line change
Expand Up @@ -746,10 +746,17 @@ private boolean isBleEnabled() {
}

private boolean permissionsGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Timber.e("no location permission, cannot scan");
return false;
int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && targetSdkVersion >= Build.VERSION_CODES.Q) {
if(context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Timber.e("no ACCESS_FINE_LOCATION permission, cannot scan");
return false;
} else return true;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Timber.e("no ACCESS_COARSE_LOCATION permission, cannot scan");
return false;
} else return true;
} else {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowBluetoothAdapter;
import org.robolectric.shadows.ShadowPackageManager;

import java.lang.reflect.Field;
Expand All @@ -43,6 +44,7 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -76,7 +78,6 @@ public void setUp() throws Exception {
initMocks(this);

application = ShadowApplication.getInstance();
application.grantPermissions(Manifest.permission.ACCESS_COARSE_LOCATION);

bluetoothAdapter = Shadow.extract(ShadowBluetoothLEAdapter.getDefaultAdapter());
bluetoothAdapter.setEnabled(true);
Expand All @@ -94,6 +95,7 @@ public void setUp() throws Exception {

@Test
public void scanForPeripheralsTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
central.scanForPeripherals();
verify(scanner).startScan(anyList(), any(ScanSettings.class), any(ScanCallback.class));

Expand All @@ -120,6 +122,7 @@ public void scanForPeripheralsTest() throws Exception {

@Test
public void scanForPeripheralsWithServicesTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
UUID BLP_SERVICE_UUID = UUID.fromString("00001810-0000-1000-8000-00805f9b34fb");
central.scanForPeripheralsWithServices(new UUID[]{BLP_SERVICE_UUID});

Expand Down Expand Up @@ -162,6 +165,7 @@ public void scanForPeripheralsWithServicesTest() throws Exception {

@Test
public void scanForPeripheralsWithAddressesTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
String myAddress = "12:23:34:98:76:54";
central.scanForPeripheralsWithAddresses(new String[]{myAddress});

Expand Down Expand Up @@ -203,6 +207,7 @@ public void scanForPeripheralsWithAddressesTest() throws Exception {

@Test
public void scanForPeripheralsWithNamesTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
String myName = "Polar";
central.scanForPeripheralsWithNames(new String[]{myName});

Expand Down Expand Up @@ -239,6 +244,7 @@ public void scanForPeripheralsWithNamesTest() throws Exception {

@Test
public void scanFailedTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
central.scanForPeripherals();
verify(scanner).startScan(anyList(), any(ScanSettings.class), any(ScanCallback.class));

Expand All @@ -252,8 +258,21 @@ public void scanFailedTest() throws Exception {
verify(callback).onScanFailed(SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
}

@Test
public void scanFailedAutoconnectTest() throws Exception {
// Grab the scan callback that is used
Field field = BluetoothCentral.class.getDeclaredField("autoConnectScanCallback");
field.setAccessible(true);
ScanCallback scanCallback = (ScanCallback) field.get(central);

scanCallback.onScanFailed(SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);

verify(callback).onScanFailed(SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES);
}

@Test
public void scanForNamesFailedTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
String myName = "Polar";
central.scanForPeripheralsWithNames(new String[]{myName});

Expand All @@ -269,6 +288,7 @@ public void scanForNamesFailedTest() throws Exception {

@Test
public void stopScanTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
central.scanForPeripherals();
verify(scanner).startScan(anyList(), any(ScanSettings.class), any(ScanCallback.class));

Expand All @@ -292,6 +312,7 @@ public void stopScanTest() throws Exception {

@Test
public void connectPeripheralTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
BluetoothPeripheral peripheral = mock(BluetoothPeripheral.class);
when(peripheral.getAddress()).thenReturn("12:23:34:98:76:54");
when(peripheral.getType()).thenReturn(BluetoothDevice.DEVICE_TYPE_LE);
Expand All @@ -313,6 +334,8 @@ public void connectPeripheralTest() throws Exception {

@Test
public void connectionFailedRetryTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);

BluetoothPeripheral peripheral = mock(BluetoothPeripheral.class);
when(peripheral.getAddress()).thenReturn("12:23:34:98:76:54");
when(peripheral.getType()).thenReturn(BluetoothDevice.DEVICE_TYPE_LE);
Expand All @@ -336,6 +359,8 @@ public void connectionFailedRetryTest() throws Exception {

@Test
public void connectionFailedAfterRetryTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);

BluetoothPeripheral peripheral = mock(BluetoothPeripheral.class);
when(peripheral.getAddress()).thenReturn("12:23:34:98:76:54");
when(peripheral.getType()).thenReturn(BluetoothDevice.DEVICE_TYPE_LE);
Expand All @@ -359,6 +384,8 @@ public void connectionFailedAfterRetryTest() throws Exception {

@Test
public void cancelConnectionPeripheralTest() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);

BluetoothPeripheral peripheral = mock(BluetoothPeripheral.class);
when(peripheral.getAddress()).thenReturn("12:23:34:98:76:54");
when(peripheral.getType()).thenReturn(BluetoothDevice.DEVICE_TYPE_LE);
Expand Down Expand Up @@ -388,6 +415,8 @@ public void cancelConnectionPeripheralTest() throws Exception {

@Test
public void autoconnectTestCached() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);

BluetoothPeripheral peripheral = mock(BluetoothPeripheral.class);
when(peripheral.getAddress()).thenReturn("12:23:34:98:76:54");
when(peripheral.getType()).thenReturn(BluetoothDevice.DEVICE_TYPE_LE);
Expand All @@ -409,6 +438,8 @@ public void autoconnectTestCached() throws Exception {

@Test
public void autoconnectTestUnCached() throws Exception {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);

BluetoothDevice device = mock(BluetoothDevice.class);
when(device.getAddress()).thenReturn("12:23:34:98:76:54");
when(device.getType()).thenReturn(BluetoothDevice.DEVICE_TYPE_LE);
Expand All @@ -434,4 +465,18 @@ public void autoconnectTestUnCached() throws Exception {

verify(peripheral).connect();
}

@Test
public void bluetoothOffTest() {
application.grantPermissions(Manifest.permission.ACCESS_FINE_LOCATION);
bluetoothAdapter.setEnabled(false);
central.scanForPeripherals();
verify(scanner, never()).startScan(anyList(), any(ScanSettings.class), any(ScanCallback.class));
}

@Test
public void noPermissionTest() {
central.scanForPeripherals();
verify(scanner, never()).startScan(anyList(), any(ScanSettings.class), any(ScanCallback.class));
}
}
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
Expand Down

0 comments on commit d00ba14

Please sign in to comment.