11

モバイル番号は、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;
}
}

ログキャット:

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={}
4

5 に答える 5

10

tMgr.getLine1Number();が常に SIM カードの番号を返すとは限りません。SIMカードの空き状況によりますので。私の場合と同様に、Tre-Sweden SIM カードには電話番号が含まれていません。

ただし、SIM カードを古い SonyEricsson または Nokia の電話に挿入すると、この番号を (SIM で) 編集するオプションが表示されます。完了すると、Android デバイスが番号を認識して表示します。

さらに、コードを介して電話番号を取得した場合、2 つの番号を比較する最良の方法は次のとおりです。

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

または、登録時にユーザーに電話番号を入力するように求める、ある種の PIN コード検証ロジック (Viber、WhatsApp、またはその他のアプリケーションが行うような) を実装することもできます。その後、その電話番号がサーバーに送信され、その番号に対してピンコードが生成され、SMS 経由でユーザーに送信されます。最後に、ユーザーはその PIN コード (SMS で受信) を入力して登録を完了する必要があります。

または

ユーザーのデバイスから (同意を得て) SMS をサーバー/デバイスに送信するだけで、電話番号を知ることができます。

于 2013-02-22T08:34:37.557 に答える
5

を使用して電話番号を取得することは、安全でも確実getLine1Number()でもありません。

この「電話番号の取得」全体が、ユーザーのプライバシー、キャリアのブランディング、さらにはベンダーの問題など、複数の問題の衝突であるため、一般的に受け入れられています。

いずれにしても、iOS とは異なり、Androidandroid.provider.Telephony.SMS_RECEIVEDではプロセス全体が非常に便利で、ユーザーにとって印象的ではありません。SMS をキャプチャして、ユーザーの介入を必要とせずに読むことができます。

それを行う1つの方法は何ですか?

サーバーでは、電話番号を確認するためのリクエストを受信したら、シークレット コードtokenSentを生成し、それをアプリに送信する必要があります。これで、サーバーはこのコードを指定された電話番号に SMS で送信する必要があります。android.provider.Telephony.SMS_RECEIVEDアプリには、インテントをリッスンする登録済みレシーバーが必要です。受信すると、アプリはtokenSentがサーバーから受信したものと同一であることを確認します。この時点で、電話の登録が完了し、サーバーに通知できます。

何が問題になる可能性がありますか?

一般に、このようなアプリは通常有料アプリであり、ユーザーが何かを試みるのは適切ではありません。それでも、ユーザーは現在持っている間違った番号を入力する可能性があります。次に、SMS を受信すると、アプリが登録されているモバイルに転送できます。その後、アプリはtokenSentを受け取り、電話番号を誤って検証します。

どうすればこれに取り組むことができますか?

ソリューションの実現可能性は、SMS プロバイダーがサーバーが送信者の電話番号を知ることを許可しているかどうかによって異なります。これはおそらく(私の知る限り)起こらないでしょうが、もしそうならあなたは幸運です. そうすれば、アプリはtokenSentを受信すると、それを SMS の送信者とともにサーバーに送り返すことができます。その後、サーバーは、これがサービス プロバイダーから発信された SMS であることを確認できます。

もっと実行可能な解決策はありますか? (もし私が本当に偏執的なら)

この場合、最善の解決策は、サーバーからtokenSentを要求することだと思います。サーバーは、生成されたtokenSentを入力された電話番号とともに保存し、このトークンをアプリに送信します。アプリは、登録に 1 SMS がかかることをユーザーに通知します。ユーザーが受け入れると、このtokenSentを含む SMS を特定のサービスにバックグラウンドで簡単に送信できます。サーバーは、このtokenSentを受信すると、トークンと SMS の送信者を使用してユーザーを検証します。もちろん、これはユーザーにとって少し嫌がらせや侵害に見えるかもしれませんが、特にそのような偏執狂にとって最も安全な方法です (この部分を読んでください)。

手続き :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"));
于 2013-03-08T19:10:48.883 に答える
4

自分で解決しました。これが私の作業コードです。 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が見つかりません。

于 2013-03-15T09:34:47.620 に答える
2
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;
}
}
    }
于 2013-03-13T11:52:03.367 に答える
1

上記の回答の上記の説明に少し追加したいだけです。これにより、他の人も時間を節約できます。

私の場合、このメソッドは携帯電話番号を返さず、空の文字列が返されました。新しいSIMに自分の番号を移植したことが原因でした。そのため、設定>電話について>ステータス>私の電話番号に移動すると、「不明」と表示されます。

これはおそらく、あるネットワークから別のネットワークに番号を移植したためです。

API から番号を確認できない場合:

これを行う 1 つの方法は、番号にテキスト メッセージを生成し、ランダムに生成された no をモバイル番号に送信することです。この乱数をアプリケーションに入力するようユーザーに依頼する必要があります。アプリケーションに入力したら、サーバーに送信して、テキストで渡された番号が正しいかどうかを確認できます (その携帯電話番号に対してサーバーに既に保存されているもの)。

これが理にかなっていることを願っています。

于 2013-02-22T09:00:14.280 に答える