diff --git a/README.md b/README.md
index e5e7679..8370d8b 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
---
author: Tony Myles
title: "AferoJavaSDK"
-date: 2022-Feb-28
-status: 1.5.0
+date: 2022-March-10
+status: 1.5.1
---
# AferoJavaSDK
@@ -32,24 +32,24 @@ The SDK is composed of four separate modules.
The `afero-sdk-core` module is required for base functionality such as interacting with the Afero Cloud and manipulating devices.
```Gradle
- implementation 'io.afero.sdk:afero-sdk-core:1.5.0'
+ implementation 'io.afero.sdk:afero-sdk-core:1.5.1'
```
The `afero-sdk-client-retrofit2` module provides an optional implementation of the AferoClient REST API interface using [Retrofit2](http://square.github.io/retrofit/) and [okhttp3](http://square.github.io/okhttp/). If you choose not to include this module in your project, you will need to develop your own implementation of AferoClient using your preferred http client library.
```Gradle
- implementation 'io.afero.sdk:afero-sdk-client-retrofit2:1.5.0'
+ implementation 'io.afero.sdk:afero-sdk-client-retrofit2:1.5.1'
```
The `afero-sdk-android` module is required for Android development.
```Gradle
- implementation 'io.afero.sdk:afero-sdk-android:1.5.0'
+ implementation 'io.afero.sdk:afero-sdk-android:1.5.1'
```
The `afero-sdk-softhub` module is required for soft hub functionality on Android.
```Gradle
- implementation 'io.afero.sdk:afero-sdk-softhub:1.5.0'
- implementation "io.afero.sdk:hubby:1.0.844@aar"
+ implementation 'io.afero.sdk:afero-sdk-softhub:1.5.1'
+ implementation "io.afero.sdk:hubby:1.0.957@aar"
```
## License
diff --git a/afero-sdk-core/src/main/java/io/afero/sdk/device/DeviceCollection.java b/afero-sdk-core/src/main/java/io/afero/sdk/device/DeviceCollection.java
index 5293319..126021d 100644
--- a/afero-sdk-core/src/main/java/io/afero/sdk/device/DeviceCollection.java
+++ b/afero-sdk-core/src/main/java/io/afero/sdk/device/DeviceCollection.java
@@ -523,6 +523,10 @@ public void call(Throwable t) {
@Override
public void call(InvalidateMessage im) {
try {
+ if (im.deviceId == null) {
+ AfLog.e("Got invalidate without deviceId");
+ return;
+ }
DeviceModel deviceModel = getDevice(im.deviceId);
if (deviceModel == null) {
AfLog.e("Got invalidate on unknown deviceId: " + im.deviceId);
diff --git a/samples/afero-lab/app/build.gradle b/samples/afero-lab/app/build.gradle
index 8ecea30..c9e8ab9 100644
--- a/samples/afero-lab/app/build.gradle
+++ b/samples/afero-lab/app/build.gradle
@@ -5,7 +5,7 @@
apply plugin: 'com.android.application'
final String sdkRepoKey = project.findProperty('aferoSDKConsumeRepoKey') ?: 'afero-java-sdk'
-final String sdkVersion = project.findProperty('aferoSDKVersion') ?: '1.5.0'
+final String sdkVersion = project.findProperty('aferoSDKVersion') ?: '1.5.1'
repositories {
maven {
@@ -31,12 +31,12 @@ configurations.all {
android {
- compileSdkVersion 30
+ compileSdkVersion 32
defaultConfig {
applicationId 'io.afero.aferolab'
minSdkVersion 26
- targetSdkVersion 30
+ targetSdkVersion 32
versionCode 1
versionName '1.0'
diff --git a/samples/afero-lab/app/src/main/AndroidManifest.xml b/samples/afero-lab/app/src/main/AndroidManifest.xml
index a8734c0..97aba77 100644
--- a/samples/afero-lab/app/src/main/AndroidManifest.xml
+++ b/samples/afero-lab/app/src/main/AndroidManifest.xml
@@ -12,6 +12,10 @@
+
+
+
+
+ android:windowSoftInputMode="adjustResize"
+ android:exported="true">
@@ -34,7 +39,7 @@
+ android:exported="true">
diff --git a/samples/afero-lab/app/src/main/java/io/afero/aferolab/helper/PermissionsHelper.java b/samples/afero-lab/app/src/main/java/io/afero/aferolab/helper/PermissionsHelper.java
index 7a3556b..8e65d87 100644
--- a/samples/afero-lab/app/src/main/java/io/afero/aferolab/helper/PermissionsHelper.java
+++ b/samples/afero-lab/app/src/main/java/io/afero/aferolab/helper/PermissionsHelper.java
@@ -22,7 +22,16 @@ public class PermissionsHelper {
// See http://developer.radiusnetworks.com/2015/09/29/is-your-beacon-app-ready-for-android-6.html
public static void checkRequiredPermissions(Activity activity) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
+ boolean hasCamera = activity.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
+ boolean hasBluetooth = activity.checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED;
+
+ if (!hasCamera || !hasBluetooth) {
+ askUserForAllPermissions(activity);
+ } else {
+ AfLog.d("checkRequiredPermissions: permissions granted");
+ }
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
boolean hasLocation = activity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean hasCamera = activity.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
@@ -42,7 +51,15 @@ private static void askUserForAllPermissions(final Activity activity) {
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ activity.requestPermissions(
+ new String[]{
+ Manifest.permission.BLUETOOTH_SCAN,
+ Manifest.permission.BLUETOOTH_CONNECT,
+ Manifest.permission.CAMERA
+ },
+ PERMISSION_REQUEST_ALL);
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.requestPermissions(
new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,