錯誤現象
PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(), 0);
smsManager.sendTextMessage(number, null, editText.getText().toString(), pi, null);
// 崩潰於此行
常見原因與檢查清單
- smsManager 為 null
確認已正確取得實例:SmsManager smsManager = SmsManager.getDefault();
- number 為 null 或空字串
加上非空驗證:if (TextUtils.isEmpty(number)) return;
- editText 為 null
確認 findViewById 成功且 ID 正確。
- PendingIntent 參數問題
getActivity 需傳入有效 Context,若在非 Activity 中請用 PendingIntent.getBroadcast。
- 權限缺失
AndroidManifest.xml 需宣告:
<uses-permission android:name="android.permission.SEND_SMS"/>
Android 6.0+ 還需執行期請求權限。
- 雙卡裝置
Android 5.1+ 可用 SmsManager.getSmsManagerForSubscriptionId(subId) 指定卡槽。
最佳實踐程式碼
public void sendSms(String phone, String text) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SEND_SMS}, REQ_SEND_SMS);
return;
}
SmsManager sms = SmsManager.getDefault();
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
new Intent("SMS_SENT"), PendingIntent.FLAG_IMMUTABLE);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
new Intent("SMS_DELIVERED"), PendingIntent.FLAG_IMMUTABLE);
sms.sendTextMessage(phone, null, text, sentPI, deliveredPI);
}
除錯技巧
- 在崩潰行前加
Log.d("TAG", "sms=" + smsManager + ", num=" + number) 確認物件非 null。
- 使用
try-catch 捕獲並上報崩潰日誌。