Как проверить введенный пользователем номер телефона в EditText?

Мобильный номер будет введен в edittext пользователем на странице регистрации в приложении для Android. Как я могу проверить, что пользователь ввел номер своего мобильного телефона, а не другой?

Я пробовал это:

TelephonyManager tMgr =(TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
  mPhoneNumber = tMgr.getLine1Number();

И сравните эту переменную с текстом edittext. Но mPhoneNumber возвращает NULL в моем случае. Есть ли другие варианты? Как это решить?

Любая помощь будет заметна.

Я пробовал это: Проверьте исходный код:

     public class MainActivity extends Activity{    

    Button submit;
    EditText contact;
    String phNo;
    ProgressDialog progress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        contact = (EditText)findViewById(R.id.mobileNumber);
        submit = (Button) findViewById(R.id.button1);

        submit.setOnClickListener(new OnClickListener()
        {
                public void onClick(View v)
                {
                    phNo = contact.getText().toString();
                    new CheckOwnMobileNumber().execute();
                    Toast.makeText(getApplicationContext(), phNo, Toast.LENGTH_LONG).show();
                }
        });



    }

    private class CheckOwnMobileNumber extends AsyncTask<String, Void, String>
    {
        @Override
        protected void onPostExecute(String result)
        {
            // TODO Auto-generated method stub
            if(progress.isShowing())
            {
                progress.dismiss();
                // Check SMS Received or not after that open dialog date
                /*if(SMSReceiver.str.equals(phNo))
                {
                    Toast.makeText(getApplicationContext(), "Thanks for providing your number.", Toast.LENGTH_LONG).show();
                }
                else
                {
                    Toast.makeText(getApplicationContext(), "Provide your own mobile number please.", Toast.LENGTH_LONG).show();
                    return;
                }*/

            }
        }

        @Override
        protected String doInBackground(String... params)
        {
            // TODO Auto-generated method stub
            String msg = phNo;
            try
            {
                sendSMS(phNo, msg);
            }
            catch(Exception ex)
            {
                Log.v("Exception :", ""+ex);
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            progress = ProgressDialog.show(MainActivity.this, "","Checking Mobile Number...");
            progress.setIndeterminate(true);
            progress.getWindow().setLayout(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
            super.onPreExecute();
        }

}

    private void sendSMS(String phoneNumber, String message)
        {        
            //PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 0);                
            SmsManager sms = SmsManager.getDefault();
            sms.sendTextMessage(phoneNumber, null, message, null, null);        
        }
}

Приемник для прослушивания полученных SMS или нет?

public class SMSReceiver extends BroadcastReceiver
{
private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
Context mContext;
private Intent mIntent;
static String address, str = null;

// Retrieve SMS
public void onReceive(Context context, Intent intent) {
    mContext = context;
    mIntent = intent;

    String action = intent.getAction();

    if(action.equals(ACTION_SMS_RECEIVED))
    {
        SmsMessage[] msgs = getMessagesFromIntent(mIntent);
        if (msgs != null)
        {
            for (int i = 0; i < msgs.length; i++)
            {
                address = msgs[i].getOriginatingAddress();
                str = msgs[i].getMessageBody().toString();
            }
        }   

        // ---send a broadcast intent to update the SMS received in the
        // activity---
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction("SMS_RECEIVED_ACTION");
        broadcastIntent.putExtra("sms", str);
        context.sendBroadcast(broadcastIntent);
    }

}

public static SmsMessage[] getMessagesFromIntent(Intent intent)
{
    Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
    byte[][] pduObjs = new byte[messages.length][];

    for (int i = 0; i < messages.length; i++)
    {
        pduObjs[i] = (byte[]) messages[i];
    }

    byte[][] pdus = new byte[pduObjs.length][];
    int pduCount = pdus.length;
    SmsMessage[] msgs = new SmsMessage[pduCount];
    for (int i = 0; i < pduCount; i++)
    {
        pdus[i] = pduObjs[i];
        msgs[i] = SmsMessage.createFromPdu(pdus[i]);
    }
    return msgs;
}
}

LOGCAT:

03-13 17:31:02.049: E/ActivityManager(161): ANR in com.example.test
03-13 17:31:02.049: E/ActivityManager(161): Reason: Broadcast of Intent { act=android.provider.Telephony.SMS_RECEIVED cmp=com.example.test/.SMSReceiver (has extras) }
03-13 17:31:02.049: E/ActivityManager(161):   54% 3732/com.example.test: 54% user + 0% kernel / faults: 21 minor
03-13 17:31:02.049: E/ActivityManager(161):   40% 3732/com.example.test: 40% user + 0% kernel / faults: 2 minor
03-13 17:31:30.699: I/ActivityManager(161): Killing com.example.test (pid=3732): user request
03-13 17:31:30.799: I/ActivityManager(161): Process com.example.test (pid 3732) has died.
03-13 17:31:30.799: I/WindowManager(161): WIN DEATH: Window{40992f50 com.example.test/com.example.test.MainActivity paused=false}
03-13 17:31:30.819: E/InputDispatcher(161): channel '40818670 com.example.test/com.example.test.MainActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x8
03-13 17:31:30.819: E/InputDispatcher(161): channel '40818670 com.example.test/com.example.test.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
03-13 17:34:59.649: I/ActivityManager(161): Start proc com.example.test for broadcast com.example.test/.SMSReceiver: pid=4037 uid=10098 gids={}

Ответ 1

Я решил это сам. Вот мой рабочий код. Класс MainActivity:

   public class MainActivity extends Activity
{    
    Button submit;
    EditText contact;
    static String phNo;
    ProgressDialog progress;
    static Boolean wasMyOwnNumber;
    static Boolean workDone;
    final static int SMS_ROUNDTRIP_TIMOUT = 30000;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        contact = (EditText)findViewById(R.id.mobileNumber);
        submit = (Button) findViewById(R.id.button1);
        wasMyOwnNumber = false;
        workDone = false;
        submit.setOnClickListener(new OnClickListener()
        {
                public void onClick(View v)
                {
                    phNo = contact.getText().toString();
                    new CheckOwnMobileNumber().execute();
                }
        });
    }

    private class CheckOwnMobileNumber extends AsyncTask<String, Void, String>
    {
        @Override
        protected void onPostExecute(String result)
        {
            // TODO Auto-generated method stub
            if(progress.isShowing())
            {
                progress.dismiss();
                if(wasMyOwnNumber)
                {
                    Toast.makeText(getApplicationContext(), "Number matched.", Toast.LENGTH_LONG).show();
                    wasMyOwnNumber = false;
                    workDone = false;
                }
                else
                {
                    Toast.makeText(getApplicationContext(), "Wrong number.", Toast.LENGTH_LONG).show();
                    wasMyOwnNumber = false;
                    workDone = false;
                    return;
                }
            }
            super.onPostExecute(result);
        }

        @Override
        protected String doInBackground(String... params)
        {
            // TODO Auto-generated method stub
            String msg = phNo;
            try
            {
                SmsManager sms = SmsManager.getDefault();
                sms.sendTextMessage(phNo, null, msg, null, null);
                timeout();
            }
            catch(Exception ex)
            {
                Log.v("Exception :", ""+ex);
            }
            return null;
        }

        @Override
        protected void onPreExecute() 
        {
            // TODO Auto-generated method stub
            progress = ProgressDialog.show(MainActivity.this, "","Checking Mobile Number...");
            progress.setIndeterminate(true);
            progress.getWindow().setLayout(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
            super.onPreExecute();
        }
    }

    private boolean timeout()
    {
           int waited = 0;
           while (waited < SMS_ROUNDTRIP_TIMOUT)
           {
              try
              {
                Thread.sleep(100);
              }
              catch (InterruptedException e)
              {
                // TODO Auto-generated catch block
                e.printStackTrace();
              }
              waited += 100;
              if(phoneNumberConfirmationReceived())
              {
                  waited=SMS_ROUNDTRIP_TIMOUT;
                  workDone = true;
              }
           }
           /*Log.v("MainActivity:timeout2: Waited: " , ""+waited);
           Log.v("MainActivity:timeout2:Comparision: ", ""+ phoneNumberConfirmationReceived());
           Log.v("MainActivity:timeout2: WorkDone value after wait complete : ", ""+workDone);*/
        return workDone;
    }

    private boolean phoneNumberConfirmationReceived()
    {
        if(wasMyOwnNumber)
        {
            workDone = true;
        }
        return workDone;
    }
}

Код SMSReceiver:

 public class SMSReceiver extends BroadcastReceiver
{
    private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
    Context mContext;
    private Intent mIntent;
    static String address, str = null;
    boolean isSame;

    // Retrieve SMS
    public void onReceive(Context context, Intent intent)
    {
        mContext = context;
        mIntent = intent;
        String action = intent.getAction();
        if(action.equals(ACTION_SMS_RECEIVED))
        {
            SmsMessage[] msgs = getMessagesFromIntent(mIntent);
            if (msgs != null)
            {
                for (int i = 0; i < msgs.length; i++)
                {
                    address = msgs[i].getOriginatingAddress();
                    str = msgs[i].getMessageBody().toString();
                }
            }
            Log.v("Originating Address : Sender :", ""+address);
            Log.v("Message from sender :", ""+str);
            isSame = PhoneNumberUtils.compare(str, MainActivity.phNo);
            Log.v("Comparison :", "Yes this true. "+isSame);
            if(isSame)
            {
                 MainActivity.wasMyOwnNumber = isSame;
                 MainActivity.workDone=true;
            }

            // ---send a broadcast intent to update the SMS received in the
            // activity---
            Intent broadcastIntent = new Intent();
            broadcastIntent.setAction("SMS_RECEIVED_ACTION");
            broadcastIntent.putExtra("sms", str);
            context.sendBroadcast(broadcastIntent);
        }
    }

    public static SmsMessage[] getMessagesFromIntent(Intent intent)
    {
        Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
        byte[][] pduObjs = new byte[messages.length][];

        for (int i = 0; i < messages.length; i++)
        {
            pduObjs[i] = (byte[]) messages[i];
        }

        byte[][] pdus = new byte[pduObjs.length][];
        int pduCount = pdus.length;
        SmsMessage[] msgs = new SmsMessage[pduCount];
        for (int i = 0; i < pduCount; i++)
        {
            pdus[i] = pduObjs[i];
            msgs[i] = SmsMessage.createFromPdu(pdus[i]);
        }
        return msgs;
    }
}

Не найдено ANR.

Ответ 2

Не гарантируется, что tMgr.getLine1Number(); всегда будет возвращать номер вашей SIM-карты. Потому что это зависит от наличия номера на SIM-карте. Как и в моем случае, моя SIM-карта Tre-Sweden не содержит мой номер телефона.

Но если вы поместите SIM-карту в старый телефон SonyEricsson или Nokia, вы получите возможность редактировать этот номер (на SIM-карте). После его завершения устройство android распознает номер и покажет вам.

Кроме того, если вы получите свой номер телефона через код, лучший способ сравнить два числа:

boolean isSame = PhoneNumberUtils.compare(num1, num2);

В качестве альтернативы вы можете реализовать какую-то логику проверки PIN-кода (например, Viber, WhatsApp или другое приложение), в котором вы просите пользователя ввести свой номер телефона во время регистрации. Позже этот номер телефона отправляется на сервер и генерируется пин-код против этого номера, который отправляется пользователю через SMS. Наконец, пользователь должен ввести этот пин-код (полученный в SMS) для завершения регистрации.

или

Просто отправьте SMS с пользовательского устройства (с согласия) на свой сервер/устройство и узнайте их номер телефона.

Ответ 3

Получение номера телефона с помощью getLine1Number() небезопасно и не обязательно.

Это общепринято, потому что все это "получение номера телефона" - это столкновение с несколькими проблемами, такими как конфиденциальность пользователей, брендинг брендов и даже поставщик.

В любом случае, в отличие от ios, андроид android.provider.Telephony.SMS_RECEIVED делает весь процесс очень удобным и беззвучным для пользователя: вы можете захватить смс и прочитать его без какой-либо необходимости вмешательства пользователя.

Как это сделать?

На вашем сервере после получения запроса на подтверждение номера телефона вы должны создать секретный код tokenSent и отправить его в приложение. Теперь ваш сервер должен отправить этот код с помощью sms на указанный номер телефона. Приложение к настоящему времени должно иметь зарегистрированный приемник, прослушивающий намерение android.provider.Telephony.SMS_RECEIVED. После получения приложение проверяет, что tokenSent идентичен тому, что он получил от сервера. На этом этапе регистрация телефона завершена, и сервер может быть уведомлен.

Что может пойти не так?

Как правило, такие приложения обычно являются платными приложениями, и пользователям нехорошо пытаться что-либо предпринять. Тем не менее, пользователь может ввести неправильный номер, который у него есть прямо сейчас. Затем, получив sms, он может отправить его на мобильный, где приложение регистрируется. Затем приложение получит tokenSent и неправильно проверит номер телефона.

Как мы можем справиться с этим?

Возможность решения зависит от того, разрешает ли поставщик sms ваш сервер знать номер телефона отправителя. Вероятно, это (AFAIK) не произойдет, но если это произойдет, вам повезло. Таким образом, приложение, получив tokenSent, отправит его обратно на сервер вместе с отправителем sms. Затем сервер может проверить, что это sms, который был создан у вашего поставщика услуг.

Любое более приемлемое решение? (Если я действительно параноик)

В этом случае лучшим решением, я считаю, будет запрос tokenSent с вашего сервера. Сервер сохраняет сгенерированный токенSent вместе с введенным номером телефона и отправляет этот токен в приложение. Приложение уведомляет пользователя о том, что регистрация будет стоить ему 1 смс. После того, как пользователь согласится, вы можете легко отправить sms в фоновом режиме, содержащий этот tokenSent, к определенной службе. Сервер, после получения этого tokenSent, проверяет пользователя, используя токен и отправитель смс. Конечно, это может показаться немного преследующим и нарушающим прав пользователя, но это самый безопасный способ, особенно для такого параноидального (чтение этой части).

Формальности: P

Add Permissions in Manifest

<uses-permission android:name="android.permission.RECEIVE_SMS">

Register the receiver (сделайте это перед отправкой sms на телефон)

registerReceiver(new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getExtras() != null)
        {
            Object[] pdus = (Object[]) intent.getExtras().get("pdus");
            SmsMessage[] msgs = new SmsMessage[pdus.length];            
            for (int i=0; i<msgs.length; i++){
                msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);                
               String from = msgs[i].getOriginatingAddress();                     
                String body = msgs[i].getMessageBody().toString();
                //here is the body
                //...
                unregisterReceiver(this); //If you are done with verification
            }
        }  
    }
}, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));

Ответ 4

public class MainActivity extends Activity{    

    Button submit;
    EditText contact;
    String phNo;
    ProgressDialog progress;
    Boolean wasMyOwnNumber = false;
Boolean workDone = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        contact = (EditText)findViewById(R.id.mobileNumber);
        submit = (Button) findViewById(R.id.button1);

        submit.setOnClickListener(new OnClickListener()
        {
                public void onClick(View v)
                {
                    phNo = contact.getText().toString();
                    new CheckOwnMobileNumber().execute();
                    Toast.makeText(getApplicationContext(), phNo, Toast.LENGTH_LONG).show();
                }
        });



    }

    private class CheckOwnMobileNumber extends AsyncTask<String, Void, String>
    {
        @Override
        protected void onPostExecute(String result)
        {
            // TODO Auto-generated method stub
            if(progress.isShowing())
            {

                progress.dismiss();
                // Check SMS Received or not after that open dialog date
                /*if(SMSReceiver.str.equals(phNo))
                {
                    Toast.makeText(getApplicationContext(), "Thanks for providing your          number.", Toast.LENGTH_LONG).show();
wasMyOwnNumber=true;workDone=true;
                }
                else
                {
                    Toast.makeText(getApplicationContext(), "Provide your own mobile number please.", Toast.LENGTH_LONG).show();
wasMyOwnNumber=false;workDone=true;
                    return;
                }*/


            }
        }

        @Override
        protected String doInBackground(String... params)
        {
            // TODO Auto-generated method stub
            String msg = phNo;
            try
            {
                sendSMS(phNo, msg);
                int count=0;
                     while(!workDone)
                          {count++;}
            }
            catch(Exception ex)
            {
                Log.v("Exception :", ""+ex);
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            progress = ProgressDialog.show(MainActivity.this, "","Checking Mobile Number...");
            progress.setIndeterminate(true);
            progress.getWindow().setLayout(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
            super.onPreExecute();
        }

}

    private void sendSMS(String phoneNumber, String message)
        {        
            //PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 0);                
            SmsManager sms = SmsManager.getDefault();
            sms.sendTextMessage(phoneNumber, null, message, null, null);        
        }

public class SMSReceiver extends BroadcastReceiver
{
private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
Context mContext;
private Intent mIntent;
static String address, str = null;

// Retrieve SMS
public void onReceive(Context context, Intent intent) {
    mContext = context;
    mIntent = intent;

    String action = intent.getAction();

    if(action.equals(ACTION_SMS_RECEIVED))
    {
        SmsMessage[] msgs = getMessagesFromIntent(mIntent);
        if (msgs != null)
        {
            for (int i = 0; i < msgs.length; i++)
            {
                address = msgs[i].getOriginatingAddress();
                str = msgs[i].getMessageBody().toString();
            }
        }   

        // ---send a broadcast intent to update the SMS received in the
        // activity---
        workDone=true;
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction("SMS_RECEIVED_ACTION");
        broadcastIntent.putExtra("sms", str);
        context.sendBroadcast(broadcastIntent);

    }

}

public static SmsMessage[] getMessagesFromIntent(Intent intent)
{
    Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
    byte[][] pduObjs = new byte[messages.length][];

    for (int i = 0; i < messages.length; i++)
    {
        pduObjs[i] = (byte[]) messages[i];
    }

    byte[][] pdus = new byte[pduObjs.length][];
    int pduCount = pdus.length;
    SmsMessage[] msgs = new SmsMessage[pduCount];
    for (int i = 0; i < pduCount; i++)
    {
        pdus[i] = pduObjs[i];
        msgs[i] = SmsMessage.createFromPdu(pdus[i]);
    }
    return msgs;
}
}
    }

Ответ 5

Просто хочу добавить немного к приведенным выше объяснениям в приведенных выше ответах. Который сэкономит время и для других.

В моем случае этот метод не вернул номер мобильного телефона, была возвращена пустая строка. Это было связано с тем, что я портировал свой номер на новом симе. Поэтому, если я перейду в Настройки > О телефоне > Статуs > Мой номер телефона, он покажет мне "Неизвестно".

Возможно, это связано с тем, что вы перенесли номер из одной сети в другую.

Если вы не можете проверить номер из API Затем:

Один из способов сделать это - вы создаете текстовое сообщение для номера и отправляете случайное сообщение "Нет" на номер мобильного телефона. Вам нужно будет попросить пользователя ввести этот произвольно сгенерированный номер в ваше приложение. После того, как он будет введен в приложение, вы можете отправить его на сервер, чтобы проверить, правильно ли указан номер, переданный в тексте (который вы уже сохранили на сервере с этим мобильным номером).

Надеюсь, это имеет смысл.