Mobile Payments SDK appears to not work with Android 14 due to a missing receiver flag

  1. Create an Android app that targets Android SDK Level 34.
  2. Use mobile-payments-sdk version 2.0.0-beta2
  3. Use a production Application ID
  4. Deploy the app to an Android device which is on Android 14.
  5. Call MobilePaymentsSdk.settingsManager().showSettings
  6. Try to pair with a Square reader by holding down the pairing button.

The app gets stuck in a loop where it keeps throwing this exception:
kotlinx.coroutines.JobCancellationException: Parent job is Cancelling; job=JobImpl{Cancelling}@ccfc8f1
Caused by: java.lang.SecurityException: net.salespad.square: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn’t being registered exclusively for system broadcasts
at android.os.Parcel.createExceptionOrNull(Parcel.java:3183)
at android.os.Parcel.createException(Parcel.java:3167)
at android.os.Parcel.readException(Parcel.java:3150)
at android.os.Parcel.readException(Parcel.java:3092)
at android.app.IActivityManager$Stub$Proxy.registerReceiverWithFeature(IActivityManager.java:5860)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1853)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1793)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1781)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:757)
at com.squareup.cardreader.ble.lock.RealBleLock.awaitDisconnectionRequestBroadcastAndDisconnect(RealBleLock.kt:104)
at com.squareup.cardreader.ble.lock.RealBleLock.access$awaitDisconnectionRequestBroadcastAndDisconnect(RealBleLock.kt:31)
at com.squareup.cardreader.ble.lock.RealBleLock$requestConnectToDevice$2.invokeSuspend(RealBleLock.kt:49)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:68)
at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:375)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at com.squareup.workflow1.RenderWorkflowKt.renderWorkflowIn(RenderWorkflow.kt:171)
at com.squareup.workflow1.RenderWorkflowKt.renderWorkflowIn$default(RenderWorkflow.kt:106)
at com.squareup.cardreaders.RealCardreaderWorkflowRunner.(CardreaderWorkflow.kt:621)
at com.squareup.cardreaders.RealCardreaderWorkflowRunnerFactory.create(CardreaderWorkflow.kt:466)
at com.squareup.cardreaders.RealCardreaders.connectTo(RealCardreaders.kt:257)
at com.squareup.cardreaders.RealCardreaders.connect(RealCardreaders.kt:300)
at com.squareup.sdk.mobilepayments.cardreader.RealReaderManager.handleSuccessfulDiscoveryResult(RealReaderManager.kt:281)
at com.squareup.sdk.mobilepayments.cardreader.RealReaderManager.access$handleSuccessfulDiscoveryResult(RealReaderManager.kt:74)
at com.squareup.sdk.mobilepayments.cardreader.RealReaderManager$pairReader$3$2.invoke(RealReaderManager.kt:251)
at com.squareup.sdk.mobilepayments.cardreader.RealReaderManager$pairReader$3$2.invoke(RealReaderManager.kt:250)
at com.squareup.sdk.mobilepayments.cardreader.RealReaderManager$pairReader$3.invoke$lambda$1(RealReaderManager.kt:250)
at com.squareup.sdk.mobilepayments.cardreader.RealReaderManager$pairReader$3.$r8$lambda$CgC6_K-l1TRHJdH4l2-q1o_32JY(Unknown Source:0)
at com.squareup.sdk.mobilepayments.cardreader.RealReaderManager$pairReader$3$$ExternalSyntheticLambda1.apply(D8$$SyntheticClass:0)
at io.reactivex.internal.operators.mixed.SingleFlatMapObservable$FlatMapObserver.onSuccess(SingleFlatMapObservable.java:102)
at io.reactivex.internal.operators.observable.ObservableElementAtSingle$ElementAtObserver.onNext(ObservableElementAtSingle.java:89)
at io.reactivex.internal.operators.observable.ObservableFilter$FilterObserver.onNext(ObservableFilter.java:52)
at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:62)
at io.reactivex.subjects.PublishSubject$PublishDisposable.onNext(PublishSubject.java:308)
at io.reactivex.subjects.PublishSubject.onNext(PublishSubject.java:228)
at com.squareup.btscan.RealBleCardreaderScanner$Scan.emitResults(RealBleCardreaderScanner.kt:119)
at com.squareup.btscan.RealBleCardreaderScanner$Scan.onScanResult$lambda$5(RealBleCardreaderScanner.kt:202)
at com.squareup.btscan.RealBleCardreaderScanner$Scan.$r8$lambda$Lc9cT4PnteA7jabc3pRzKIxZFa4(Unknown Source:0)
at com.squareup.btscan.RealBleCardreaderScanner$Scan$$ExternalSyntheticLambda1.run(D8$$SyntheticClass:0)
at com.squareup.thread.executor.StoppableHandlerExecutor.execute(StoppableHandlerExecutor.java:66)
at com.squareup.btscan.RealBleCardreaderScanner$Scan.onScanResult(RealBleCardreaderScanner.kt:139)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:568)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.app.ActivityThread.main(ActivityThread.java:8592)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:878)

Are there any workarounds for this or plans to fix it?

Are you using Mobile Payments SDK: 2.0.0-beta2? :slightly_smiling_face:

Yes, I’m using mobile-payments-sdk-2.0.0-beta2

Okay, you may need to apply this workaround till Android 14 is fully supported in the next release. :slightly_smiling_face:

Thank you Bryan, that workaround worked for me!

Great! Glad to hear it worked. :slightly_smiling_face: