diff --git a/.gitignore b/.gitignore index 479d76c..38dae50 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ *.apk /blue-pair-secret.properties /app/app-keystore.jks +/.idea diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser deleted file mode 100644 index e074ada..0000000 Binary files a/.idea/caches/build_file_checksums.ser and /dev/null differ diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 681f41a..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
-
-
\ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 96cc43e..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3..0000000 --- a/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 5cd135a..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index 3af60f3..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index dd67e70..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 3acfebc..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 1ceffce..62888e4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 32 buildToolsVersion "29.0.2" defaultConfig { applicationId "co.aurasphere.bluepair" minSdkVersion 19 - targetSdkVersion 28 + targetSdkVersion 32 versionCode 3 versionName "1.0.2" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5f8db2a..9fc3798 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,8 +2,32 @@ - - + + + + + + + + + + + + + + + diff --git a/app/src/main/java/co/aurasphere/bluepair/MainActivity.java b/app/src/main/java/co/aurasphere/bluepair/MainActivity.java index 3cea24d..c8d74fa 100644 --- a/app/src/main/java/co/aurasphere/bluepair/MainActivity.java +++ b/app/src/main/java/co/aurasphere/bluepair/MainActivity.java @@ -23,16 +23,22 @@ */ package co.aurasphere.bluepair; +import android.Manifest; import android.app.ProgressDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.content.Context; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.os.Build; import android.os.Bundle; import android.os.SystemClock; +import android.support.annotation.NonNull; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; @@ -62,6 +68,7 @@ */ public class MainActivity extends AppCompatActivity implements ListInteractionListener { + private static final int REQUEST_CODE_BLUETOOTH = 1; /** * Tag string used for logging. */ @@ -112,6 +119,8 @@ protected void onCreate(Bundle savedInstanceState) { this.adContainer = (LinearLayout) findViewById(R.id.ad_container); reloadAd(); + checkAndRequestPermissions(); + // Sets up the RecyclerView. this.recyclerViewAdapter = new DeviceRecyclerViewAdapter(this); this.recyclerView = (RecyclerViewProgressEmptySupport) findViewById(R.id.list); @@ -173,6 +182,62 @@ public void onClick(View view) { }); } + private void checkAndRequestPermissions() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + // Android 12 (API 31) and above + String[] permissions = { + Manifest.permission.BLUETOOTH_SCAN, + Manifest.permission.BLUETOOTH_CONNECT + }; + + if (!hasPermissions(this, permissions)) { + ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE_BLUETOOTH); + } + } else { + // Below Android 12 (API 30 and lower) + String[] permissions = { + Manifest.permission.ACCESS_FINE_LOCATION // Needed for Bluetooth scanning + }; + + if (!hasPermissions(this, permissions)) { + ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE_BLUETOOTH); + } + } + } + + private boolean hasPermissions(Context context, String[] permissions) { + for (String permission : permissions) { + if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } + return true; + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if (requestCode == REQUEST_CODE_BLUETOOTH) { + boolean allGranted = true; + for (int grantResult : grantResults) { + if (grantResult != PackageManager.PERMISSION_GRANTED) { + allGranted = false; + break; + } + } + + if (allGranted) { + Log.d("Permission", "Permissions granted"); + } else { + Log.d("Permission", "Permissions denied"); + Snackbar.make(findViewById(android.R.id.content), + "Bluetooth permissions are required for discovery", + Snackbar.LENGTH_LONG).show(); + } + } + } + /** * {@inheritDoc} */ diff --git a/app/src/main/java/co/aurasphere/bluepair/bluetooth/BluetoothController.java b/app/src/main/java/co/aurasphere/bluepair/bluetooth/BluetoothController.java index 972a36f..dfbe179 100644 --- a/app/src/main/java/co/aurasphere/bluepair/bluetooth/BluetoothController.java +++ b/app/src/main/java/co/aurasphere/bluepair/bluetooth/BluetoothController.java @@ -80,7 +80,7 @@ public class BluetoothController implements Closeable { * @param context the activity which is using this controller. * @param listener a callback for handling Bluetooth events. */ - public BluetoothController(Activity context,BluetoothAdapter adapter, BluetoothDiscoveryDeviceListener listener) { + public BluetoothController(Activity context, BluetoothAdapter adapter, BluetoothDiscoveryDeviceListener listener) { this.context = context; this.bluetooth = adapter; this.broadcastReceiverDelegator = new BroadcastReceiverDelegator(context, listener, this); @@ -101,16 +101,6 @@ public boolean isBluetoothEnabled() { public void startDiscovery() { broadcastReceiverDelegator.onDeviceDiscoveryStarted(); - // This line of code is very important. In Android >= 6.0 you have to ask for the runtime - // permission as well in order for the discovery to get the devices ids. If you don't do - // this, the discovery won't find any device. - if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) - != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(context, - new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, - 1); - } - // If another discovery is in progress, cancels it before starting the new one. if (bluetooth.isDiscovering()) { bluetooth.cancelDiscovery();