Skip to content

Commit

Permalink
Merge pull request #11 from odemolliens/feat/request-permission-on-ge…
Browse files Browse the repository at this point in the history
…t-sim-cards

feat: Added a permission requestion for getSimCards
  • Loading branch information
FrLallemandArhs authored Apr 26, 2022
2 parents 9769098 + cdc8229 commit 60ade5d
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 51 deletions.
133 changes: 86 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# react-native-sim-cards-manager

A new library that merge multiple sim cards libraries into a single one:

- https://github.com/markneh/react-native-esim
- https://github.com/pocesar/react-native-sim-data

Bridges have been adapted, so you will have to adapt your code if you come from one of those libraries.

Bugs fixed and some improvements have been made.


## Installation

```sh
Expand All @@ -21,9 +21,10 @@ npm install react-native-sim-cards-manager

**Minimum API Level is 22**

*TelephonyManager* require Android permission **READ_PHONE_STATE**:
_TelephonyManager_ require Android permission **READ_PHONE_STATE**:

Add in your Android Manifest:

```xml
<uses-permission
android:name="android.permission.READ_PHONE_STATE" />
Expand All @@ -35,103 +36,141 @@ Add in your Android Manifest:

**Minimum API Level is 12 for eSIM methods**

Note: At the moment *(iOS 14.2)* there might a bug in iOS SDK which returns uknown result before eSIM setup completion. More about it [here](https://developer.apple.com/forums/thread/662001)
Note: At the moment _(iOS 14.2)_ there might a bug in iOS SDK which returns uknown result before eSIM setup completion. More about it [here](https://developer.apple.com/forums/thread/662001)

## Usage

### Get sim cards

The list can be empty (no simcards detected) or one/many element(s)
Two methods are availabe :

#### Method getSimCards

This handle the permission request and takes an optionnal _rationale_ Parameter

```ts
import { SimManager } from "react-native-sim-cards-manager";
import { SimManager } from 'react-native-sim-cards-manager';

SimCardsManagerModule.getSimCards({
title: 'App Permission',
message: 'Custom message',
buttonNeutral: 'Not now',
buttonNegative: 'Not OK',
buttonPositive: 'OK',
})
.then((array: Array<any>) => {
//
})
.catch((error) => {
//
});
```

SimCardsManagerModule.getSimCards().then((array: Array<any>)=>{
#### Method getSimCardsNative

This is the method used internally by getSimCards. It does not handle the permission request and leaves the user of this lib.

```ts
import { SimManager } from 'react-native-sim-cards-manager';

SimCardsManagerModule.getSimCardsNative()
.then((array: Array<any>) => {
//
}).catch((error)=>{
})
.catch((error) => {
//
})
});
```

Available set of data per platform:

| Platform | iOS | Android |
|------------------- |----- |--------- |
| carrierName | | |
| displayName | | |
| isoCountryCode | | |
| mobileCountryCode | | |
| mobileNetworkCode | | |
| isNetworkRoaming | | |
| isDataRoaming | | |
| simSlotIndex | | |
| phoneNumber | | |
| simSerialNumber | | |
| subscriptionId | | |
| allowsVOIP | | |
| Platform | iOS | Android |
| ----------------- | --- | ------- |
| carrierName | | |
| displayName | | |
| isoCountryCode | | |
| mobileCountryCode | | |
| mobileNetworkCode | | |
| isNetworkRoaming | | |
| isDataRoaming | | |
| simSlotIndex | | |
| phoneNumber | | |
| simSerialNumber | | |
| subscriptionId | | |
| allowsVOIP | | |

### Esim is supported

Return true/false is the device support eSim feature

```ts
import { SimManager } from "react-native-sim-cards-manager";
import { SimManager } from 'react-native-sim-cards-manager';

SimCardsManagerModule.isEsimSupported().then((isSupported: boolean)=>{
SimCardsManagerModule.isEsimSupported()
.then((isSupported: boolean) => {
//
}).catch((error)=>{
})
.catch((error) => {
//
})
});
```

### Setup eSim with an activation code

Entry parameters for the bridge:

| Entry parameters | Mandatory | Description |
|------------------ |----------- |----------------------------------------------------------------------------------------------------------------- |
| address | N/A | The address of the carrier network’s eSIM server |
| confirmationCode | N/A | The provisioning request’s confirmation code, provided by the network operator when initiating an eSIM download |
| iccid | N/A | The provisioning request’s eUICC identifier |
| address | N/A | The provisioning request’s Integrated Circuit Card Identifier |
| matchingId | N/A | The provisioning request’s matching identifier |
| oid | N/A | The provisioning request’s Object Identifier |
| Entry parameters | Mandatory | Description |
| ---------------- | --------- | --------------------------------------------------------------------------------------------------------------- |
| address | N/A | The address of the carrier network’s eSIM server |
| confirmationCode | N/A | The provisioning request’s confirmation code, provided by the network operator when initiating an eSIM download |
| iccid | N/A | The provisioning request’s eUICC identifier |
| address | N/A | The provisioning request’s Integrated Circuit Card Identifier |
| matchingId | N/A | The provisioning request’s matching identifier |
| oid | N/A | The provisioning request’s Object Identifier |

Error code that can be returned by the bridge:

| Error code | Description |
|-------------- |----------------------------------------------------------------------------------- |
| 0 | Feature not available for that OS / device |
| 1 | The device doesn't support a cellular plan |
| 2 | The OS failed to add the new plan |
| 3 **(iOS)** | The OS has returned an unknow error |
| 3 **(Android)** | The OS has returned an error **or** something goes wrong with the Intent/Activity |
| Error code | Description |
| --------------- | --------------------------------------------------------------------------------- |
| 0 | Feature not available for that OS / device |
| 1 | The device doesn't support a cellular plan |
| 2 | The OS failed to add the new plan |
| 3 **(iOS)** | The OS has returned an unknow error |
| 3 **(Android)** | The OS has returned an error **or** something goes wrong with the Intent/Activity |

```ts
import { SimManager } from "react-native-sim-cards-manager";
import { SimManager } from 'react-native-sim-cards-manager';

SimCardsManagerModule.setupEsim({
confirmationCode, address: '',
}).then((isPlanAdded: boolean)=>{
//
}).catch((error)=>{
//
confirmationCode,
address: '',
})
.then((isPlanAdded: boolean) => {
//
})
.catch((error) => {
//
});
```


## Changelog

### 1.0.2

- Remove 'deviceID' on Android because it require high privilege
- Adding permission management on Android (READ_PHONE_STATE)

### 1.0.1

- Android bug fixes

### 1.0.0

- First stable release

### 0.9.9

- iOS implementation
- Android implementation
- RN implementation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public String getName() {

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

TelephonyManager telManager = (TelephonyManager) mReactContext.getSystemService(Context.TELEPHONY_SERVICE);
Expand Down
2 changes: 1 addition & 1 deletion ios/SimCardsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ @implementation SimCardsManager

RCT_EXPORT_MODULE()

RCT_EXPORT_METHOD(getSimCards:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
RCT_EXPORT_METHOD(getSimCardsNative:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {

NSMutableArray *simCardsList = [[NSMutableArray alloc]init];

Expand Down
36 changes: 34 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NativeModules, Platform } from 'react-native';
import { NativeModules, PermissionsAndroid, Platform, Rationale } from 'react-native';

const LINKING_ERROR =
`The package 'react-native-sim-cards-manager' doesn't seem to be linked. Make sure: \n\n` +
Expand All @@ -17,6 +17,33 @@ const SimCardsManagerModule = NativeModules.SimCardsManager
}
);

export async function requestCellularNetworkPermission(then: () => any, rationale?: Rationale) {
if (Platform.OS == 'android') {
const granted = await PermissionsAndroid.request(
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',
}
);
console.log(granted);
console.log(PermissionsAndroid.RESULTS);
if (
granted === PermissionsAndroid.RESULTS.GRANTED ||
granted === PermissionsAndroid.RESULTS.NEVER_ASK_AGAIN
) {
return then();
} else {
return Promise.reject({ code: '3', message: 'Permission not granted' });
}
} else {
return then();
}
}

export type EsimConfig = {
address: string;
confirmationCode?: string;
Expand All @@ -27,9 +54,14 @@ export type EsimConfig = {
};

type SimManager = {
getSimCards(): Promise<Array<any>>;
getSimCards(rationale?: Rationale): Promise<Array<any>>; // Permission request handled by react-native-sim-cards-manager
getSimCardsNative(): Promise<Array<any>>; // Permission request left to be handled by the user
setupEsim(config: EsimConfig): Promise<boolean | never>;
isEsimSupported(): Promise<boolean | never>;
};

SimCardsManagerModule.getSimCards = async () => {
return await requestCellularNetworkPermission(NativeModules.SimCardsManager.getSimCardsNative);
};

export default SimCardsManagerModule as SimManager;

0 comments on commit 60ade5d

Please sign in to comment.