react-native-serialport icon indicating copy to clipboard operation
react-native-serialport copied to clipboard

Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent

Open little-infinity opened this issue 1 year ago • 2 comments

After updating android target Sdk to 31. Before that it was working fine. build.gradle

buildscript {
    ext {
        buildToolsVersion = "30.0.3"
        minSdkVersion = 28
        compileSdkVersion = 31
        targetSdkVersion = 31
        supportLibVersion = "30.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:3.4.0")
    }
}

As soon as a USB device is connected following error gets thrown :

Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.

little-infinity avatar Jun 12 '23 07:06 little-infinity

The cause of this error can be found in the RNSerialPortModule.java file.

method : requestUserPermission()

 private void requestUserPermission() {
    if(device == null)
      return;
    PendingIntent mPendingIntent = PendingIntent.getBroadcast(reactContext, 0 , new Intent(ACTION_USB_PERMISSION), 0);
    usbManager.requestPermission(device, mPendingIntent);
  }

Android API 31 onwards you need to set explicit FLAG while creating a PendingIntent https://developer.android.com/reference/android/app/PendingIntent#FLAG_MUTABLE

  private void requestUserPermission() {
    if (device == null) 
      return;
    PendingIntent mPendingIntent = PendingIntent.getBroadcast(reactContext, 0, new Intent(ACTION_USB_PERMISSION), 
    PendingIntent.FLAG_MUTABLE);
    usbManager.requestPermission(device, mPendingIntent);
  }

Till the time this fix is available you can patch it using patch-package :

  1. Update requestUserPermission() in RNSerialPortModule.java:
  private void requestUserPermission() {
    if (device == null) 
      return;
    PendingIntent mPendingIntent = PendingIntent.getBroadcast(reactContext, 0, new Intent(ACTION_USB_PERMISSION), 
    PendingIntent.FLAG_MUTABLE);
    usbManager.requestPermission(device, mPendingIntent);
  }
  1. Install patch-package: npm install patch-package -D or using yarn yarn add patch-package

  2. add postinstall script to package.json:

"scripts": {
  "postinstall": "patch-package"
 }
  1. Run patch-package to create a .patch file npx patch-package react-native-serialport or yarn patch-package react-native-serialport This will create .patch file with name react-native-serialport+1.3.1.patch - This can be committed in your project for the time being.
  2. Apply your fix: npm install or yarn install

Hopefully, this works for you as well if someone is facing the same error.

little-infinity avatar Jun 12 '23 07:06 little-infinity

I've fixed that problem on my branch:

https://github.com/goostavo/react-native-serialport

Goostavo avatar Apr 11 '24 01:04 Goostavo