1package eu.siacs.conversations.utils;
2
3import android.content.Context;
4import android.telephony.TelephonyManager;
5
6import java.util.ArrayList;
7import java.util.List;
8import java.util.Locale;
9
10import io.michaelrocks.libphonenumber.android.NumberParseException;
11import io.michaelrocks.libphonenumber.android.PhoneNumberUtil;
12import io.michaelrocks.libphonenumber.android.Phonenumber;
13import rocks.xmpp.addr.Jid;
14
15public class PhoneNumberUtilWrapper {
16
17 private static volatile PhoneNumberUtil instance;
18
19
20 public static String getCountryForCode(String code) {
21 Locale locale = new Locale("", code);
22 return locale.getDisplayCountry();
23 }
24
25 public static String getUserCountry(Context context) {
26 try {
27 final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
28 final String simCountry = tm.getSimCountryIso();
29 if (simCountry != null && simCountry.length() == 2) { // SIM country code is available
30 return simCountry.toUpperCase(Locale.US);
31 } else if (tm.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) { // device is not 3G (would be unreliable)
32 String networkCountry = tm.getNetworkCountryIso();
33 if (networkCountry != null && networkCountry.length() == 2) { // network country code is available
34 return networkCountry.toUpperCase(Locale.US);
35 }
36 }
37 } catch (Exception e) {
38 // fallthrough
39 }
40 Locale locale = Locale.getDefault();
41 return locale.getCountry();
42 }
43
44 public static String toFormattedPhoneNumber(Context context, Jid jid) {
45 try {
46 return getInstance(context).format(toPhoneNumber(context, jid), PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL);
47 } catch (Exception e) {
48 return jid.getEscapedLocal();
49 }
50 }
51
52 public static Phonenumber.PhoneNumber toPhoneNumber(Context context, Jid jid) throws NumberParseException {
53 return getInstance(context).parse(jid.getEscapedLocal(), "de");
54 }
55
56 public static String normalize(Context context, String input) throws IllegalArgumentException, NumberParseException {
57 final Phonenumber.PhoneNumber number = getInstance(context).parse(input, getUserCountry(context));
58 if (!getInstance(context).isValidNumber(number)) {
59 throw new IllegalArgumentException("Not a valid phone number");
60 }
61 return normalize(context, number);
62 }
63
64 public static String normalize(Context context, Phonenumber.PhoneNumber phoneNumber) {
65 return getInstance(context).format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.E164);
66 }
67
68 public static PhoneNumberUtil getInstance(final Context context) {
69 PhoneNumberUtil localInstance = instance;
70 if (localInstance == null) {
71 synchronized (PhoneNumberUtilWrapper.class) {
72 localInstance = instance;
73 if (localInstance == null) {
74 instance = localInstance = PhoneNumberUtil.createInstance(context);
75 }
76
77 }
78 }
79 return localInstance;
80 }
81
82 public static List<Country> getCountries(final Context context) {
83 List<Country> countries = new ArrayList<>();
84 for (String region : getInstance(context).getSupportedRegions()) {
85 countries.add(new Country(region, getInstance(context).getCountryCodeForRegion(region)));
86 }
87 return countries;
88
89 }
90
91 public static class Country implements Comparable<Country> {
92 private final String name;
93 private final String region;
94 private final int code;
95
96 Country(String region, int code) {
97 this.name = getCountryForCode(region);
98 this.region = region;
99 this.code = code;
100 }
101
102 public String getName() {
103 return name;
104 }
105
106 public String getRegion() {
107 return region;
108 }
109
110 public String getCode() {
111 return '+' + String.valueOf(code);
112 }
113
114 @Override
115 public int compareTo(Country o) {
116 return name.compareTo(o.name);
117 }
118 }
119
120}