odemolliens / react-native-sim-cards-manager

React Native plugin to manage Sim card(s) & eSim
MIT License
67 stars 29 forks source link

android API Level 33 , getNumber is not working , and we can't get phone number in response #42

Closed prashilak closed 1 year ago

prashilak commented 1 year ago

[ { "carrierName": "JIO — Jio", "displayName": "SIM1", "phoneNumber": "", "simSerialNumber": "", "simSlotIndex": 0, "subscriptionId": 1 }, { "carrierName": "airtel", "displayName": "SIM2", "phoneNumber": "", "simSerialNumber": "", "simSlotIndex": 1, "subscriptionId": 2 } ]

officialomkarjadhav commented 1 year ago

@TarikHuber

officialomkarjadhav commented 1 year ago

[ { "carrierName": "JIO — Jio", "displayName": "SIM1", "phoneNumber": "", "simSerialNumber": "", "simSlotIndex": 0, "subscriptionId": 1 }, { "carrierName": "airtel", "displayName": "SIM2", "phoneNumber": "", "simSerialNumber": "", "simSlotIndex": 1, "subscriptionId": 2 } ]

hi @prashilak you got any solution

xiiao5777 commented 1 year ago

About this problem, you need to at node_modules->react-native-sin-cards-manager ->android -> src -> main -> com -> reactnativesimcardsmanager -> SimCardsManagerModule.java

adding the code as `if(android.os.Build.VERSION.SDK_INT >= 33){ int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount(); int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

    List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();

    for (SubscriptionInfo subInfo : subscriptionInfos) {
      WritableMap simCard = Arguments.createMap();

      CharSequence carrierName = subInfo.getCarrierName();
      String countryIso = subInfo.getCountryIso();
      int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
      CharSequence displayName = subInfo.getDisplayName();
      String iccId = subInfo.getIccId();
      int mcc = subInfo.getMcc();
      int mnc = subInfo.getMnc();
      String number = manager.getPhoneNumber(subInfo.getSubscriptionId(),3);
      int simSlotIndex = subInfo.getSimSlotIndex();
      int subscriptionId = subInfo.getSubscriptionId();
      int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

      simCard.putString("carrierName", carrierName.toString());
      simCard.putString("displayName", displayName.toString());
      simCard.putString("isoCountryCode", countryIso);
      simCard.putInt("mobileCountryCode", mcc);
      simCard.putInt("mobileNetworkCode", mnc);
      simCard.putInt("isNetworkRoaming", networkRoaming);
      simCard.putInt("isDataRoaming", dataRoaming);
      simCard.putInt("simSlotIndex", simSlotIndex);
      simCard.putString("phoneNumber", number);
      simCard.putString("simSerialNumber", iccId);
      simCard.putInt("subscriptionId", subscriptionId);

      simCardsList.pushMap(simCard);
    }
  }else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) `

  put this code inside the getSimCardsNative function. it works on me
xiiao5777 commented 1 year ago

About this problem, you need to at node_modules->react-native-sin-cards-manager ->android -> src -> main -> com -> reactnativesimcardsmanager -> SimCardsManagerModule.java

adding the code as `if(android.os.Build.VERSION.SDK_INT >= 33){ int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount(); int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

    List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();

    for (SubscriptionInfo subInfo : subscriptionInfos) {
      WritableMap simCard = Arguments.createMap();

      CharSequence carrierName = subInfo.getCarrierName();
      String countryIso = subInfo.getCountryIso();
      int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
      CharSequence displayName = subInfo.getDisplayName();
      String iccId = subInfo.getIccId();
      int mcc = subInfo.getMcc();
      int mnc = subInfo.getMnc();
      String number = manager.getPhoneNumber(subInfo.getSubscriptionId(),3);
      int simSlotIndex = subInfo.getSimSlotIndex();
      int subscriptionId = subInfo.getSubscriptionId();
      int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

      simCard.putString("carrierName", carrierName.toString());
      simCard.putString("displayName", displayName.toString());
      simCard.putString("isoCountryCode", countryIso);
      simCard.putInt("mobileCountryCode", mcc);
      simCard.putInt("mobileNetworkCode", mnc);
      simCard.putInt("isNetworkRoaming", networkRoaming);
      simCard.putInt("isDataRoaming", dataRoaming);
      simCard.putInt("simSlotIndex", simSlotIndex);
      simCard.putString("phoneNumber", number);
      simCard.putString("simSerialNumber", iccId);
      simCard.putInt("subscriptionId", subscriptionId);

      simCardsList.pushMap(simCard);
    }
  }else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) `

  put this code inside the getSimCardsNative function. it works on me

and you also need to add this inside the index.js requestCellularNetworkPermission function let granted = '' if(react_native_1.Platform.Version >= 33){ granted = await react_native_1.PermissionsAndroid.request(react_native_1.PermissionsAndroid.PERMISSIONS.READ_PHONE_NUMBERS, rationale ?? { title: 'App Permission', message: 'App needs access to get informations of your cellular network', buttonNeutral: 'Ask Me Later', buttonNegative: 'Cancel', buttonPositive: 'OK', }); granted = await react_native_1.PermissionsAndroid.request(react_native_1.PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE, rationale ?? { title: 'App Permission', message: 'App needs access to get informations of your cellular network', buttonNeutral: 'Ask Me Later', buttonNegative: 'Cancel', buttonPositive: 'OK', }); }else{ granted = await react_native_1.PermissionsAndroid.request(react_native_1.PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE, rationale ?? { title: 'App Permission', message: 'App needs access to get informations of your cellular network', buttonNeutral: 'Ask Me Later', buttonNegative: 'Cancel', buttonPositive: 'OK', }); } it need to request READ_PHONE_NUMBERS permission on api 33

odemolliens commented 1 year ago

Any PR is welcome ;)

officialomkarjadhav commented 1 year ago

@odemolliens can you update this to the main branch

or else can you provide an example code it will be really helpful

officialomkarjadhav commented 1 year ago

package com.reactnativesimcardsmanager;

import static android.content.Context.EUICC_SERVICE;

import android.app.Activity; import android.os.Build; import android.telephony.euicc.EuiccManager; import com.facebook.react.bridge.*; import android.app.PendingIntent; import android.content.Intent; import android.telephony.euicc.DownloadableSubscription; import android.content.IntentFilter; import android.content.Context; import android.content.BroadcastReceiver; import android.telephony.TelephonyManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.content.Intent;

import androidx.annotation.NonNull; import androidx.annotation.RequiresApi;

import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.module.annotations.ReactModule;

import java.util.List;

@ReactModule(name = SimCardsManagerModule.NAME) public class SimCardsManagerModule extends ReactContextBaseJavaModule { public static final String NAME = "SimCardsManager"; private String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription"; private ReactContext mReactContext;

@RequiresApi(api = Build.VERSION_CODES.P) private EuiccManager mgr;

public SimCardsManagerModule(ReactApplicationContext reactContext) { super(reactContext); mReactContext = reactContext; }

@RequiresApi(api = Build.VERSION_CODES.P) private void initMgr() { if (mgr == null) { mgr = (EuiccManager) mReactContext.getSystemService(EUICC_SERVICE); } }

@Override @NonNull public String getName() { return NAME; }

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1) @ReactMethod public void getSimCardsNative(Promise promise) { WritableArray simCardsList = new WritableNativeArray();

TelephonyManager telManager = (TelephonyManager) mReactContext.getSystemService(Context.TELEPHONY_SERVICE);
try {
  SubscriptionManager manager = (SubscriptionManager) mReactContext
      .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
  if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
    int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount();
    int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

    List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();

    for (SubscriptionInfo subInfo : subscriptionInfos) {
      WritableMap simCard = Arguments.createMap();

      CharSequence carrierName = subInfo.getCarrierName();
      String countryIso = subInfo.getCountryIso();
      int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
      CharSequence displayName = subInfo.getDisplayName();
      String iccId = subInfo.getIccId();
      int mcc = subInfo.getMcc();
      int mnc = subInfo.getMnc();
      String number = subInfo.getNumber();
      int simSlotIndex = subInfo.getSimSlotIndex();
      int subscriptionId = subInfo.getSubscriptionId();
      int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

      simCard.putString("carrierName", carrierName.toString());
      simCard.putString("displayName", displayName.toString());
      simCard.putString("isoCountryCode", countryIso);
      simCard.putInt("mobileCountryCode", mcc);
      simCard.putInt("mobileNetworkCode", mnc);
      simCard.putInt("isNetworkRoaming", networkRoaming);
      simCard.putInt("isDataRoaming", dataRoaming);
      simCard.putInt("simSlotIndex", simSlotIndex);
      simCard.putString("phoneNumber", number);
      simCard.putString("simSerialNumber", iccId);
      simCard.putInt("subscriptionId", subscriptionId);

      simCardsList.pushMap(simCard);
    }
  }else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
    promise.reject("0", "This functionality is not supported before Android 5.1 (22)");
}
} catch (Exception e) {
  promise.reject("1", "Something goes wrong to fetch simcards: " + e.getLocalizedMessage());
}
promise.resolve(simCardsList);

}

@RequiresApi(api = Build.VERSION_CODES.P) @ReactMethod public void isEsimSupported(Promise promise) { initMgr(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && mgr != null) { promise.resolve(mgr.isEnabled()); } else { promise.resolve(false); } return; }

@RequiresApi(api = Build.VERSION_CODES.P) private void handleResolvableError(Promise promise, Intent intent) { try { // Resolvable error, attempt to resolve it by a user action // FIXME: review logic of resolve functions int resolutionRequestCode = 3; PendingIntent callbackIntent = PendingIntent.getBroadcast(mReactContext, resolutionRequestCode, new Intent(ACTION_DOWNLOAD_SUBSCRIPTION), PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);

  mgr.startResolutionActivity(mReactContext.getCurrentActivity(), resolutionRequestCode, intent, callbackIntent);
} catch (Exception e) {
  promise.reject("3", "EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR - Can't setup eSim du to Activity error "
      + e.getLocalizedMessage());
}

}

private boolean checkCarrierPrivileges() { TelephonyManager telManager = (TelephonyManager) mReactContext.getSystemService(Context.TELEPHONY_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { return telManager.hasCarrierPrivileges(); } else { return false; } }

@RequiresApi(api = Build.VERSION_CODES.P) @ReactMethod public void setupEsim(ReadableMap config, Promise promise) { initMgr(); if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP_MR1) { promise.reject("0", "EuiccManager is not available or before Android 9 (API 28)"); }

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && mgr != null && !mgr.isEnabled()) {
  promise.reject("1", "The device doesn't support a cellular plan (EuiccManager is not available)");
  return;
}

// if (!checkCarrierPrivileges()) { // promise.reject("1", "No carrier privileges detected"); // return; // }

BroadcastReceiver receiver = new BroadcastReceiver() {

  @Override
  public void onReceive(Context context, Intent intent) {
    if (!ACTION_DOWNLOAD_SUBSCRIPTION.equals(intent.getAction())) {
      promise.reject("3",
          "Can't setup eSim du to wrong Intent:" + intent.getAction() + " instead of "
              + ACTION_DOWNLOAD_SUBSCRIPTION);
      return;
    }
    int resultCode = getResultCode();
    if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR && mgr != null) {
      handleResolvableError(promise, intent);
    } else if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
      promise.resolve(true);
    } else if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR) {
      // Embedded Subscription Error
      promise.reject("2",
          "EMBEDDED_SUBSCRIPTION_RESULT_ERROR - Can't add an Esim subscription");
    } else {
      // Unknown Error
      promise.reject("3",
          "Can't add an Esim subscription due to unknown error, resultCode is:" + String.valueOf(resultCode));
    }
  }
};

mReactContext.registerReceiver(
    receiver,
    new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
    null,
    null);

DownloadableSubscription sub = DownloadableSubscription.forActivationCode(
    /* Passed from react side */
    config.getString("confirmationCode"));

PendingIntent callbackIntent = PendingIntent.getBroadcast(
    mReactContext,
    0,
    new Intent(ACTION_DOWNLOAD_SUBSCRIPTION),
    PendingIntent.FLAG_UPDATE_CURRENT |
        PendingIntent.FLAG_MUTABLE);

mgr.downloadSubscription(sub, true, callbackIntent);

} } still facing same issue

error: method getNumber in class SubscriptionInfo cannot be applied to given types; String number = subInfo.getNumber(subInfo.getSubscriptionId(),3); ^ required: no arguments found: int,int reason: actual and formal argument lists differ in length

xiiao5777 commented 1 year ago

sorry for missing some of the coding, this i s my try and catch function `try { SubscriptionManager manager = (SubscriptionManager) mReactContext .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); if(android.os.Build.VERSION.SDK_INT >= 33){ int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount(); int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

    List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();

    for (SubscriptionInfo subInfo : subscriptionInfos) {
      WritableMap simCard = Arguments.createMap();

      CharSequence carrierName = subInfo.getCarrierName();
      String countryIso = subInfo.getCountryIso();
      int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
      CharSequence displayName = subInfo.getDisplayName();
      String iccId = subInfo.getIccId();
      int mcc = subInfo.getMcc();
      int mnc = subInfo.getMnc();
      String number = manager.getPhoneNumber(subInfo.getSubscriptionId(),3);
      int simSlotIndex = subInfo.getSimSlotIndex();
      int subscriptionId = subInfo.getSubscriptionId();
      int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

      simCard.putString("carrierName", carrierName.toString());
      simCard.putString("displayName", displayName.toString());
      simCard.putString("isoCountryCode", countryIso);
      simCard.putInt("mobileCountryCode", mcc);
      simCard.putInt("mobileNetworkCode", mnc);
      simCard.putInt("isNetworkRoaming", networkRoaming);
      simCard.putInt("isDataRoaming", dataRoaming);
      simCard.putInt("simSlotIndex", simSlotIndex);
      simCard.putString("phoneNumber", number);
      simCard.putString("simSerialNumber", iccId);
      simCard.putInt("subscriptionId", subscriptionId);

      simCardsList.pushMap(simCard);
    }
  }else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
    int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount();
    int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

    List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();

    for (SubscriptionInfo subInfo : subscriptionInfos) {
      WritableMap simCard = Arguments.createMap();

      CharSequence carrierName = subInfo.getCarrierName();
      String countryIso = subInfo.getCountryIso();
      int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
      CharSequence displayName = subInfo.getDisplayName();
      String iccId = subInfo.getIccId();
      int mcc = subInfo.getMcc();
      int mnc = subInfo.getMnc();
      String number = subInfo.getNumber();
      int simSlotIndex = subInfo.getSimSlotIndex();
      int subscriptionId = subInfo.getSubscriptionId();
      int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

      simCard.putString("carrierName", carrierName.toString());
      simCard.putString("displayName", displayName.toString());
      simCard.putString("isoCountryCode", countryIso);
      simCard.putInt("mobileCountryCode", mcc);
      simCard.putInt("mobileNetworkCode", mnc);
      simCard.putInt("isNetworkRoaming", networkRoaming);
      simCard.putInt("isDataRoaming", dataRoaming);
      simCard.putInt("simSlotIndex", simSlotIndex);
      simCard.putString("phoneNumber", number);
      simCard.putString("simSerialNumber", iccId);
      simCard.putInt("subscriptionId", subscriptionId);

      simCardsList.pushMap(simCard);
    }
  } else {
    promise.reject("0", "This functionality is not supported before Android 5.1 (22)");
  }
} catch (Exception e) {
  promise.reject("1", "Something goes wrong to fetch simcards: " + e.getLocalizedMessage());
}`
officialomkarjadhav commented 1 year ago

react-native-sim-cards-manager\android\src\main\java\com\reactnativesimcardsmanager\SimCardsManagerModule.java:82: error: cannot find symbol String number = manager.getPhoneNumber(subInfo.getSubscriptionId(),3); ^ symbol: method getPhoneNumber(int,int) location: variable manager of type SubscriptionManager

xiiao5777 commented 1 year ago

react-native-sim-cards-manager\android\src\main\java\com\reactnativesimcardsmanager\SimCardsManagerModule.java:82: error: cannot find symbol String number = manager.getPhoneNumber(subInfo.getSubscriptionId(),3); ^ symbol: method getPhoneNumber(int,int) location: variable manager of type SubscriptionManager

do you have adding this ? if(android.os.Build.VERSION.SDK_INT >= 33)

if still can't try go to the bulid.gradle and change the compile and target sdkversion to 33

officialomkarjadhav commented 1 year ago
package com.reactnativesimcardsmanager;

import static android.content.Context.EUICC_SERVICE;

import android.app.Activity;
import android.os.Build;
import android.telephony.euicc.EuiccManager;
import com.facebook.react.bridge.*;
import android.app.PendingIntent;
import android.content.Intent;
import android.telephony.euicc.DownloadableSubscription;
import android.content.IntentFilter;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.content.Intent;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;

import java.util.List;

@ReactModule(name = SimCardsManagerModule.NAME)
public class SimCardsManagerModule extends ReactContextBaseJavaModule {
  public static final String NAME = "SimCardsManager";
  private String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription";
  private ReactContext mReactContext;

  @RequiresApi(api = Build.VERSION_CODES.P)
  private EuiccManager mgr;

  public SimCardsManagerModule(ReactApplicationContext reactContext) {
    super(reactContext);
    mReactContext = reactContext;
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  private void initMgr() {
    if (mgr == null) {
      mgr = (EuiccManager) mReactContext.getSystemService(EUICC_SERVICE);
    }
  }

  @Override
  @NonNull
  public String getName() {
    return NAME;
  }

  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
  @ReactMethod
  public void getSimCardsNative(Promise promise) {
    WritableArray simCardsList = new WritableNativeArray();

    TelephonyManager telManager = (TelephonyManager) mReactContext.getSystemService(Context.TELEPHONY_SERVICE);
    try {
      SubscriptionManager manager = (SubscriptionManager) mReactContext
          .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
        int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount();
        int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

        List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();
        for (SubscriptionInfo subInfo : subscriptionInfos) {
          WritableMap simCard = Arguments.createMap();

          CharSequence carrierName = subInfo.getCarrierName();
          String countryIso = subInfo.getCountryIso();
          int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
          CharSequence displayName = subInfo.getDisplayName();
          String iccId = subInfo.getIccId();
          int mcc = subInfo.getMcc();
          int mnc = subInfo.getMnc();
          String number = manager.getPhoneNumber(subInfo.getSubscriptionId(),3);
          int simSlotIndex = subInfo.getSimSlotIndex();
          int subscriptionId = subInfo.getSubscriptionId();
          int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

          simCard.putString("carrierName", carrierName.toString());
          simCard.putString("displayName", displayName.toString());
          simCard.putString("isoCountryCode", countryIso);
          simCard.putInt("mobileCountryCode", mcc);
          simCard.putInt("mobileNetworkCode", mnc);
          simCard.putInt("isNetworkRoaming", networkRoaming);
          simCard.putInt("isDataRoaming", dataRoaming);
          simCard.putInt("simSlotIndex", simSlotIndex);
          simCard.putString("phoneNumber", number);
          simCard.putString("simSerialNumber", iccId);
          simCard.putInt("subscriptionId", subscriptionId);

          simCardsList.pushMap(simCard);
        }
      }else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
        int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount();
        int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

        List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();

        for (SubscriptionInfo subInfo : subscriptionInfos) {
          WritableMap simCard = Arguments.createMap();

          CharSequence carrierName = subInfo.getCarrierName();
          String countryIso = subInfo.getCountryIso();
          int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
          CharSequence displayName = subInfo.getDisplayName();
          String iccId = subInfo.getIccId();
          int mcc = subInfo.getMcc();
          int mnc = subInfo.getMnc();
          String number = subInfo.getNumber();
          int simSlotIndex = subInfo.getSimSlotIndex();
          int subscriptionId = subInfo.getSubscriptionId();
          int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

          simCard.putString("carrierName", carrierName.toString());
          simCard.putString("displayName", displayName.toString());
          simCard.putString("isoCountryCode", countryIso);
          simCard.putInt("mobileCountryCode", mcc);
          simCard.putInt("mobileNetworkCode", mnc);
          simCard.putInt("isNetworkRoaming", networkRoaming);
          simCard.putInt("isDataRoaming", dataRoaming);
          simCard.putInt("simSlotIndex", simSlotIndex);
          simCard.putString("phoneNumber", number);
          simCard.putString("simSerialNumber", iccId);
          simCard.putInt("subscriptionId", subscriptionId);

          simCardsList.pushMap(simCard);
        }
      } else {
        promise.reject("0", "This functionality is not supported before Android 5.1 (22)");
      }
    } catch (Exception e) {
      promise.reject("1", "Something goes wrong to fetch simcards: " + e.getLocalizedMessage());
    }
    promise.resolve(simCardsList);
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  @ReactMethod
  public void isEsimSupported(Promise promise) {
    initMgr();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && mgr != null) {
      promise.resolve(mgr.isEnabled());
    } else {
      promise.resolve(false);
    }
    return;
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  private void handleResolvableError(Promise promise, Intent intent) {
    try {
      // Resolvable error, attempt to resolve it by a user action
      // FIXME: review logic of resolve functions
      int resolutionRequestCode = 3;
      PendingIntent callbackIntent = PendingIntent.getBroadcast(mReactContext, resolutionRequestCode,
          new Intent(ACTION_DOWNLOAD_SUBSCRIPTION), PendingIntent.FLAG_UPDATE_CURRENT |
              PendingIntent.FLAG_MUTABLE);

      mgr.startResolutionActivity(mReactContext.getCurrentActivity(), resolutionRequestCode, intent, callbackIntent);
    } catch (Exception e) {
      promise.reject("3", "EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR - Can't setup eSim du to Activity error "
          + e.getLocalizedMessage());
    }
  }

  private boolean checkCarrierPrivileges() {
    TelephonyManager telManager = (TelephonyManager) mReactContext.getSystemService(Context.TELEPHONY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
      return telManager.hasCarrierPrivileges();
    } else {
      return false;
    }
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  @ReactMethod
  public void setupEsim(ReadableMap config, Promise promise) {
    initMgr();
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
      promise.reject("0", "EuiccManager is not available or before Android 9 (API 28)");
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && mgr != null && !mgr.isEnabled()) {
      promise.reject("1", "The device doesn't support a cellular plan (EuiccManager is not available)");
      return;
    }

//    if (!checkCarrierPrivileges()) {
//      promise.reject("1", "No carrier privileges detected");
//      return;
//    }

    BroadcastReceiver receiver = new BroadcastReceiver() {

      @Override
      public void onReceive(Context context, Intent intent) {
        if (!ACTION_DOWNLOAD_SUBSCRIPTION.equals(intent.getAction())) {
          promise.reject("3",
              "Can't setup eSim du to wrong Intent:" + intent.getAction() + " instead of "
                  + ACTION_DOWNLOAD_SUBSCRIPTION);
          return;
        }
        int resultCode = getResultCode();
        if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR && mgr != null) {
          handleResolvableError(promise, intent);
        } else if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
          promise.resolve(true);
        } else if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR) {
          // Embedded Subscription Error
          promise.reject("2",
              "EMBEDDED_SUBSCRIPTION_RESULT_ERROR - Can't add an Esim subscription");
        } else {
          // Unknown Error
          promise.reject("3",
              "Can't add an Esim subscription due to unknown error, resultCode is:" + String.valueOf(resultCode));
        }
      }
    };

    mReactContext.registerReceiver(
        receiver,
        new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
        null,
        null);

    DownloadableSubscription sub = DownloadableSubscription.forActivationCode(
        /* Passed from react side */
        config.getString("confirmationCode"));

    PendingIntent callbackIntent = PendingIntent.getBroadcast(
        mReactContext,
        0,
        new Intent(ACTION_DOWNLOAD_SUBSCRIPTION),
        PendingIntent.FLAG_UPDATE_CURRENT |
            PendingIntent.FLAG_MUTABLE);

    mgr.downloadSubscription(sub, true, callbackIntent);
  }
}
xiiao5777 commented 1 year ago
package com.reactnativesimcardsmanager;

import static android.content.Context.EUICC_SERVICE;

import android.app.Activity;
import android.os.Build;
import android.telephony.euicc.EuiccManager;
import com.facebook.react.bridge.*;
import android.app.PendingIntent;
import android.content.Intent;
import android.telephony.euicc.DownloadableSubscription;
import android.content.IntentFilter;
import android.content.Context;
import android.content.BroadcastReceiver;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.content.Intent;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;

import java.util.List;

@ReactModule(name = SimCardsManagerModule.NAME)
public class SimCardsManagerModule extends ReactContextBaseJavaModule {
  public static final String NAME = "SimCardsManager";
  private String ACTION_DOWNLOAD_SUBSCRIPTION = "download_subscription";
  private ReactContext mReactContext;

  @RequiresApi(api = Build.VERSION_CODES.P)
  private EuiccManager mgr;

  public SimCardsManagerModule(ReactApplicationContext reactContext) {
    super(reactContext);
    mReactContext = reactContext;
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  private void initMgr() {
    if (mgr == null) {
      mgr = (EuiccManager) mReactContext.getSystemService(EUICC_SERVICE);
    }
  }

  @Override
  @NonNull
  public String getName() {
    return NAME;
  }

  @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
  @ReactMethod
  public void getSimCardsNative(Promise promise) {
    WritableArray simCardsList = new WritableNativeArray();

    TelephonyManager telManager = (TelephonyManager) mReactContext.getSystemService(Context.TELEPHONY_SERVICE);
    try {
      SubscriptionManager manager = (SubscriptionManager) mReactContext
          .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
        int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount();
        int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

        List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();
        for (SubscriptionInfo subInfo : subscriptionInfos) {
          WritableMap simCard = Arguments.createMap();

          CharSequence carrierName = subInfo.getCarrierName();
          String countryIso = subInfo.getCountryIso();
          int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
          CharSequence displayName = subInfo.getDisplayName();
          String iccId = subInfo.getIccId();
          int mcc = subInfo.getMcc();
          int mnc = subInfo.getMnc();
          String number = manager.getPhoneNumber(subInfo.getSubscriptionId(),3);
          int simSlotIndex = subInfo.getSimSlotIndex();
          int subscriptionId = subInfo.getSubscriptionId();
          int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

          simCard.putString("carrierName", carrierName.toString());
          simCard.putString("displayName", displayName.toString());
          simCard.putString("isoCountryCode", countryIso);
          simCard.putInt("mobileCountryCode", mcc);
          simCard.putInt("mobileNetworkCode", mnc);
          simCard.putInt("isNetworkRoaming", networkRoaming);
          simCard.putInt("isDataRoaming", dataRoaming);
          simCard.putInt("simSlotIndex", simSlotIndex);
          simCard.putString("phoneNumber", number);
          simCard.putString("simSerialNumber", iccId);
          simCard.putInt("subscriptionId", subscriptionId);

          simCardsList.pushMap(simCard);
        }
      }else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
        int activeSubscriptionInfoCount = manager.getActiveSubscriptionInfoCount();
        int activeSubscriptionInfoCountMax = manager.getActiveSubscriptionInfoCountMax();

        List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();

        for (SubscriptionInfo subInfo : subscriptionInfos) {
          WritableMap simCard = Arguments.createMap();

          CharSequence carrierName = subInfo.getCarrierName();
          String countryIso = subInfo.getCountryIso();
          int dataRoaming = subInfo.getDataRoaming(); // 1 is enabled ; 0 is disabled
          CharSequence displayName = subInfo.getDisplayName();
          String iccId = subInfo.getIccId();
          int mcc = subInfo.getMcc();
          int mnc = subInfo.getMnc();
          String number = subInfo.getNumber();
          int simSlotIndex = subInfo.getSimSlotIndex();
          int subscriptionId = subInfo.getSubscriptionId();
          int networkRoaming = telManager.isNetworkRoaming() ? 1 : 0;

          simCard.putString("carrierName", carrierName.toString());
          simCard.putString("displayName", displayName.toString());
          simCard.putString("isoCountryCode", countryIso);
          simCard.putInt("mobileCountryCode", mcc);
          simCard.putInt("mobileNetworkCode", mnc);
          simCard.putInt("isNetworkRoaming", networkRoaming);
          simCard.putInt("isDataRoaming", dataRoaming);
          simCard.putInt("simSlotIndex", simSlotIndex);
          simCard.putString("phoneNumber", number);
          simCard.putString("simSerialNumber", iccId);
          simCard.putInt("subscriptionId", subscriptionId);

          simCardsList.pushMap(simCard);
        }
      } else {
        promise.reject("0", "This functionality is not supported before Android 5.1 (22)");
      }
    } catch (Exception e) {
      promise.reject("1", "Something goes wrong to fetch simcards: " + e.getLocalizedMessage());
    }
    promise.resolve(simCardsList);
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  @ReactMethod
  public void isEsimSupported(Promise promise) {
    initMgr();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && mgr != null) {
      promise.resolve(mgr.isEnabled());
    } else {
      promise.resolve(false);
    }
    return;
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  private void handleResolvableError(Promise promise, Intent intent) {
    try {
      // Resolvable error, attempt to resolve it by a user action
      // FIXME: review logic of resolve functions
      int resolutionRequestCode = 3;
      PendingIntent callbackIntent = PendingIntent.getBroadcast(mReactContext, resolutionRequestCode,
          new Intent(ACTION_DOWNLOAD_SUBSCRIPTION), PendingIntent.FLAG_UPDATE_CURRENT |
              PendingIntent.FLAG_MUTABLE);

      mgr.startResolutionActivity(mReactContext.getCurrentActivity(), resolutionRequestCode, intent, callbackIntent);
    } catch (Exception e) {
      promise.reject("3", "EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR - Can't setup eSim du to Activity error "
          + e.getLocalizedMessage());
    }
  }

  private boolean checkCarrierPrivileges() {
    TelephonyManager telManager = (TelephonyManager) mReactContext.getSystemService(Context.TELEPHONY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
      return telManager.hasCarrierPrivileges();
    } else {
      return false;
    }
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  @ReactMethod
  public void setupEsim(ReadableMap config, Promise promise) {
    initMgr();
    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
      promise.reject("0", "EuiccManager is not available or before Android 9 (API 28)");
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && mgr != null && !mgr.isEnabled()) {
      promise.reject("1", "The device doesn't support a cellular plan (EuiccManager is not available)");
      return;
    }

//    if (!checkCarrierPrivileges()) {
//      promise.reject("1", "No carrier privileges detected");
//      return;
//    }

    BroadcastReceiver receiver = new BroadcastReceiver() {

      @Override
      public void onReceive(Context context, Intent intent) {
        if (!ACTION_DOWNLOAD_SUBSCRIPTION.equals(intent.getAction())) {
          promise.reject("3",
              "Can't setup eSim du to wrong Intent:" + intent.getAction() + " instead of "
                  + ACTION_DOWNLOAD_SUBSCRIPTION);
          return;
        }
        int resultCode = getResultCode();
        if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR && mgr != null) {
          handleResolvableError(promise, intent);
        } else if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
          promise.resolve(true);
        } else if (resultCode == EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR) {
          // Embedded Subscription Error
          promise.reject("2",
              "EMBEDDED_SUBSCRIPTION_RESULT_ERROR - Can't add an Esim subscription");
        } else {
          // Unknown Error
          promise.reject("3",
              "Can't add an Esim subscription due to unknown error, resultCode is:" + String.valueOf(resultCode));
        }
      }
    };

    mReactContext.registerReceiver(
        receiver,
        new IntentFilter(ACTION_DOWNLOAD_SUBSCRIPTION),
        null,
        null);

    DownloadableSubscription sub = DownloadableSubscription.forActivationCode(
        /* Passed from react side */
        config.getString("confirmationCode"));

    PendingIntent callbackIntent = PendingIntent.getBroadcast(
        mReactContext,
        0,
        new Intent(ACTION_DOWNLOAD_SUBSCRIPTION),
        PendingIntent.FLAG_UPDATE_CURRENT |
            PendingIntent.FLAG_MUTABLE);

    mgr.downloadSubscription(sub, true, callbackIntent);
  }
}

your ' if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) ' change to ' if (android.os.Build.VERSION.SDK_INT >= 33) '

officialomkarjadhav commented 1 year ago

@xiiao5777 thank you got it!

odemolliens commented 1 year ago

https://github.com/odemolliens/react-native-sim-cards-manager/releases/tag/1.0.11