diff --git a/app/build.gradle b/app/build.gradle index f00bb3863..fa1c980a2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -74,8 +74,8 @@ android { applicationId "nodomain.freeyourgadget.gadgetbridge" //noinspection OldTargetApi - targetSdkVersion 33 - compileSdk 33 + targetSdkVersion 34 + compileSdk 34 minSdkVersion 21 // Note: always bump BOTH versionCode and versionName! @@ -114,7 +114,7 @@ android { applicationIdSuffix ".banglejs" versionNameSuffix "-banglejs" buildConfigField "boolean", "INTERNET_ACCESS", "true" - targetSdkVersion 33 + targetSdkVersion 34 // Note: app/src/banglejs/AndroidManifest.xml contains some extra permissions } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5bf5266f1..4ee80bbfd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -59,6 +59,8 @@ + + @@ -455,22 +457,35 @@ android:name=".externalevents.NotificationListener" android:label="@string/app_name" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" - android:exported="false"> + android:exported="false" + android:foregroundServiceType="specialUse"> + - - + + + + + android:label="PineTime Nordic DFU service" + android:foregroundServiceType="connectedDevice" /> - + android:exported="false" + android:foregroundServiceType="connectedDevice" /> = Build.VERSION_CODES.Q) { + startForeground(GB.NOTIFICATION_ID, GB.createNotification(getString(R.string.gadgetbridge_running), this), ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE); + } else { + startForeground(GB.NOTIFICATION_ID, GB.createNotification(getString(R.string.gadgetbridge_running), this)); + } } private boolean isDeviceConnected(GBDevice device) { @@ -1289,16 +1294,16 @@ public class DeviceCommunicationService extends Service implements SharedPrefere calendarIntentFilter.addDataScheme("content"); calendarIntentFilter.addDataAuthority("com.android.calendar", null); CalendarReceiver receiver = new CalendarReceiver(deviceWithCalendar); - registerReceiver(receiver, calendarIntentFilter); + ContextCompat.registerReceiver(this, receiver, calendarIntentFilter, ContextCompat.RECEIVER_EXPORTED); mCalendarReceiver.add(receiver); // Add a receiver to allow us to quickly force as calendar sync (without having to provide data) - registerReceiver(receiver, new IntentFilter("FORCE_CALENDAR_SYNC")); + ContextCompat.registerReceiver(this, receiver, new IntentFilter("FORCE_CALENDAR_SYNC"), ContextCompat.RECEIVER_EXPORTED); } } } if (mAlarmReceiver == null) { mAlarmReceiver = new AlarmReceiver(); - registerReceiver(mAlarmReceiver, new IntentFilter("DAILY_ALARM")); + ContextCompat.registerReceiver(this, mAlarmReceiver, new IntentFilter("DAILY_ALARM"), ContextCompat.RECEIVER_EXPORTED); } } else { for (CalendarReceiver registeredReceiver: mCalendarReceiver){ @@ -1318,15 +1323,15 @@ public class DeviceCommunicationService extends Service implements SharedPrefere filter.addAction("android.intent.action.PHONE_STATE"); filter.addAction("android.intent.action.NEW_OUTGOING_CALL"); filter.addAction("nodomain.freeyourgadget.gadgetbridge.MUTE_CALL"); - registerReceiver(mPhoneCallReceiver, filter); + ContextCompat.registerReceiver(this, mPhoneCallReceiver, filter, ContextCompat.RECEIVER_EXPORTED); } if (mSMSReceiver == null) { mSMSReceiver = new SMSReceiver(); - registerReceiver(mSMSReceiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED")); + ContextCompat.registerReceiver(this, mSMSReceiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"), ContextCompat.RECEIVER_EXPORTED); } if (mPebbleReceiver == null) { mPebbleReceiver = new PebbleReceiver(); - registerReceiver(mPebbleReceiver, new IntentFilter("com.getpebble.action.SEND_NOTIFICATION")); + ContextCompat.registerReceiver(this, mPebbleReceiver, new IntentFilter("com.getpebble.action.SEND_NOTIFICATION"), ContextCompat.RECEIVER_EXPORTED); } if (mMusicPlaybackReceiver == null && features.supportsMusicInfo()) { mMusicPlaybackReceiver = new MusicPlaybackReceiver(); @@ -1334,7 +1339,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere for (String action : mMusicActions) { filter.addAction(action); } - registerReceiver(mMusicPlaybackReceiver, filter); + ContextCompat.registerReceiver(this, mMusicPlaybackReceiver, filter, ContextCompat.RECEIVER_EXPORTED); } if (mTimeChangeReceiver == null) { mTimeChangeReceiver = new TimeChangeReceiver(); @@ -1342,14 +1347,14 @@ public class DeviceCommunicationService extends Service implements SharedPrefere filter.addAction("android.intent.action.TIME_SET"); filter.addAction("android.intent.action.TIMEZONE_CHANGED"); filter.addAction(TimeChangeReceiver.ACTION_DST_CHANGED_OR_PERIODIC_SYNC); - registerReceiver(mTimeChangeReceiver, filter); + ContextCompat.registerReceiver(this, mTimeChangeReceiver, filter, ContextCompat.RECEIVER_EXPORTED); // Ensure alarm is scheduled after registering broadcast receiver // (this is important in case receiver was unregistered when the previous alarm arrived). TimeChangeReceiver.ifEnabledScheduleNextDstChangeOrPeriodicSync(this); } if (mBlueToothPairingRequestReceiver == null) { mBlueToothPairingRequestReceiver = new BluetoothPairingRequestReceiver(this); - registerReceiver(mBlueToothPairingRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)); + ContextCompat.registerReceiver(this, mBlueToothPairingRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST), ContextCompat.RECEIVER_EXPORTED); } if (mAlarmClockReceiver == null) { mAlarmClockReceiver = new AlarmClockReceiver(); @@ -1358,14 +1363,14 @@ public class DeviceCommunicationService extends Service implements SharedPrefere filter.addAction(AlarmClockReceiver.ALARM_DONE_ACTION); filter.addAction(AlarmClockReceiver.GOOGLE_CLOCK_ALARM_ALERT_ACTION); filter.addAction(AlarmClockReceiver.GOOGLE_CLOCK_ALARM_DONE_ACTION); - registerReceiver(mAlarmClockReceiver, filter); + ContextCompat.registerReceiver(this, mAlarmClockReceiver, filter, ContextCompat.RECEIVER_EXPORTED); } if (mSilentModeReceiver == null) { mSilentModeReceiver = new SilentModeReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); - registerReceiver(mSilentModeReceiver, filter); + ContextCompat.registerReceiver(this, mSilentModeReceiver, filter, ContextCompat.RECEIVER_EXPORTED); } if (locationService == null) { @@ -1382,21 +1387,21 @@ public class DeviceCommunicationService extends Service implements SharedPrefere if (GBApplication.isRunningOreoOrLater()) { if (mLineageOsWeatherReceiver == null) { mLineageOsWeatherReceiver = new LineageOsWeatherReceiver(); - registerReceiver(mLineageOsWeatherReceiver, new IntentFilter("GB_UPDATE_WEATHER")); + ContextCompat.registerReceiver(this, mLineageOsWeatherReceiver, new IntentFilter("GB_UPDATE_WEATHER"), ContextCompat.RECEIVER_EXPORTED); } } else { if (mCMWeatherReceiver == null) { mCMWeatherReceiver = new CMWeatherReceiver(); - registerReceiver(mCMWeatherReceiver, new IntentFilter("GB_UPDATE_WEATHER")); + ContextCompat.registerReceiver(this, mCMWeatherReceiver, new IntentFilter("GB_UPDATE_WEATHER"), ContextCompat.RECEIVER_EXPORTED); } } if (mTinyWeatherForecastGermanyReceiver == null) { mTinyWeatherForecastGermanyReceiver = new TinyWeatherForecastGermanyReceiver(); - registerReceiver(mTinyWeatherForecastGermanyReceiver, new IntentFilter("de.kaffeemitkoffein.broadcast.WEATHERDATA")); + ContextCompat.registerReceiver(this, mTinyWeatherForecastGermanyReceiver, new IntentFilter("de.kaffeemitkoffein.broadcast.WEATHERDATA"), ContextCompat.RECEIVER_EXPORTED); } if (mGenericWeatherReceiver == null) { mGenericWeatherReceiver = new GenericWeatherReceiver(); - registerReceiver(mGenericWeatherReceiver, new IntentFilter(GenericWeatherReceiver.ACTION_GENERIC_WEATHER)); + ContextCompat.registerReceiver(this, mGenericWeatherReceiver, new IntentFilter(GenericWeatherReceiver.ACTION_GENERIC_WEATHER), ContextCompat.RECEIVER_EXPORTED); } if (mOmniJawsObserver == null) { try { @@ -1412,14 +1417,14 @@ public class DeviceCommunicationService extends Service implements SharedPrefere { if (mSleepAsAndroidReceiver == null) { mSleepAsAndroidReceiver = new SleepAsAndroidReceiver(); - registerReceiver(mSleepAsAndroidReceiver, new IntentFilter()); + ContextCompat.registerReceiver(this, mSleepAsAndroidReceiver, new IntentFilter(), ContextCompat.RECEIVER_EXPORTED); } } if (GBApplication.getPrefs().getBoolean("auto_fetch_enabled", false) && features.supportsActivityDataFetching() && mGBAutoFetchReceiver == null) { mGBAutoFetchReceiver = new GBAutoFetchReceiver(); - registerReceiver(mGBAutoFetchReceiver, new IntentFilter("android.intent.action.USER_PRESENT")); + ContextCompat.registerReceiver(this, mGBAutoFetchReceiver, new IntentFilter("android.intent.action.USER_PRESENT"), ContextCompat.RECEIVER_EXPORTED); } } else { if (mPhoneCallReceiver != null) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLEScanService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLEScanService.java index 5e6efa224..f5d622dc9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLEScanService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/BLEScanService.java @@ -35,12 +35,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.pm.ServiceInfo; import android.os.Build; import android.os.Handler; import android.os.IBinder; import androidx.core.app.ActivityCompat; import androidx.core.app.NotificationCompat; +import androidx.core.content.ContextCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.slf4j.Logger; @@ -215,7 +217,11 @@ public class BLEScanService extends Service { private void startForeground() { Notification serviceNotification = createNotification(false, 0); - super.startForeground(GB.NOTIFICATION_ID_SCAN, serviceNotification); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + super.startForeground(GB.NOTIFICATION_ID_SCAN, serviceNotification, ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE); + } else { + super.startForeground(GB.NOTIFICATION_ID_SCAN, serviceNotification); + } } @Override @@ -315,9 +321,11 @@ public class BLEScanService extends Service { filter ); - registerReceiver( + ContextCompat.registerReceiver( + this, bluetoothStateChangedReceiver, - new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) + new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED), + ContextCompat.RECEIVER_EXPORTED ); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java index eacc9afee..8e88e59f6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/actions/BondAction.java @@ -22,6 +22,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; +import androidx.core.content.ContextCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -65,7 +66,7 @@ public class BondAction extends PlainAction implements BondingInterface { @Override public void registerBroadcastReceivers() { LocalBroadcastManager.getInstance(GBApplication.getContext()).registerReceiver(pairingReceiver, new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED)); - getContext().registerReceiver(bondingReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)); + ContextCompat.registerReceiver(getContext(), bondingReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED), ContextCompat.RECEIVER_EXPORTED); } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/flipper/zero/support/FlipperZeroSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/flipper/zero/support/FlipperZeroSupport.java index 726afd6c0..5f4a5c4ec 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/flipper/zero/support/FlipperZeroSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/flipper/zero/support/FlipperZeroSupport.java @@ -24,12 +24,11 @@ import android.content.Intent; import android.content.IntentFilter; import android.widget.Toast; +import androidx.core.content.ContextCompat; + import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.util.UUID; -import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; @@ -127,7 +126,7 @@ public class FlipperZeroSupport extends FlipperZeroBaseSupport{ @Override protected TransactionBuilder initializeDevice(TransactionBuilder builder) { if(!recevierRegistered) { - getContext().registerReceiver(receiver, new IntentFilter(COMMAND_PLAY_FILE)); + ContextCompat.registerReceiver(getContext(), receiver, new IntentFilter(COMMAND_PLAY_FILE), ContextCompat.RECEIVER_EXPORTED); recevierRegistered = true; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java index a912af8a8..3702181e7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleKitSupport.java @@ -22,6 +22,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.util.Base64; +import androidx.core.content.ContextCompat; + import org.json.JSONArray; import org.json.JSONException; import org.slf4j.Logger; @@ -131,7 +133,7 @@ class PebbleKitSupport { intentFilter.addAction(PEBBLEKIT_ACTION_APP_START); intentFilter.addAction(PEBBLEKIT_ACTION_APP_STOP); intentFilter.addAction(PEBBLEKIT_ACTION_DL_ACK_DATA); - mContext.registerReceiver(mPebbleKitReceiver, intentFilter); + ContextCompat.registerReceiver(mContext, mPebbleKitReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED); } void sendAppMessageIntent(GBDeviceEventAppMessage appMessage) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java index 1b84873c0..6606874fb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/QHybridSupport.java @@ -28,6 +28,7 @@ import android.net.Uri; import android.os.Bundle; import android.widget.Toast; +import androidx.core.content.ContextCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.json.JSONException; @@ -393,7 +394,7 @@ public class QHybridSupport extends QHybridBaseSupport { } } }; - GBApplication.getContext().registerReceiver(globalCommandReceiver, globalFilter); + ContextCompat.registerReceiver(GBApplication.getContext(), globalCommandReceiver, globalFilter, ContextCompat.RECEIVER_EXPORTED); } private void handleConfigSetIntent(Intent intent) {