我需要爲我的用戶準備一個經過驗證的電話號碼,但經過研究,似乎沒有可靠的方法從設備獲取手機號碼。我見過幾次的一個建議是發送一條短信,然後在廣播接收器中捕獲它,並根據意向解析電話號碼。我已經看到這個問題: I could not get data from Intent after broadcast received和this one,但他們沒有解決我的問題。如何在廣播接收器中獲取短信數據
目前,我有接收器工作,但我無法獲得關於SMS消息的任何數據,這可能是通過意圖訪問的。
下面是當用戶按下發送按鈕觸發該代碼:
btnSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
String SENT = "sent";
String DELIVERED = "delivered";
Intent sentIntent = new Intent(SENT);
/*Create Pending Intents*/
PendingIntent sentPI = PendingIntent.getBroadcast(
getApplicationContext(), 0, sentIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
/* Register for SMS send action */
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
try {
---> **SmsMessage[] smsMessage = Telephony.Sms.Intents.getMessagesFromIntent(intent);**
String messageBody = smsMessage[0].getMessageBody();
} catch (Exception e) {
e.printStackTrace();
}
int resultcode = getResultCode();
Log.d(" RESULT=", Integer.toString(resultcode));
}
}, new IntentFilter(SENT));
SmsManager smsManager = SmsManager.getDefault();
if ((ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.SEND_SMS) !=
PackageManager.PERMISSION_GRANTED) ||
(ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.RECEIVE_SMS) !=
PackageManager.PERMISSION_GRANTED)){
ActivityCompat.requestPermissions(SMSActivity.this,
new String[] {
Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_SMS
}, 1);
}
smsManager.sendTextMessage(phoneNo.getText().toString(), null,
msg.getText().toString(), sentPI, null);
} catch (Exception ex) {
Toast.makeText(getApplicationContext(),
ex.getMessage(), Toast.LENGTH_LONG)
.show();
ex.printStackTrace();
}
}
});
當調用getMessagesFromIntent()由(粗體線),拋出一個異常作爲「的onReceive這裏列出( SMSActivity.java:60):「Intent不是null,所以看起來」null array「是getMessagesFromIntent的內部。
W/System.err: java.lang.NullPointerException: Attempt to get length of null array
W/System.err: at android.provider.Telephony$Sms$Intents.getMessagesFromIntent(Telephony.java:1345)
W/System.err: at com.jdot.jsontest.SMSActivity$1$1.onReceive(SMSActivity.java:60)
W/System.err: at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:993)
W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:158)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:7224)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
我想我可能有相關的問題權限。我把這個添加到我的清單:
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
我也看到了這個清單除了幾次,但我不知道如何命名MyBroadcastListener,因爲它不是像例子類我見過。
<receiver android:name="MyBroadcastListener">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
最後,我在的onReceive的身體試圖下面的代碼塊(作爲替代)()。雖然intent.getExtras()返回一個Bundle,但是調用bundle.get(「pdus」)返回null,所以一切都失敗了。
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
if (bundle != null) {
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
}
//---display the new SMS message---
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}
我的問題是:
- 我是否需要接收器/意圖濾波器塊在我的表現,如果是這樣,我怎麼命名的第一行聽衆?
- 我無法在onReceive()中收到傳入消息的副本的原因是什麼?我該如何糾正?
- 我是否需要在onReceive()中發送消息並「捕獲」消息以便可靠地獲取設備的電話號碼,或者我可以請求獲取用戶讀取SMS的權限,並且只需讀取第一條消息以獲取來電號碼?
請注意,我已經通讀了所有類似的問題,但沒有找到答案。
非常感謝您的幫助!我會給你一槍,讓你知道。 –
沒問題。如果可以的話,我只是意識到我忽略了提及應該堅持'getMessagesFromIntent()'方法。即,至少在API 19或以上。在API 23中爲不同的PDU格式增加了一個新的'SmsMessage#createFromPdu()'重載,並且使用'getMessagesFromIntent()'將調用正確的API層次的適當參數,所以你不必你自己。 –
我不能告訴你我多麼感激解釋。我按照你的建議修改了這個意圖,它的效果非常好。有一個問題,如果我想支持API 18,我認爲我應該使用bundle.get(「pdus」)方法來解析消息,並且「android.provider.Telephony.SMS_RECEIVED」仍然可以工作?我無法從你的評論中得知它是API-19特有的常數還是兩者。 –