0

My Android app launches the in-app purchasing interface from a fragment, like this:

Bundle responseBundle = this.billingService.getBuyIntent(3, getPackageName(), id, "inapp", StringUtils.randomString(32));
PendingIntent pendingIntent = responseBundle.getParcelable("BUY_INTENT");
fragment.getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(), R.id.buyUpgradeResponse, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));

This was working fine until I increased my targetSdkVersion from 23 to 25 to add some Android 7 features. Now the startIntentSenderForResult line throws this exception:

java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode

This means the request code (2nd argument of that method) has a limit of 65,535. But the R.id.buyUpgradeResponse, which is randomly generated from the ids.xml file, has a value of something like 20,000,000. Is there a way limit the range Android uses for randomly-generated resource IDs?

Another SO answer says this error only occurs when using android.support.v4.app.FragmentActivity. My activities all use a base activity that extends AppCompatActivity, which extends android.support.v7.app.AppCompatActivity, which extends android.support.v4.app.FragmentActivity. So another approach would be removing my reliance on the support.v4 class. But I'm afraid to make a global change that could have unintended consequences in any part of my app. (My minSdkVersion is 15, if that matters.)

I could also just replace R.id.buyUpgradeResponse with a hard-coded ID, but I'm afraid there are other places in the app that have the same problem, and that wouldn't solve all instances of the problem.

Update

I just confirmed that the change to my build settings is what triggered the problem. The problem did not occur with my previous settings:

compileSdkVersion 23
buildToolsVersion '25.0.2'
minSdkVersion 15
targetSdkVersion 23
compile "com.android.support:appcompat-v7:23.0.0"

The problem started when I updated these settings:

compileSdkVersion 25
buildToolsVersion '25.0.2'
minSdkVersion 15
targetSdkVersion 25
compile "com.android.support:appcompat-v7:25.3.1"

Update 2

I just ran into this again while implementing the Storage Access Framework. startActivityForResult generated the invalid ID exception because the randomly-generated ID was 20 million something. Other functions in my app, like opening a fragment in a popup, use these IDs without complaint, but the SAF intents won't. I ended up hard-coding more IDs for the SAF intents. I think the best solution would be to restrict the range of the randomly-generated IDs to a range that all frameworks support, but I don't see a way to do that.

arlomedia
  • 8,534
  • 5
  • 60
  • 108
  • Framework fragments/activities have the same requirement on their requestCode, so not using the Support Libraries won't help you. Why were you using ids in the first place instead of just a few constants you define? – ianhanniballake May 31 '17 at 17:43
  • 1
    "Why were you using ids" - I have dozens of alerts and popups that take an ID argument, so I've just been adding items to the ids.xml file for all of them. – arlomedia May 31 '17 at 18:22
  • It looks like `Fragment.startActivityForResult()` and `DialogFragment.setTargetFragment()` still work fine with the auto-generated IDs, so maybe I just need to hard-code an ID for `Activity. startIntentSenderForResult()`, which I'm only using in one place currently. – arlomedia May 31 '17 at 18:33

1 Answers1

0

I found that the problem doesn't happen if I start an activity from a fragment rather than from the fragment's activity. So this triggers the problem:

fragment.getActivity().startIntentSenderForResult(pendingIntent.getIntentSender(), R.id.buyUpgradeResponse, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));

But this is fine:

fragment.startIntentSenderForResult(pendingIntent.getIntentSender(), R.id.buyUpgradeResponse, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));

Maybe there's a logic to that, but I don't know what it is.

arlomedia
  • 8,534
  • 5
  • 60
  • 108