1package eu.siacs.conversations.utils;
2
3import android.content.Context;
4import android.telephony.TelephonyManager;
5import android.util.Log;
6
7import androidx.core.content.ContextCompat;
8
9import org.osmdroid.util.GeoPoint;
10
11import java.io.BufferedReader;
12import java.io.IOException;
13import java.io.InputStreamReader;
14import java.util.Locale;
15
16import eu.siacs.conversations.Config;
17import eu.siacs.conversations.R;
18
19public class LocationProvider {
20
21 public static final GeoPoint FALLBACK = new GeoPoint(0.0, 0.0);
22
23 public static String getUserCountry(final Context context) {
24 return getUserCountry(context, false);
25 }
26
27 public static String getUserCountry(final Context context, boolean preferNetwork) {
28 try {
29 final TelephonyManager tm = ContextCompat.getSystemService(context, TelephonyManager.class);
30 if (tm == null) {
31 return getUserCountryFallback();
32 }
33 Log.d(Config.LOGTAG, "SIM Operator: " + tm.getSimOperator());
34 final String simCountry = tm.getSimOperator().equals("20801") ? "us" : tm.getSimCountryIso();
35 final String networkCountry = tm.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA ? null : tm.getNetworkCountryIso(); // if device is not 3G would be unreliable
36 if (preferNetwork && networkCountry != null && networkCountry.length() == 2) {
37 return networkCountry.toUpperCase(Locale.US);
38 }
39
40 if (simCountry != null && simCountry.length() == 2) { // SIM country code is available
41 return simCountry.toUpperCase(Locale.US);
42 } else if (networkCountry != null && networkCountry.length() == 2) { // network country code is available
43 return networkCountry.toUpperCase(Locale.US);
44 }
45 return getUserCountryFallback();
46 } catch (final Exception e) {
47 return getUserCountryFallback();
48 }
49 }
50
51 private static String getUserCountryFallback() {
52 final Locale locale = Locale.getDefault();
53 return locale.getCountry();
54 }
55
56 public static GeoPoint getGeoPoint(final Context context) {
57 return getGeoPoint(context, getUserCountry(context));
58 }
59
60
61 public static synchronized GeoPoint getGeoPoint(final Context context, final String country) {
62 try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(R.raw.countries)))) {
63 String line;
64 while ((line = reader.readLine()) != null) {
65 final String[] parts = line.split("\\s+", 4);
66 if (parts.length == 4) {
67 if (country.equalsIgnoreCase(parts[0])) {
68 try {
69 return new GeoPoint(Double.parseDouble(parts[1]), Double.parseDouble(parts[2]));
70 } catch (final NumberFormatException e) {
71 return FALLBACK;
72 }
73 }
74 }
75 }
76 } catch (final IOException e) {
77 Log.d(Config.LOGTAG, "unable to parse country->geo map", e);
78 }
79 return FALLBACK;
80 }
81
82}