firebase OTP не получает международные номера - PullRequest
0 голосов
/ 09 ноября 2018

Я из Индии, работаю над приложением для Android. В этом случае индийские мобильные номера успешно получают OTP из пожарной базы, где международные мобильные номера, которые используются в физических устройствах в их соответствующих странах, не получают OTP. Я пытался использовать международные фиктивные номера с этого портала онлайн-sms OTP-портал получает OTP через Интернет, кроме номеров США, но OTP не получает международные номера в своих физических устройствах. Я выполнил шаги из документации Firebase, но это мне не помогло.

Заранее спасибо

activity_number.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.pmkmap.Activities.NumberActivity">


    <LinearLayout
        android:id="@+id/number_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:src="@drawable/pmk_background_pic" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"
            android:text="PMK"
            android:textColor="@color/blue"
            android:textSize="15sp"
            android:textStyle="bold"
            android:visibility="gone" />


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <com.hbb20.CountryCodePicker
                android:id="@+id/ccp"
                android:layout_width="130dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                android:layout_marginTop="40dp"               />

            <EditText
                android:id="@+id/enter_number"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="20dp"
                android:layout_marginTop="40dp"
                android:digits="0123456789"
                android:hint="@string/enter_your_no"
                android:inputType="phone"
                android:textSize="15dp" />
        </LinearLayout>

        <Button
            android:id="@+id/generate_otp"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:background="@drawable/button_background"
            android:text="@string/genrate_otp"
            android:textColor="@color/white" />


        <EditText
            android:id="@+id/enter_otp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="60dp"
            android:layout_marginRight="30dp"
            android:layout_marginTop="20dp"
            android:hint="@string/enterur_otp"
            android:inputType="numberPassword"
            android:maxLength="6"
            android:visibility="gone" />

        <Button
            android:id="@+id/verify"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:background="@drawable/button_background"
            android:text="@string/verify"
            android:textColor="@color/white"
            android:visibility="gone" />

        <TextView
            android:id="@+id/resend_otp"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="5dp"
            android:gravity="center"
            android:text="@string/resend_otp"
            android:textColor="@color/blue"
            android:visibility="gone" />

    </LinearLayout>

</LinearLayout>

NumberActivity.java

package com.pmkmap.Activities;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseException;
import com.google.firebase.FirebaseTooManyRequestsException;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.perf.metrics.AddTrace;
import com.hbb20.CountryCodePicker;
import com.pmkmap.Modals.UserTokenModal;
import com.pmkmap.R;
import com.pmkmap.Utility;

import java.util.Map;
import java.util.concurrent.TimeUnit;

public class NumberActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "PhoneAuthActivity";
    EditText enterNoEdt, enterOtpEdt;
    Button generateOpt, verifyOtp;
    TextView resendOtp;
    String mVerificationId, countryCode, countryName, mobileNo;
    CountryCodePicker countryCodePicker;
    private FirebaseAuth mAuth;
    private PhoneAuthProvider.ForceResendingToken mResendToken;
    private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallBacks;
    private FirebaseFirestore firestoreDB;
    private Tracker mTracker;

    public static void hideSoftKeyboard(Activity activity) {
        try {
            InputMethodManager inputMethodManager =
                    (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @AddTrace(name = "NumberInput_trace", enabled = true)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_number);
        getSupportActionBar().hide();
        findID();
        clickListener();
        AnalyticsApplication application = (AnalyticsApplication) getApplication();
        mTracker = application.getDefaultTracker();
        mAuth = FirebaseAuth.getInstance();
        firestoreDB = FirebaseFirestore.getInstance();
        mCallBacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
                Log.e(TAG, "onVerificationCompleted:" + phoneAuthCredential);
                if (mVerificationId == null) {
                    signInWithPhoneAuthCredential(phoneAuthCredential);
                }
            }

            @Override
            public void onVerificationFailed(FirebaseException e) {
                Log.e(TAG, "onVerificationFailed", e);
                Utility.hideProgressDialog();
                if (e instanceof FirebaseAuthInvalidCredentialsException) {
                    enterNoEdt.setError("தவறான அலைபேசி எண் !");
                } else if (e instanceof FirebaseTooManyRequestsException) {
                    Toast.makeText(NumberActivity.this, "Quota exceeded.", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                Log.d(TAG, "onCodeSent:" + verificationId);
                Toast.makeText(NumberActivity.this, "உங்கள் அலைபேசி எண்ணிற்கு OTP வெற்றிகரமாக அனுப்பப்பட்டது", Toast.LENGTH_SHORT).show();
                mVerificationId = verificationId;
                mResendToken = forceResendingToken;
                Utility.hideProgressDialog();
                generateOpt.setVisibility(View.GONE);
                enterOtpEdt.setVisibility(View.VISIBLE);
                verifyOtp.setVisibility(View.VISIBLE);
                resendOtp.setVisibility(View.VISIBLE);
            }
        };

    }

    @Override
    protected void onResume() {
        super.onResume();
        mTracker.setScreenName("Image~" + "Mobile_Number_Input");
        mTracker.send(new HitBuilders.ScreenViewBuilder().build());
    }

    public void findID() {
        enterNoEdt = findViewById(R.id.enter_number);
        generateOpt = findViewById(R.id.generate_otp);
        verifyOtp = findViewById(R.id.verify);
        enterOtpEdt = findViewById(R.id.enter_otp);
        resendOtp = findViewById(R.id.resend_otp);

        countryCodePicker = findViewById(R.id.ccp);
    }

    private void signInWithPhoneAuthCredential(final PhoneAuthCredential credential) {
        mAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    if (countryCode.equalsIgnoreCase("+91")) {
                        getUsers();
                    } else {
                        getIntUsers();
                    }

                } else {
                    Log.w(TAG, "signInWithCredential:failure", task.getException());
                    if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                        Utility.hideProgressDialog();
                        Toast.makeText(NumberActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                        enterOtpEdt.setError("Invalid code");
                    }
                }
            }
        });
    }

    private void startPhoneNumberVerification(String phoneNumber) {
        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                phoneNumber,       
                30,                 
                TimeUnit.SECONDS,  
                this,               
                mCallBacks);
    }

    private void verifyPhoneNumberWithCode(String verificationId, String code) {
        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
        signInWithPhoneAuthCredential(credential);
    }

    private void resendVerificationCode(String phoneNumber, PhoneAuthProvider.ForceResendingToken token) {
        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                phoneNumber,        
                30,                 
                TimeUnit.SECONDS,   
                this,               
                mCallBacks,         
                token);            
    }

    public void clickListener() {
        generateOpt.setOnClickListener(this);
        verifyOtp.setOnClickListener(this);
        resendOtp.setOnClickListener(this);
    }

    @AddTrace(name = "Number_trace", enabled = true)
    @Override
    public void onClick(View v) {
        if (v == generateOpt) {
            try {
                if (Utility.isNetworkAvailable(NumberActivity.this)) {
                    if (enterNoEdt.getText().toString().equalsIgnoreCase("")) {
                        Toast.makeText(this, "தாங்கள் அலைபேசி எண்ணை பதிவு செய்யவும்", Toast.LENGTH_SHORT).show();
                    } else {
                        hideSoftKeyboard(NumberActivity.this);
                        Utility.showProgressDialog(NumberActivity.this);
                        mobileNo = enterNoEdt.getText().toString();
                        getCountryCode();
                        startPhoneNumberVerification(countryCode + mobileNo);
                    }
                } else {
                    Toast.makeText(this, "தாங்கள் இணையதள இணைப்பை சரி பார்க்கவும்", Toast.LENGTH_SHORT).show();
                    Utility.hideProgressDialog();
                }
            } catch (Exception e) {
                e.printStackTrace();
                Utility.hideProgressDialog();
            }
        }
        if (v == verifyOtp) {
            try {
                if (Utility.isNetworkAvailable(NumberActivity.this)) {

                    if (enterOtpEdt.getText().toString().equalsIgnoreCase("")) {
                        Toast.makeText(this, "OTP ஐ பதிவு செய்க", Toast.LENGTH_SHORT).show();
                    } else {
                        hideSoftKeyboard(NumberActivity.this);
                        Utility.showProgressDialog(NumberActivity.this);
                        verifyPhoneNumberWithCode(mVerificationId, enterOtpEdt.getText().toString());
                    }

                } else {
                    Toast.makeText(this, "தாங்கள் இணையதள இணைப்பை சரி பார்க்கவும்", Toast.LENGTH_SHORT).show();
                    Utility.hideProgressDialog();
                }
            } catch (Exception e) {
                e.printStackTrace();
                Utility.hideProgressDialog();
            }
        }
        if (v == resendOtp) {
            try {
                if (Utility.isNetworkAvailable(NumberActivity.this)) {
                    if (enterNoEdt.getText().toString().equalsIgnoreCase("")) {
                        Toast.makeText(this, "தாங்கள் அலைபேசி எண்ணை பதிவு செய்யவும்", Toast.LENGTH_SHORT).show();
                    } else {
                        hideSoftKeyboard(NumberActivity.this);
                        Utility.showProgressDialog(NumberActivity.this);
                        mobileNo = enterNoEdt.getText().toString();
                        getCountryCode();
                        resendVerificationCode(countryCode + mobileNo, mResendToken);
                    }
                } else {
                    Toast.makeText(this, "தாங்கள் இணையதள இணைப்பை சரி பார்க்கவும்", Toast.LENGTH_SHORT).show();
                    Utility.hideProgressDialog();
                }
            } catch (Exception e) {
                e.printStackTrace();
                Utility.hideProgressDialog();
            }
        }
    }

    private void getUsers() {
        firestoreDB.collection("users").document(countryCode + mobileNo).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                try {
                    if (task.isSuccessful()) {
                        sendToken();
                        DocumentSnapshot document = task.getResult();
                        if (document.exists()) {
                            Map<String, Object> array = document.getData();
                            if (array.get("blocked").toString().equalsIgnoreCase("no")) {
                                Log.e(">>>", array.toString());
                                checkLoginStatus();
                                getMyAccountDetailPref();
                                Log.e(">>>>", document.getId());
                                startActivity(new Intent(NumberActivity.this, HomeActivity.class));
                                finish();
                            } else {
                                AlertDialog.Builder builder = new AlertDialog.Builder(NumberActivity.this);
                                builder.setMessage("Your account is blocked by admin.")
                                        .setCancelable(false)
                                        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                NumberActivity.this.finish();
                                            }
                                        });
                                AlertDialog alert = builder.create();
                                alert.show();
                            }

                        } else {
                            gotoNextActivity();
                        }
                    } else {
                        try {
                            sendToken();
                            gotoNextActivity();
                            Log.d(TAG, "Error getting documents: ", task.getException());
                        } catch (Exception e) {
                            Toast.makeText(NumberActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                            e.printStackTrace();
                        }
                    }
                } catch (Exception e) {
                    Toast.makeText(NumberActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                    e.printStackTrace();
                }
            }

        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.e(">>>", e.toString());
            }
        });
    }

    private void getIntUsers() {
        firestoreDB.collection("int_users").document(countryCode + mobileNo).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                try {
                    if (task.isSuccessful()) {
                        sendToken();
                        DocumentSnapshot document = task.getResult();
                        if (document.exists()) {
                            Map<String, Object> array = document.getData();
                            if (array.get("blocked").toString().equalsIgnoreCase("no")) {
                                Log.e(">>>", array.toString());
                                checkLoginStatus();
                                getMyAccountDetailPref();
                                Log.e(">>>>", document.getId());
                                startActivity(new Intent(NumberActivity.this, HomeActivity.class));
                                finish();
                            } else {
                                AlertDialog.Builder builder = new AlertDialog.Builder(NumberActivity.this);
                                builder.setMessage("Your account is blocked by admin.")
                                        .setCancelable(false)
                                        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                NumberActivity.this.finish();
                                            }
                                        });
                                AlertDialog alert = builder.create();
                                alert.show();
                            }

                        } else {
                            gotoNextActivity();
                        }
                    } else {
                        try {
                            sendToken();
                            gotoNextActivity();
                            Log.d(TAG, "Error getting documents: ", task.getException());
                        } catch (Exception e) {
                            Toast.makeText(NumberActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                            e.printStackTrace();
                        }
                    }
                } catch (Exception e) {
                    Toast.makeText(NumberActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                    e.printStackTrace();
                }
            }

        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.e(">>>", e.toString());
            }
        });
    }

    public void gotoNextActivity() {
        if (countryCode.equalsIgnoreCase("+91")) {
            getMyAccountDetailPref();
        } else {
            getMyIntAccountDetailPref();
        }

        if (countryCode.equalsIgnoreCase("+91")) {
            startActivity(new Intent(NumberActivity.this, SaveInformationActivity.class).putExtra("mobile_no", countryCode + mobileNo));
            finish();
        } else {
            startActivity(new Intent(NumberActivity.this, IntSaveInformationActivity.class).putExtra("mobile_no", countryCode + mobileNo)
                    .putExtra("countryName", countryName));
            finish();
        }

    }

    public void checkLoginStatus() {
        SharedPreferences settings = getSharedPreferences(SaveInformationActivity.PREFS_NAME, 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putBoolean("hasLoggedIn", true);
        editor.commit();
    }

    public void getMyAccountDetailPref() {
        SharedPreferences.Editor editor = getSharedPreferences("mobile_no", MODE_PRIVATE).edit();
        editor.putString("user_mobile", countryCode + mobileNo);
        editor.apply();
    }

    public void getMyIntAccountDetailPref() {
        SharedPreferences.Editor editor = getSharedPreferences("mobile_no", MODE_PRIVATE).edit();
        editor.putString("user_mobile", countryCode + mobileNo);
        editor.apply();
    }

    public void getCountryCode() {
        countryCode = countryCodePicker.getFullNumberWithPlus();
        countryName = countryCodePicker.getSelectedCountryName();
    }

    public void sendToken() {
        try {
            String token = FirebaseInstanceId.getInstance().getToken();
            SharedPreferences.Editor editor = getSharedPreferences("user_token", MODE_PRIVATE).edit();
            editor.putString("token", token);
            editor.apply();
            UserTokenModal userTokenModal = new UserTokenModal(token);
            firestoreDB.collection("userToken").document(countryCode + mobileNo).set(userTokenModal).addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void documentReference) {
                    try {
                        Log.e(">>>>", "token sent succefully");

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.w(">>>", "Error adding event document", e);
                    Toast.makeText(NumberActivity.this,
                            e.getMessage(),
                            Toast.LENGTH_SHORT).show();
                    Utility.hideProgressDialog();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1 Ответ

0 голосов
/ 09 ноября 2018

Firebase Authentication поддерживает проверку телефонных номеров по всему миру. Вот список стран, поддерживаемых Firebase:

AD  Andorra
AE  United Arab Emirates
AF  Afghanistan
AG  Antigua and Barbuda
AL  Albania
AM  Armenia
AO  Angola
AR  Argentina
AS  American Samoa
AT  Austria
AU  Australia
AW  Aruba
BA  Bosnia and Herzegovina
BB  Barbados
BD  Bangladesh
BE  Belgium
BF  Burkina Faso
BG  Bulgaria
BJ  Benin
BM  Bermuda
BN  Brunei Darussalam
BO  Bolivia
BR  Brazil
BS  Bahamas
BT  Bhutan
BW  Botswana
BY  Belarus
BZ  Belize
CA  Canada
CD  Congo, (Kinshasa)
CF  Central African Republic
CG  Congo (Brazzaville)
CH  Switzerland
CI  Côte d'Ivoire
CK  Cook Islands
CL  Chile
CM  Cameroon
CO  Colombia
CR  Costa Rica
CV  Cape Verde
CW  Curaçao
CY  Cyprus
CZ  Czech Republic
DE  Germany
DJ  Djibouti
DK  Denmark
DM  Dominica
DO  Dominican Republic
DZ  Algeria
EC  Ecuador
EG  Egypt
ES  Spain
ET  Ethiopia
FI  Finland
FJ  Fiji
FK  Falkland Islands (Malvinas)
FM  Micronesia, Federated States of
FO  Faroe Islands
FR  France
GA  Gabon
GB  United Kingdom
GD  Grenada
GE  Georgia
GF  French Guiana
GG  Guernsey
GH  Ghana
GI  Gibraltar
GL  Greenland
GM  Gambia
GP  Guadeloupe
GQ  Equatorial Guinea
GR  Greece
GT  Guatemala
GY  Guyana
HK  Hong Kong, SAR China
HN  Honduras
HR  Croatia
HT  Haiti
HU  Hungary
ID  Indonesia
IE  Ireland
IL  Israel
IM  Isle of Man
IN  India
IQ  Iraq
IT  Italy
JE  Jersey
JM  Jamaica
JO  Jordan
JP  Japan
KE  Kenya
KG  Kyrgyzstan
KH  Cambodia
KM  Comoros
KN  Saint Kitts and Nevis
KR  Korea (South)
KW  Kuwait
KY  Cayman Islands
KZ  Kazakhstan
LA  Lao PDR
LB  Lebanon
LC  Saint Lucia
LI  Liechtenstein
LK  Sri Lanka
LS  Lesotho
LT  Lithuania
LU  Luxembourg
LV  Latvia
LY  Libya
MA  Morocco
MD  Moldova
ME  Montenegro
MF  Saint-Martin (French part)
MG  Madagascar
MK  Macedonia, Republic of
MM  Myanmar
MN  Mongolia
MO  Macao, SAR China
MS  Montserrat
MT  Malta
MU  Mauritius
MW  Malawi
MX  Mexico
MY  Malaysia
MZ  Mozambique
NA  Namibia
NC  New Caledonia
NE  Niger
NF  Norfolk Island
NG  Nigeria
NI  Nicaragua
NL  Netherlands
NO  Norway
NP  Nepal
NZ  New Zealand
OM  Oman
PA  Panama
PE  Peru
PG  Papua New Guinea
PH  Philippines
PK  Pakistan
PL  Poland
PM  Saint Pierre and Miquelon
PR  Puerto Rico
PS  Palestinian Territory
PT  Portugal
PY  Paraguay
QA  Qatar
RE  Réunion
RO  Romania
RS  Serbia
RU  Russian Federation
RW  Rwanda
SA  Saudi Arabia
SC  Seychelles
SD  Sudan
SE  Sweden
SG  Singapore
SH  Saint Helena
SI  Slovenia
SK  Slovakia
SL  Sierra Leone
SN  Senegal
SR  Suriname
ST  Sao Tome and Principe
SV  El Salvador
SY  Syrian Arab Republic (Syria)
SZ  Swaziland
TC  Turks and Caicos Islands
TG  Togo
TH  Thailand
TL  Timor-Leste
TM  Turkmenistan
TO  Tonga
TR  Turkey
TT  Trinidad and Tobago
TW  Taiwan, Republic of China
TZ  Tanzania, United Republic of
UA  Ukraine
UG  Uganda
US  United States of America
UY  Uruguay
UZ  Uzbekistan
VC  Saint Vincent and Grenadines
VE  Venezuela (Bolivarian Republic)
VG  British Virgin Islands
VI  Virgin Islands, US
VN  Viet Nam
WS  Samoa
YE  Yemen
YT  Mayotte
ZA  South Africa
ZM  Zambia
ZW  Zimbabwe

Покажите ваш код XML и Java, чтобы мы могли вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...