Skip to content

Commit

Permalink
android permissions util (#218)
Browse files Browse the repository at this point in the history
* android permissions util

* improve location permission message
  • Loading branch information
arekkubaczkowski authored Mar 30, 2022
1 parent c83d8f7 commit 688fc77
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 75 deletions.
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ useEffect(() => {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Permission Permission',
message: 'App needs access to your Location ',
title: 'Location Permission',
message: 'Stripe Terminal needs access to your location',
buttonPositive: 'Accept',
}
);
Expand All @@ -150,6 +150,32 @@ useEffect(() => {
}, []);
```

For convenience, Stripe Terminal SDK also provides an util that handles all needed Android permissions.
In order to use it follow below instrustions:

```tsx
import { requestNeededAndroidPermissions } from 'stripe-terminal-react-native';

try {
const granted = await requestNeededAndroidPermissions({
accessFineLocation: {
title: 'Location Permission',
message: 'Stripe Terminal needs access to your location',
buttonPositive: 'Accept',
},
});
if (granted) {
// init SDK
} else {
console.error(
'Location and BT services are required in order to connect to a reader.'
);
}
} catch (e) {
console.error(e);
}
```

#### Manifest

To enable compatibility the library with the latest Android 12 please make sure that you add following requirements:
Expand Down
4 changes: 2 additions & 2 deletions docs/integration-builder/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ export default function App() {
const granted = await PermissionsAndroid.request(
'android.permission.ACCESS_FINE_LOCATION',
{
title: 'Location Permission Permission',
message: 'App needs access to your Location ',
title: 'Location Permission',
message: 'Stripe Terminal needs access to your location',
buttonPositive: 'Accept',
}
);
Expand Down
30 changes: 28 additions & 2 deletions docs/set-up-your-sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ useEffect(() => {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Permission Permission',
message: 'App needs access to your Location ',
title: 'Location Permission',
message: 'Stripe Terminal needs access to your location',
buttonPositive: 'Accept',
}
);
Expand All @@ -102,6 +102,32 @@ useEffect(() => {
}, []);
```

For convenience, Stripe Terminal SDK also provides an util that handles all needed Android permissions.
In order to use it follow below instrustions:

```tsx
import { requestNeededAndroidPermissions } from 'stripe-terminal-react-native';

try {
const granted = await requestNeededAndroidPermissions({
accessFineLocation: {
title: 'Location Permission',
message: 'Stripe Terminal needs access to your location',
buttonPositive: 'Accept',
},
});
if (granted) {
// init SDK
} else {
console.error(
'Location and BT services are required in order to connect to a reader.'
);
}
} catch (e) {
console.error(e);
}
```

#### Manifest

To enable compatibility the library with the latest Android 12 please make sure that you ad following requirements:
Expand Down
95 changes: 26 additions & 69 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ import {
TransitionPresets,
} from '@react-navigation/stack';
import HomeScreen from './screens/HomeScreen';
import {
Alert,
PermissionsAndroid,
Platform,
StatusBar,
StyleSheet,
} from 'react-native';
import { Alert, Platform, StatusBar, StyleSheet } from 'react-native';
import { colors } from './colors';
import { LogContext, Log, Event } from './components/LogContext';
import DiscoverReadersScreen from './screens/DiscoverReadersScreen';
Expand All @@ -27,11 +21,11 @@ import ReadReusableCardScreen from './screens/ReadReusableCardScreen';
import LogListScreen from './screens/LogListScreen';
import LogScreen from './screens/LogScreen';
import RegisterInternetReaderScreen from './screens/RegisterInternetReaderScreen';
import { isAndroid12orHigher } from './utils';
import {
Reader,
Location,
useStripeTerminal,
requestNeededAndroidPermissions,
} from 'stripe-terminal-react-native';
import { LogBox } from 'react-native';

Expand Down Expand Up @@ -104,81 +98,44 @@ export default function App() {
const clearLogs = useCallback(() => setlogs([]), []);
const { initialize: initStripe } = useStripeTerminal();

useEffect(() => {
const handlePermissionsSuccess = async () => {
const { error } = await initStripe({
logLevel: 'verbose',
});
if (error) {
Alert.alert('StripeTerminal init failed', error.message);
} else {
console.log('StripeTerminal has been initialized properly');
}
};
const handlePermissionsSuccess = useCallback(async () => {
const { error } = await initStripe({
logLevel: 'verbose',
});
if (error) {
Alert.alert('StripeTerminal init failed', error.message);
} else {
console.log('StripeTerminal has been initialized properly');
}
}, [initStripe]);

useEffect(() => {
async function handlePermissions() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
const granted = await requestNeededAndroidPermissions({
accessFineLocation: {
title: 'Location Permission',
message: 'App needs access to your Location ',
message: 'Stripe Terminal needs access to your location',
buttonPositive: 'Accept',
}
);

if (hasGrantedPermission(granted)) {
if (isAndroid12orHigher()) {
const grantedBT = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
{
title: 'BT Permission',
message: 'App needs access to Bluetooth ',
buttonPositive: 'Accept',
}
);

const grantedBTScan = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
{
title: 'BT Permission',
message: 'App needs access to Bluetooth ',
buttonPositive: 'Accept',
}
);
if (
hasGrantedPermission(grantedBT) &&
hasGrantedPermission(grantedBTScan)
) {
handlePermissionsSuccess();
return;
} else {
handlePermissionsError();
return;
}
}
},
});
if (granted) {
handlePermissionsSuccess();
} else {
handlePermissionsError();
console.error(
'Location and BT services are required in order to connect to a reader.'
);
}
} catch {}
} catch (e) {
console.error(e);
}
}
if (Platform.OS === 'android') {
handlePermissions();
} else {
handlePermissionsSuccess();
}
}, [initStripe]);

const handlePermissionsError = () => {
console.error(
'Location and BT services are required in order to connect to a reader.'
);
};

const hasGrantedPermission = (status: string) => {
return status === PermissionsAndroid.RESULTS.GRANTED;
};
}, [handlePermissionsSuccess]);

const addLogs = useCallback((newLog: Log) => {
const updateLog = (log: Log) =>
Expand Down
3 changes: 3 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ export {
withStripeTerminal,
WithStripeTerminalProps,
} from './components/withStripeTerminal';

// utils
export { requestNeededAndroidPermissions } from './utils/androidPermissionsUtils';
59 changes: 59 additions & 0 deletions src/utils/androidPermissionsUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { PermissionsAndroid, Platform } from 'react-native';

const defaultFineLocationParams = {
title: 'Location Permission',
message: 'Stripe Terminal needs access to your location',
buttonPositive: 'Accept',
};

type PermissionsProps = {
accessFineLocation?: {
title: string;
message: string;
buttonPositive: string;
};
};

const isAndroid12orHigher = () =>
Platform.OS === 'android' && Platform.Version >= 31;

export async function requestNeededAndroidPermissions({
accessFineLocation = defaultFineLocationParams,
}: PermissionsProps | undefined = {}): Promise<boolean> {
let hasGrantedLocationPermissions = false;
let hasGrantedBluetoothPermissions = false;

const grantedFineLocation = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
accessFineLocation || defaultFineLocationParams
);

if (hasGrantedPermission(grantedFineLocation)) {
hasGrantedLocationPermissions = true;

if (isAndroid12orHigher()) {
const grantedBT = await PermissionsAndroid.request(
// BLUETOOTH_CONNECT doesn't support customization
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT
);

const grantedBTScan = await PermissionsAndroid.request(
// BLUETOOTH_SCAN doesn't support customization
PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN
);
if (
hasGrantedPermission(grantedBT) &&
hasGrantedPermission(grantedBTScan)
) {
hasGrantedBluetoothPermissions = true;
}
} else {
hasGrantedBluetoothPermissions = true;
}
}
return hasGrantedBluetoothPermissions && hasGrantedLocationPermissions;
}

const hasGrantedPermission = (status: string) => {
return status === PermissionsAndroid.RESULTS.GRANTED;
};

0 comments on commit 688fc77

Please sign in to comment.