Skip to content

Commit 09b0281

Browse files
authored
Merge pull request #37 from martinwork/from288
From288
2 parents 73f556f + c8309bd commit 09b0281

22 files changed

+2481
-1017
lines changed

.idea/gradle.xml

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/runConfigurations.xml

Lines changed: 0 additions & 12 deletions
This file was deleted.

app/build.gradle

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 29
5-
buildToolsVersion '29.0.2'
4+
compileSdk 34
65
defaultConfig {
76
applicationId "com.samsung.microbit"
87
minSdkVersion 21
9-
targetSdkVersion 29
10-
// Once target SDK version is 30, requestLegacyStorage will no longer work
8+
targetSdk 33
9+
// When target SDK version is 30+,
10+
// requestLegacyExternalStorage will continue to work for 29 Android 10
1111
}
1212
buildTypes {
1313
release {
@@ -17,7 +17,8 @@ android {
1717
}
1818
productFlavors {
1919
}
20-
lintOptions {
20+
namespace 'com.samsung.microbit'
21+
lint {
2122
abortOnError false
2223
}
2324
}
@@ -29,7 +30,7 @@ dependencies {
2930
implementation 'androidx.cardview:cardview:1.0.0'
3031
implementation 'androidx.recyclerview:recyclerview:1.0.0'
3132
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.19'
32-
implementation 'no.nordicsemi.android:dfu:1.11.1'
33+
implementation 'no.nordicsemi.android:dfu:2.4.1'
3334
implementation project(':pfLibrary')
3435
implementation 'com.google.android.gms:play-services-analytics:9.2.0'
3536
implementation 'com.google.code.gson:gson:2.8.2'

app/src/main/AndroidManifest.xml

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@
1414
limitations under the License.
1515
-->
1616
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
17-
package="com.samsung.microbit"
18-
android:versionCode="38"
19-
android:versionName="2.8.8">
17+
android:versionCode="50"
18+
android:versionName="3.0.0">
2019

2120
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2221
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
2322
<uses-permission android:name="android.permission.INTERNET"/>
24-
<uses-permission android:name="android.permission.BLUETOOTH"/>
25-
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
26-
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
27-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
23+
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
24+
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/>
25+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
26+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
2827
<uses-permission android:name="android.permission.VIBRATE"/>
2928
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
3029
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" android:protectionLevel="signature"/>
@@ -34,18 +33,23 @@
3433
<uses-permission android:name="android.permission.CAMERA"/>
3534
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
3635

37-
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
38-
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
39-
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
36+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30"/>
37+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30"/>
38+
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" android:maxSdkVersion="30"/>
39+
40+
<!-- API 31 Needed only if your app looks for Bluetooth devices. -->
41+
<!-- Include "neverForLocation" only if you can strongly assert that
42+
your app never derives physical location from Bluetooth scan results. -->
43+
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
44+
<!-- API 31 Needed only if your app communicates with already-paired Bluetooth devices. -->
45+
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
4046

4147
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
4248
<uses-feature android:name="android.hardware.camera" android:required="false"/>
4349
<uses-feature android:name="android.hardware.camera.flash" android:required="false"/>
4450
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
4551
<uses-feature android:name="android.hardware.telephony" android:required="false"/>
4652

47-
48-
4953
<supports-screens android:normalScreens="true" />
5054
<supports-screens android:largeScreens="true" />
5155
<supports-screens android:xlargeScreens="true" />
@@ -70,9 +74,10 @@
7074
android:label="@string/app_name_without_colon"
7175
android:configChanges="orientation|screenSize|keyboardHidden"
7276
android:windowSoftInputMode="adjustResize"
73-
android:launchMode="singleTask">
74-
<!-- Intent filters for open micro:bit app, accord to user request -->
77+
android:launchMode="singleTask"
78+
android:exported="true">
7579

80+
<!-- Intent filters for open micro:bit app, accord to user request -->
7681

7782
<!-- This filter works, when request - open file from File Manager -->
7883
<intent-filter>
@@ -149,8 +154,7 @@
149154
android:configChanges="orientation|screenSize"
150155
android:label="MakeCode Webview"
151156
android:launchMode="singleTask"
152-
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
153-
android:screenOrientation="portrait"/>
157+
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
154158

155159
<activity
156160
android:name=".ui.activity.CameraActivityPermissionChecker"
@@ -187,7 +191,8 @@
187191
<activity
188192
android:name=".ui.activity.SplashScreenActivity"
189193
android:screenOrientation="locked"
190-
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
194+
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
195+
android:exported="true">
191196
<intent-filter>
192197
<action android:name="android.intent.action.MAIN"/>
193198

Lines changed: 63 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.samsung.microbit.core.bluetooth;
22

3+
import android.Manifest;
4+
import android.annotation.SuppressLint;
35
import android.bluetooth.BluetoothAdapter;
46
import android.bluetooth.BluetoothDevice;
57
import android.bluetooth.BluetoothGattCharacteristic;
68
import android.bluetooth.BluetoothManager;
79
import android.content.Context;
810
import android.content.SharedPreferences;
11+
import android.os.Build;
912
import android.provider.Settings;
1013
import android.util.Log;
1114

@@ -17,12 +20,16 @@
1720

1821
import static com.samsung.microbit.BuildConfig.DEBUG;
1922

23+
import androidx.core.content.ContextCompat;
24+
import androidx.core.content.PermissionChecker;
25+
2026
public class BluetoothUtils {
2127
private static final String TAG = BluetoothUtils.class.getSimpleName();
2228

2329
public static final String PREFERENCES_KEY = "Microbit_PairedDevices";
2430
public static final String PREFERENCES_PAIREDDEV_KEY = "PairedDeviceDevice";
2531

32+
// sConnectedDevice used only as a buffer - actual value stored in prefs
2633
private static ConnectedDevice sConnectedDevice = new ConnectedDevice();
2734

2835
private static void logi(String message) {
@@ -37,19 +44,44 @@ public static SharedPreferences getPreferences(Context ctx) {
3744
return ctx.getApplicationContext().getSharedPreferences(PREFERENCES_KEY, Context.MODE_MULTI_PROCESS);
3845
}
3946

40-
public static int getTotalPairedMicroBitsFromSystem() {
41-
int totalPairedMicroBits = 0;
42-
BluetoothAdapter mBluetoothAdapter = ((BluetoothManager) MBApp.getApp().getSystemService(Context
43-
.BLUETOOTH_SERVICE)).getAdapter();
44-
if(mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()) {
45-
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
46-
for(BluetoothDevice bt : pairedDevices) {
47-
if(bt.getName().contains("micro:bit")) {
48-
++totalPairedMicroBits;
49-
}
50-
}
47+
public static ConnectedDevice deviceFromPrefs(Context ctx) {
48+
SharedPreferences prefs = getPreferences( ctx);
49+
50+
ConnectedDevice fromPrefs = null;
51+
52+
if( prefs.contains(PREFERENCES_PAIREDDEV_KEY)) {
53+
String pairedDeviceString = prefs.getString(PREFERENCES_PAIREDDEV_KEY, null);
54+
Gson gson = new Gson();
55+
fromPrefs = gson.fromJson(pairedDeviceString, ConnectedDevice.class);
5156
}
52-
return totalPairedMicroBits;
57+
return fromPrefs;
58+
}
59+
60+
public static void deviceToPrefs(Context ctx, ConnectedDevice toPrefs) {
61+
SharedPreferences prefs = ctx.getApplicationContext().getSharedPreferences(PREFERENCES_KEY,
62+
Context.MODE_MULTI_PROCESS);
63+
SharedPreferences.Editor editor = prefs.edit();
64+
if( toPrefs == null) {
65+
editor.clear();
66+
} else {
67+
Gson gson = new Gson();
68+
String jsonActiveDevice = gson.toJson( toPrefs);
69+
editor.putString(PREFERENCES_PAIREDDEV_KEY, jsonActiveDevice);
70+
}
71+
editor.apply();
72+
}
73+
74+
private static boolean havePermission( Context ctx, String permission) {
75+
return ContextCompat.checkSelfPermission( ctx, permission) == PermissionChecker.PERMISSION_GRANTED;
76+
}
77+
78+
private static boolean havePermissionsFlashing( Context ctx) {
79+
boolean yes = true;
80+
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
81+
if ( !havePermission( ctx, Manifest.permission.BLUETOOTH_CONNECT))
82+
yes = false;
83+
}
84+
return yes;
5385
}
5486

5587
public static String parse(final BluetoothGattCharacteristic characteristic) {
@@ -89,51 +121,23 @@ public static boolean inZenMode(Context paramContext) {
89121
}
90122

91123
public static void updateFirmwareMicrobit(Context ctx, String firmware) {
92-
SharedPreferences pairedDevicePref = ctx.getApplicationContext().getSharedPreferences(PREFERENCES_KEY,
93-
Context.MODE_MULTI_PROCESS);
94-
if(pairedDevicePref.contains(PREFERENCES_PAIREDDEV_KEY)) {
95-
String pairedDeviceString = pairedDevicePref.getString(PREFERENCES_PAIREDDEV_KEY, null);
96-
Log.v("BluetoothUtils", "Updating the microbit firmware");
97-
ConnectedDevice deviceInSharedPref = new Gson().fromJson(pairedDeviceString, ConnectedDevice.class);
98-
deviceInSharedPref.mfirmware_version = firmware;
99-
setPairedMicroBit(ctx, deviceInSharedPref);
124+
ConnectedDevice fromPrefs = deviceFromPrefs(ctx);
125+
if( fromPrefs != null) {
126+
Log.v("BluetoothUtils", "Updating the microbit firmware version");
127+
fromPrefs.mfirmware_version = firmware;
128+
deviceToPrefs(ctx, fromPrefs);
100129
}
101130
}
102131

103132
public static void updateConnectionStartTime(Context ctx, long time) {
104-
SharedPreferences pairedDevicePref = ctx.getApplicationContext().getSharedPreferences(PREFERENCES_KEY,
105-
Context.MODE_MULTI_PROCESS);
106-
if(pairedDevicePref.contains(PREFERENCES_PAIREDDEV_KEY)) {
107-
String pairedDeviceString = pairedDevicePref.getString(PREFERENCES_PAIREDDEV_KEY, null);
108-
Log.e("BluetoothUtils", "Updating the microbit firmware");
109-
ConnectedDevice deviceInSharedPref = new Gson().fromJson(pairedDeviceString, ConnectedDevice.class);
110-
deviceInSharedPref.mlast_connection_time = time;
111-
setPairedMicroBit(ctx, deviceInSharedPref);
133+
ConnectedDevice fromPrefs = deviceFromPrefs(ctx);
134+
if( fromPrefs != null) {
135+
Log.e("BluetoothUtils", "Updating the microbit connection time");
136+
fromPrefs.mlast_connection_time = time;
137+
deviceToPrefs(ctx, fromPrefs);
112138
}
113139
}
114140

115-
public static BluetoothDevice getPairedDeviceMicroBit(Context context) {
116-
SharedPreferences pairedDevicePref = context.getApplicationContext().getSharedPreferences(PREFERENCES_KEY,
117-
Context.MODE_MULTI_PROCESS);
118-
if(pairedDevicePref.contains(PREFERENCES_PAIREDDEV_KEY)) {
119-
String pairedDeviceString = pairedDevicePref.getString(PREFERENCES_PAIREDDEV_KEY, null);
120-
Gson gson = new Gson();
121-
sConnectedDevice = gson.fromJson(pairedDeviceString, ConnectedDevice.class);
122-
//Check if the microbit is still paired with our mobile
123-
BluetoothAdapter mBluetoothAdapter = ((BluetoothManager) MBApp.getApp().getSystemService(Context
124-
.BLUETOOTH_SERVICE)).getAdapter();
125-
if(mBluetoothAdapter.isEnabled()) {
126-
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
127-
for(BluetoothDevice bt : pairedDevices) {
128-
if(bt.getAddress().equals(sConnectedDevice.mAddress)) {
129-
return bt;
130-
}
131-
}
132-
}
133-
}
134-
return null;
135-
}
136-
137141
public static ConnectedDevice getPairedMicrobit(Context ctx) {
138142
SharedPreferences pairedDevicePref = ctx.getApplicationContext().getSharedPreferences(PREFERENCES_KEY,
139143
Context.MODE_MULTI_PROCESS);
@@ -142,16 +146,18 @@ public static ConnectedDevice getPairedMicrobit(Context ctx) {
142146
sConnectedDevice = new ConnectedDevice();
143147
}
144148

145-
if(pairedDevicePref.contains(PREFERENCES_PAIREDDEV_KEY)) {
149+
ConnectedDevice fromPrefs = deviceFromPrefs(ctx);
150+
if( fromPrefs == null) {
151+
sConnectedDevice.mPattern = null;
152+
sConnectedDevice.mName = null;
153+
} else {
146154
boolean pairedMicrobitInSystemList = false;
147-
String pairedDeviceString = pairedDevicePref.getString(PREFERENCES_PAIREDDEV_KEY, null);
148-
Gson gson = new Gson();
149-
sConnectedDevice = gson.fromJson(pairedDeviceString, ConnectedDevice.class);
155+
sConnectedDevice = fromPrefs;
150156
//Check if the microbit is still paired with our mobile
151157
BluetoothAdapter mBluetoothAdapter = ((BluetoothManager) MBApp.getApp().getSystemService(Context
152158
.BLUETOOTH_SERVICE)).getAdapter();
153-
if(mBluetoothAdapter.isEnabled()) {
154-
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
159+
if(mBluetoothAdapter.isEnabled() && havePermissionsFlashing( ctx)) {
160+
@SuppressLint("MissingPermission") Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
155161
for(BluetoothDevice bt : pairedDevices) {
156162
if(bt.getAddress().equals(sConnectedDevice.mAddress)) {
157163
pairedMicrobitInSystemList = true;
@@ -176,26 +182,12 @@ public static ConnectedDevice getPairedMicrobit(Context ctx) {
176182

177183
setPairedMicroBit(ctx, null);
178184
}
179-
} else {
180-
sConnectedDevice.mPattern = null;
181-
sConnectedDevice.mName = null;
182185
}
183186
return sConnectedDevice;
184187
}
185188

186189
public static void setPairedMicroBit(Context ctx, ConnectedDevice newDevice) {
187-
SharedPreferences pairedDevicePref = ctx.getApplicationContext().getSharedPreferences(PREFERENCES_KEY,
188-
Context.MODE_MULTI_PROCESS);
189-
SharedPreferences.Editor editor = pairedDevicePref.edit();
190-
if(newDevice == null) {
191-
editor.clear();
192-
} else {
193-
Gson gson = new Gson();
194-
String jsonActiveDevice = gson.toJson(newDevice);
195-
editor.putString(PREFERENCES_PAIREDDEV_KEY, jsonActiveDevice);
196-
}
197-
198-
editor.apply();
190+
deviceToPrefs( ctx, newDevice);
199191
}
200192

201193
}

app/src/main/java/com/samsung/microbit/data/constants/PermissionCodes.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@ private PermissionCodes() {
1414
public static final int CAMERA_PERMISSIONS_REQUESTED = 0x03;
1515
public static final int INCOMING_CALL_PERMISSIONS_REQUESTED = 0x03;
1616
public static final int INCOMING_SMS_PERMISSIONS_REQUESTED = 0x04;
17+
public static final int BLUETOOTH_PERMISSIONS_REQUESTED_API28 = 0x10;
18+
public static final int BLUETOOTH_PERMISSIONS_REQUESTED_API29 = 0x11;
19+
public static final int BLUETOOTH_PERMISSIONS_REQUESTED_API30_FOREGROUND = 0x12;
20+
public static final int BLUETOOTH_PERMISSIONS_REQUESTED_API30_BACKGROUND = 0x13;
21+
public static final int BLUETOOTH_PERMISSIONS_REQUESTED_API31 = 0x14;
22+
public static final int BLUETOOTH_PERMISSIONS_REQUESTED_FLASHING_API31 = 0x15;
23+
24+
1725
}

app/src/main/java/com/samsung/microbit/data/constants/RequestCodes.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ private RequestCodes() {
88
}
99

1010
public static final int REQUEST_ENABLE_BT = 12345;
11+
public static final int REQUEST_ENABLE_LOCATION = 12346;
1112
public static final int REQUEST_RESTART_SERVICES = 110;
1213
}

app/src/main/java/com/samsung/microbit/data/model/ui/PairingActivityState.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55
*/
66
public class PairingActivityState extends BaseActivityState {
77
public static final int STATE_ENABLE_BT_FOR_PAIRING = 5;
8+
public static final int STATE_ENABLE_LOCATION_FOR_PAIRING = 6;
89
}

0 commit comments

Comments
 (0)