【问题标题】:How to check user entered own phone number in EditText?如何检查用户在 EditText 中输入的自己的电话号码?
【发布时间】:2013-02-22 08:09:36
【问题描述】:

用户将在我的 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);        
        }
}

接收方是否收听短信?

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's 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={}

【问题讨论】:

  • whatsapp 在内部向您的号码发送一条消息,并在内部读取您正在尝试仅通过该号码登录并验证它。如果您尝试使用另一个号码,它会向该号码发送一条消息,您需要从中获取验证码并将其粘贴到此处。 whatsapp 不使用 MSISDN 号码。
  • 使用send 向某人的号码发送短信,并使用read 读取短信并验证消息是否是从您的应用发送的。多田!
  • 我已经尝试了所有这些。顺便说一句,这不是我的问题。请再次阅读我的问题。
  • 您需要检查发送带有生成密钥的消息,并在侦听器中检查是否是您从自己的号码收到的密钥...

标签: android android-asynctask sms telephony android-broadcast


【解决方案1】:

不保证tMgr.getLine1Number(); 将始终返回您的 SIM 卡号码。因为这取决于 SIM 卡中号码的可用性。就像我的情况一样,我的 Tre-Sweden SIM 卡不包含我的电话号码。

但是,如果您将 SIM 卡放入旧的索尼爱立信或诺基亚手机中,则您可以选择编辑此号码(在 SIM 上)。完成后,Android 设备将识别该号码并显示给您。

此外,如果您确实通过代码获取了您的电话号码,那么比较两个号码的最佳方法是:

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

或者,您可以实施某种密码验证逻辑(如 Viber、WhatsApp 或其他应用程序),在其中要求用户在注册期间输入他们的电话号码。随后,该电话号码被发送到服务器,并针对该号码生成一个密码,该密码通过 SMS 发送给用户。最后,用户必须输入该密码(通过短信接收)才能完成注册。

或者

只需从用户的设备(征得同意)向您的服务器/设备发送短信,然后了解他们的电话号码。

【讨论】:

  • 你为什么要投票?我不知道。但是您的答案不是解决方案。当我将这个应用程序上传到 Play 商店时,我会通知每个用户将他们的 sim 卡放入旧的诺基亚或索尼爱立信手机以编辑 sim 卡中的电话号码,然后在 android 上使用它吗?
  • 这样的赞成票也许是有原因的。就像我说的,没有完美的解决方案来验证用户的电话号码是否始终在 sim 卡中可用。解决这个问题的唯一方法是通过用户设备的短信到您的专用设置,或通过用户的电话号码从您的服务器到用户设备的密码类型注册。这是您的第一个(原始)问题的答案,现在如果它仍然不能满足您,那么请提出一个新问题及其相关信息。不要只是不时更新您的问题,这可能会使其他人的答案无效。
  • 此外,将您的SIM卡放入旧手机的想法完全是为了您修复您的SIM卡号码(这可能会在开发过程中有所帮助)。
  • 请编辑您的答案,我想为您的答案投票,因为我使用了您的提示。
【解决方案2】:

使用getLine1Number() 获取电话号码既不安全也不确定

之所以普遍接受,是因为整个“获取电话号码”是用户隐私、运营商品牌、甚至供应商等多个问题的冲突。

无论如何,与 ios 不同的是,android 的android.provider.Telephony.SMS_RECEIVED 使整个过程对用户来说非常方便和无缝:您可以捕获短信并阅读它,而无需用户干预。

一种方法是什么?

在您的服务器上,收到验证电话号码的请求后,您应该生成一个密码 tokenSent,并将其发送到应用程序。现在,您的服务器应该通过短信将此代码发送到指定的电话号码。该应用程序现在应该有一个注册的接收器来监听android.provider.Telephony.SMS_RECEIVED 意图。收到后,应用会验证 tokenSent 是否与它从服务器收到的相同。至此,手机注册完成,可以通知服务器了。

会出什么问题?

一般来说,此类应用程序通常是付费应用程序,用户不宜尝试任何事情。尽管如此,用户可能会输入他现在拥有的错误号码。然后在收到短信后,他可以将其转发到应用注册的手机。然后应用会收到 tokenSent 并错误地验证电话号码。

我们如何解决这个问题?

解决方案的可行性取决于短信提供商是否允许您的服务器知道发件人的电话号码。这可能(AFAIK)不会发生,但如果发生了,那么你很幸运。这样,应用程序可以在收到 tokenSent 后,将其与短信发送者一起发送回服务器。然后服务器可以验证这是来自您的服务提供商的短信。

还有更可行的解决方案吗? (如果我真的偏执)

在这种情况下,我认为最好的解决方案是从您的服务器请求 tokenSent。服务器将生成的 tokenSent 与输入的电话号码一起保存,并将此令牌发送到应用程序。该应用程序通知用户注册将花费他 1 条短信。一旦用户接受,您可以轻松地在后台发送一条包含此 tokenSent 的短信到某个服务。服务器一旦收到此 tokenSent 就会使用令牌验证用户和短信的发送者。当然,这对用户来说可能看起来有点骚扰和侵权,但它是最安全的方式,尤其是对于这种偏执狂(阅读这部分)。

手续:P

Add Permissions in Manifest

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

Register the receiver(在向手机发送短信之前执行此操作)

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"));

【讨论】:

  • 我不想使用服务器端检查用户手机号码。它应该在客户端完成。
  • @ManishAndroid 整个服务器端都可以在手机上完成。 “无缝”
  • 是的。这就是我想要的方式。
  • 实际上,我正在向用户输入的号码发送短信,并检查是否收到了短信,如果收到,那么原始地址是什么,并将原始地址与用户在编辑文本中输入的电话号码进行比较。
  • @ManishAndroid 在这种情况下,它会起作用,但用户可能(如前所述)使用不同的电话号码并将收到的短信发送到应用程序的电话号码。防止这种情况的唯一方法是让应用知道什么是短信的发件人(以确保它来自服务器)
【解决方案3】:

我自己解决了。这是我的工作代码。 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;
    }
}

短信接收方代码:

 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。

【讨论】:

  • 我是否也在清单中为接收者写了,因为我的接收者似乎没有调用 onReceive?
  • 这个应用程序会从用户那里减少短信费用吗?
【解决方案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;
}
}
    }

【讨论】:

  • 我的包裹中有 ANR。我的 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(有附加功能)} 03-13 17:31:02.049: E/ActivityManager(161): 54% 3732/com.example.test: 54 % 用户 + 0% 内核/故障:21 个次要
  • 请在我无法理解的问题中发布格式化的 logcat
  • 好的,现在试试。注意我把while循环从PostExecute()移到doInBackground()
  • 也许只有我一个人,但是在赏金活动中复制粘贴别人的代码感觉不对。
  • 我复制了给定问题本身的任何内容。提示:你觉得可能不对
【解决方案5】:

只是想在上述答案的上述解释中添加一点。这也将为其他人节省时间。

在我的例子中,这个方法没有返回任何手机号码,返回的是一个空字符串。这是因为我将我的号码移植到了新的 sim 卡上。因此,如果我进入“设置”>“关于手机”>“状态”>“我的电话号码”,它会显示“未知”。

这可能是因为您已将号码从一个网络转移到另一个网络。

如果您无法从 API 中检查号码,则:

这样做的一种方法是您向该号码生成一条短信,然后向该手机号码发送一个随机生成的否。您必须要求用户将此随机生成的数字输入您的应用程序。将其输入应用程序后,您可以将其发送到服务器以检查文本中传递的号码是否正确(您已经针对该手机号码在服务器上保存了该号码)。

我希望这是有道理的。

【讨论】:

  • 我没有将号码从一个网络移植到另一个网络。请根据问题给出答案,请参阅我的代码。
  • @ManishAndroid 您能在设置屏幕中看到您的手机号码吗?另请查看我的编辑以验证手机号码
猜你喜欢
  • 2013-06-08
  • 2011-03-08
  • 1970-01-01
  • 2019-12-20
  • 2016-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
相关资源
最近更新 更多