@shayrn/react-native-android-phone-number-hint
v0.1.6
Published
A simple React Native library that provides Android users with a native UI to pick their phone number using Google’s Smart Lock hint API.
Maintainers
Readme
React Native Android Phone Number Hint
A simple and lightweight React Native package that allows Android users to select their SIM-based phone number using the native Google Phone Number Hint Picker. This improves user experience by avoiding manual number entry.
🧩 What is Phone Number Hint API?
The Phone Number Hint API (part of Google Identity Services) allows apps to request the user’s phone number using a secure, native picker. It returns the number linked to the device SIM without requiring any permissions. This is useful for onboarding, OTP flows, and autofill use cases.
✨ Features
- ✅ Fetch SIM-based phone number using Android’s native dialog
- 🚫 No runtime permissions required
- ⚡ Fast & lightweight (uses Play Services)
- 📦 Built with TurboModules
- 📱 Supports Android (API 24+)
🚀 Getting Started
📦 Install the package
npm install @shayrn/react-native-android-phone-number-hint
# or
yarn add @shayrn/react-native-android-phone-number-hint
# or
npx expo install @shayrn/react-native-android-phone-number-hintImportant: This package will not work with Expo Go.
To test it, use either:
- A custom development build (via EAS)
- A bare React Native app
⚙️ Android Setup (Manual Linking)
1. Add Play Services Auth dependency
In android/app/build.gradle:
dependencies {
implementation 'com.google.android.gms:play-services-auth:21.3.0'
}In android/app/src/main/java/androidphonenumberhint/example/MainApplication.kt:
import com.androidphonenumberhint.AndroidPhoneNumberHintPackage // NOTE: Add this line
...
override fun getPackages(): List<ReactPackage> {
return PackageList(this).packages.apply {
// Manually add packages that can't be auto-linked
add(AndroidPhoneNumberHintPackage()) // NOTE: add this line
}
}2. Ensure minSdkVersion is 24 or higher
In android/build.gradle or your root gradle.properties:
minSdkVersion=24
targetSdkVersion=34
compileSdkVersion=353. For Turborepo/Monorepo
In your app’s settings.gradle:
include(":react-native-android-phone-number-hint")
project(":react-native-android-phone-number-hint").projectDir = new File(rootDir, "../../packages/react-native-android-phone-number-hint/android")And ensure pluginManagement includes:
pluginManagement {
includeBuild("../../node_modules/react-native-gradle-plugin")
}🛠️ End to End Fully Feature Usage Example
import { useEffect, useState } from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Alert,
ActivityIndicator,
} from 'react-native';
import { showPhoneNumberHint } from '@shayrn/react-native-android-phone-number-hint';
export default function App() {
const [phoneNumber, setPhoneNumber] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const [_, setHasAttempted] = useState(false);
const requestPhoneNumber = async () => {
setLoading(true);
setError('');
setHasAttempted(true);
try {
const _phoneNumber = await showPhoneNumberHint();
setPhoneNumber(_phoneNumber);
} catch (err: any) {
console.log('🚀 ~ requestPhoneNumber ~ err:', err);
// Handle different error types
if (err.code === 'USER_CANCELLED') {
setError('Phone number selection was cancelled');
} else if (
err.code === 'RESOLUTION_REQUIRED' ||
err.code === 'API_NOT_CONNECTED'
) {
setError(
'Phone number hints are disabled. Please enable in Settings → Google → Phone number sharing'
);
} else if (err.code === 'NO_ACTIVITY') {
setError('App is not ready. Please try again');
} else if (err.code === 'NETWORK_ERROR') {
setError('Network error. Please check your connection and try again');
} else if (err.code === 'SIGN_IN_REQUIRED') {
setError('Please sign in to your Google account to use this feature');
} else {
setError('Unable to retrieve phone number. Please try again');
}
} finally {
setLoading(false);
}
};
useEffect(() => {
requestPhoneNumber();
}, []);
const showErrorDetails = () => {
Alert.alert(
'Troubleshooting',
'To use phone number hints:\n\n• Go to Settings → Google → Phone number sharing and enable it\n• Ensure you have a phone number saved in your Google account\n• Make sure Google Play Services is updated\n• Try restarting the app if issues persist',
[{ text: 'OK' }]
);
};
const renderContent = () => {
if (loading) {
return (
<View style={styles.contentContainer}>
<ActivityIndicator size="large" color="#4285F4" />
<Text style={styles.loadingText}>Requesting phone number...</Text>
</View>
);
}
if (phoneNumber) {
return (
<View style={styles.contentContainer}>
<View style={styles.successIcon}>
<Text style={styles.successIconText}>✓</Text>
</View>
<Text style={styles.successTitle}>Phone Number Retrieved</Text>
<View style={styles.phoneContainer}>
<Text style={styles.phoneNumber}>{phoneNumber}</Text>
</View>
<TouchableOpacity
style={styles.secondaryButton}
onPress={requestPhoneNumber}
>
<Text style={styles.secondaryButtonText}>Try Another Number</Text>
</TouchableOpacity>
</View>
);
}
if (error) {
return (
<View style={styles.contentContainer}>
<View style={styles.errorIcon}>
<Text style={styles.errorIconText}>⚠</Text>
</View>
<Text style={styles.errorTitle}>Unable to Get Phone Number</Text>
<Text style={styles.errorMessage}>{error}</Text>
<TouchableOpacity
style={styles.primaryButton}
onPress={requestPhoneNumber}
>
<Text style={styles.primaryButtonText}>Try Again</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.helpButton}
onPress={showErrorDetails}
>
<Text style={styles.helpButtonText}>Need Help?</Text>
</TouchableOpacity>
</View>
);
}
// Initial state (shouldn't happen due to useEffect, but just in case)
return (
<View style={styles.contentContainer}>
<Text style={styles.title}>Phone Number Hint</Text>
<Text style={styles.subtitle}>Get your phone number from Google</Text>
<TouchableOpacity
style={styles.primaryButton}
onPress={requestPhoneNumber}
>
<Text style={styles.primaryButtonText}>Get Phone Number</Text>
</TouchableOpacity>
</View>
);
};
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.appTitle}>Phone Number Hint Demo</Text>
</View>
{renderContent()}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8f9fa',
},
header: {
backgroundColor: '#4285F4',
paddingTop: 50,
paddingBottom: 20,
paddingHorizontal: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
appTitle: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
textAlign: 'center',
},
contentContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 30,
},
title: {
fontSize: 28,
fontWeight: 'bold',
color: '#333',
marginBottom: 8,
textAlign: 'center',
},
subtitle: {
fontSize: 16,
color: '#666',
marginBottom: 40,
textAlign: 'center',
},
loadingText: {
fontSize: 16,
color: '#666',
marginTop: 16,
textAlign: 'center',
},
successIcon: {
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: '#4CAF50',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 24,
},
successIconText: {
fontSize: 40,
color: 'white',
fontWeight: 'bold',
},
successTitle: {
fontSize: 24,
fontWeight: 'bold',
color: '#4CAF50',
marginBottom: 20,
textAlign: 'center',
},
phoneContainer: {
backgroundColor: 'white',
paddingHorizontal: 24,
paddingVertical: 16,
borderRadius: 12,
borderWidth: 2,
borderColor: '#4CAF50',
marginBottom: 30,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
phoneNumber: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
textAlign: 'center',
},
errorIcon: {
width: 80,
height: 80,
borderRadius: 40,
backgroundColor: '#FF9800',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 24,
},
errorIconText: {
fontSize: 40,
color: 'white',
fontWeight: 'bold',
},
errorTitle: {
fontSize: 24,
fontWeight: 'bold',
color: '#FF9800',
marginBottom: 16,
textAlign: 'center',
},
errorMessage: {
fontSize: 16,
color: '#666',
textAlign: 'center',
marginBottom: 30,
lineHeight: 24,
},
primaryButton: {
backgroundColor: '#4285F4',
paddingHorizontal: 32,
paddingVertical: 16,
borderRadius: 12,
marginBottom: 16,
shadowColor: '#4285F4',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 6,
},
primaryButtonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
secondaryButton: {
backgroundColor: 'white',
paddingHorizontal: 32,
paddingVertical: 16,
borderRadius: 12,
borderWidth: 2,
borderColor: '#4285F4',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
secondaryButtonText: {
color: '#4285F4',
fontSize: 16,
fontWeight: 'bold',
textAlign: 'center',
},
helpButton: {
paddingHorizontal: 16,
paddingVertical: 12,
},
helpButtonText: {
color: '#4285F4',
fontSize: 16,
textAlign: 'center',
textDecorationLine: 'underline',
},
});
📷 Demo Example
Troubleshoot Phone Number Permissions
Follow these steps to enable phone number sharing on Android:
Open Settings
Scroll down and tap on Google
Tap on Phone number sharing

Turn on the Phone number sharing toggle

✅ Compatibility
| Platform | Support | | -------- | --------------------- | | Android | ✅ Supported (API 24+) | | iOS | ❌ Not supported |
📱 Works only on physical Android devices with SIM and Google Play Services installed.
🧠 Notes
- Uses Google Identity Services under the hood
- Requires no special permissions (like
READ_PHONE_STATE) - Phone number may return
nullif the user cancels or SIM not found
📄 License
MIT © 2025 [Mahesh Muttinti]
🙌 Contributing
Got suggestions or bug fixes? PRs and issues are welcome! 👉 GitHub Issues
💬 Questions?
Join the conversation: 👉 GitHub Discussions

