Integrating the paypal SDK in an android app with SDK 31

I encountered a stackoverflow question which did not have anywhere near enough details to debug what was happening, and contained pasted images.

The problem was that the developer was attempting to integrate the Paypal Checkout SDK into an Android app, and it was not building with a ‘merge resources’ error.

When I pointed the developer to the ‘how to fix’ question, they didn’t believe it would fix their problem and very soon afterwards the question was closed with ‘needs more details’.

It had scratched an itch with me, so I started a new android SDK project to test this integration myself. The github repository is available for all to see.

I started with a main branch without any paypal SDK integration. It builds and runs.

Then I created an ‘adding_paypal’ branch, where I was introducing the paypal SDK. Step one was adding the SDK. I too experienced the ‘merge resources’ error, and when I clicked back on the log I saw:

...PaypalSdkIntegration/app/src/main/AndroidManifest.xml Error:
android:exported needs to be explicitly specified for <activity>. Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.
...PaypalSdkIntegration/app/src/main/AndroidManifest.xml Error:
android:exported needs to be explicitly specified for <activity>. Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.

There is a very simple solution to this – revert the targetSdk to 30, instead of the 31 that it was currently set to. This is what I did for the initial commit.

Then I sat down, and looked at the ‘merged manifest’. Any <activity> items that didn’t have an android:exported tag, needed to be merged in my own AndroidManifest.xml.

Firstly, add the tools namespace to the AndroidManifest.xml file, so in the <manifest> tag, you add:

xmlns:tools="http://schemas.android.com/tools"

Then add entries for all the activities that were present in the merged AndroidManifest which don’t have an android:exported property, and apply a merge flag for them. The true/false value I chose was based on the premise:

True: If there was an intent filter.
False: When there are no intent filters.

Merge items look like:

<activity android:name="com.paypal.authcore.authentication.TokenActivity"
android:exported="false"
tools:node="merge" />

While I was writing up this article, I noticed that I had completely inverted the logic, so I fixed it in a third commit to the branch.

I hope this helps someone who’s having the same problem. It can be applied when you encounter any project that has the same merged manifest issue. The general procedure is:

  • Set to targetSdk 30
  • Build, which should work cleanly
  • Look at all activities that do not have an android:exported tag and add a merge node in your own manifest file.
  • Set to targetSdk 31
  • Build, which should now build correctly.