From 8994a2942453acf04afc071be77b7bd91ce81a9f Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Mon, 30 Jan 2023 12:03:00 +0000 Subject: [PATCH] Fixes #253. Permissions ordering fix for Android Have now moved Sensor start to the request permissions response function to prevent mis-timing between permission requests and features being used in Herald in the demo app. This was a particular issue in Android 13 testing. Signed-off-by: Adam Fowler --- app/build.gradle | 2 +- .../heraldprox/herald/app/MainActivity.java | 104 +++++++++--------- herald/build.gradle | 4 +- 3 files changed, 57 insertions(+), 53 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 254f226..2e1bdce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,7 +13,7 @@ android { minSdkVersion 21 targetSdkVersion 31 versionCode 2 - versionName "2.1.0" + versionName "2.1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/io/heraldprox/herald/app/MainActivity.java b/app/src/main/java/io/heraldprox/herald/app/MainActivity.java index 84f638e..f32df89 100644 --- a/app/src/main/java/io/heraldprox/herald/app/MainActivity.java +++ b/app/src/main/java/io/heraldprox/herald/app/MainActivity.java @@ -157,56 +157,7 @@ protected void onCreate(Bundle savedInstanceState) { // REQUIRED : Ensure app has all required permissions requestPermissions(); - // Test UI specific process to gather data from sensor for presentation - final Sensor sensor = AppDelegate.getAppDelegate().sensor(); - sensor.add(this); - sensor.add(socialMixingScore); - ((TextView) findViewById(R.id.device)).setText(SensorArray.deviceDescription); - PayloadData payloadData = ((SensorArray) AppDelegate.getAppDelegate().sensor()).payloadData(); - ((TextView) findViewById(R.id.payload)).setText("PAYLOAD : " + payloadData.shortName()); - - if (BLESensorConfiguration.gpdmpEnabled) { - // We generate a static identified and use this for the TEST payload, and for the channel UUID - // DO NOT DO THIS IN PRODUCTION - this is JUST for THIS demo app - mySenderRecipientId = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aa" + payloadData.hexEncodedString().substring(10)); - Log.d(tag, "Setting my own GPDMP channel ID (channelID=" + mySenderRecipientId.toString() + ")"); - // Listen for any and all data sent on the default GPDMP channel - ((SensorArray) sensor).getGPDMPMessageListenerManager().addMessageListener(defaultChannelId, this); - } - - targetListAdapter = new TargetListAdapter(this, targets); - final ListView targetsListView = ((ListView) findViewById(R.id.targets)); - targetsListView.setAdapter(targetListAdapter); - targetsListView.setOnItemClickListener(this); - // - Temporal histogram model configuration - ((TemporalHistogramModelView) findViewById(R.id.temporalHistogram)).model(temporalHistogramModel); - ((TemporalHistogramModelView) findViewById(R.id.temporalHistogram)).bin(3); - - // Test programmatic control of sensor on/off - final Switch onOffSwitch = findViewById(R.id.sensorOnOffSwitch); - onOffSwitch.setChecked(false); - onOffSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - sensor.start(); - } else { - sensor.stop(); - } - } - }); - - // Sensor is on by default, unless automated test has been enabled, - // in which case, sensor is off by default and controlled by test - // server remote commands. - final AutomatedTestClient automatedTestClient = AppDelegate.getAppDelegate().automatedTestClient; - if (null == automatedTestClient) { - sensor.stop(); - sensor.start(); // called again (first called by AppDelegate constructor) to ensure permissions are forced - } else { - sensor.stop(); - automatedTestClient.add(this); - } + // All Herald advert/scan start code now moved to onRequestPermissionsResult() } /** @@ -273,6 +224,59 @@ public void onRequestPermissionsResult(final int requestCode, @NonNull final Str if (!permissionsGranted) { Log.e(tag, "Application does not have all required permissions to start (permissions=" + Arrays.asList(permissions) + ")"); } + + // Herald sensor initialisation code moved here to prevent mistiming between the advert starting and permissions being granted + + // Test UI specific process to gather data from sensor for presentation + final Sensor sensor = AppDelegate.getAppDelegate().sensor(); + sensor.add(this); + sensor.add(socialMixingScore); + ((TextView) findViewById(R.id.device)).setText(SensorArray.deviceDescription); + PayloadData payloadData = ((SensorArray) AppDelegate.getAppDelegate().sensor()).payloadData(); + ((TextView) findViewById(R.id.payload)).setText("PAYLOAD : " + payloadData.shortName()); + + if (BLESensorConfiguration.gpdmpEnabled) { + // We generate a static identified and use this for the TEST payload, and for the channel UUID + // DO NOT DO THIS IN PRODUCTION - this is JUST for THIS demo app + mySenderRecipientId = UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aa" + payloadData.hexEncodedString().substring(10)); + Log.d(tag, "Setting my own GPDMP channel ID (channelID=" + mySenderRecipientId.toString() + ")"); + // Listen for any and all data sent on the default GPDMP channel + ((SensorArray) sensor).getGPDMPMessageListenerManager().addMessageListener(defaultChannelId, this); + } + + targetListAdapter = new TargetListAdapter(this, targets); + final ListView targetsListView = ((ListView) findViewById(R.id.targets)); + targetsListView.setAdapter(targetListAdapter); + targetsListView.setOnItemClickListener(this); + // - Temporal histogram model configuration + ((TemporalHistogramModelView) findViewById(R.id.temporalHistogram)).model(temporalHistogramModel); + ((TemporalHistogramModelView) findViewById(R.id.temporalHistogram)).bin(3); + + // Test programmatic control of sensor on/off + final Switch onOffSwitch = findViewById(R.id.sensorOnOffSwitch); + onOffSwitch.setChecked(false); + onOffSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + sensor.start(); + } else { + sensor.stop(); + } + } + }); + + // Sensor is on by default, unless automated test has been enabled, + // in which case, sensor is off by default and controlled by test + // server remote commands. + final AutomatedTestClient automatedTestClient = AppDelegate.getAppDelegate().automatedTestClient; + if (null == automatedTestClient) { + sensor.stop(); + sensor.start(); // called again (first called by AppDelegate constructor) to ensure permissions are forced + } else { + sensor.stop(); + automatedTestClient.add(this); + } } } diff --git a/herald/build.gradle b/herald/build.gradle index 2353ea8..18358e4 100644 --- a/herald/build.gradle +++ b/herald/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'io.heraldprox' -version = '2.1.0' +version = '2.1.1' apply plugin: 'com.android.library' @@ -17,7 +17,7 @@ android { minSdkVersion 21 targetSdkVersion 31 versionCode 2 - versionName "2.1.0" + versionName "2.1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro"