You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

安卓APP发送短信失败求助:已配置SEND_SMS权限仍无法发送

Hey there! Let's troubleshoot why your SMS sending feature isn't working, based on the code snippets and info you've shared. I'll walk through the most common issues and fixes step by step:

1. Double-Check Your Manifest Permission Placement

First off, make sure your SEND_SMS permission is declared outside the <application> tag in your AndroidManifest.xml—this is a super common mistake. Here's the correct structure:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.your.app.package">

    <!-- Permission goes HERE, not inside <application> -->
    <uses-permission android:name="android.permission.SEND_SMS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        ...>
        <!-- Your activities, services, etc. -->
    </application>
</manifest>
2. Validate Your Dynamic Permission Request Logic

You're already requesting permissions, but adding a pre-check ensures you only request when needed, and avoids edge cases. Update your code to check if the permission is already granted before requesting:

// Call this when you want to send an SMS
public void attemptSendSMS(String phoneNumber, String message) {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission not granted, request it
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.SEND_SMS},
                1);
    } else {
        // Permission already granted, send immediately
        sendSMS(phoneNumber, message);
    }
}
3. Fix Your sendSMS Method Implementation

This is likely the root cause—you mentioned calling sendSMS but didn't share its code. Android has two main ways to send SMS; here's the reliable, recommended approach using SmsManager:

private void sendSMS(String phoneNumber, String message) {
    SmsManager smsManager = SmsManager.getDefault();
    
    // Handle long SMS messages by splitting them automatically
    ArrayList<String> messageParts = smsManager.divideMessage(message);
    
    // Send the split parts (works for short messages too)
    smsManager.sendMultipartTextMessage(phoneNumber, null, messageParts, null, null);
}

If you're using an implicit Intent to open the system SMS app instead, ensure your Intent is set up correctly:

private void sendSMSWithIntent(String phoneNumber, String message) {
    Intent smsIntent = new Intent(Intent.ACTION_SENDTO);
    smsIntent.setData(Uri.parse("smsto:" + Uri.encode(phoneNumber)));
    smsIntent.putExtra("sms_body", message);
    
    // Only launch if there's an app to handle the Intent
    if (smsIntent.resolveActivity(getPackageManager()) != null) {
        startActivity(smsIntent);
    }
}
4. Complete Your Permission Callback Handling

Your onRequestPermissionsResult is missing edge case handling (like when the user cancels the request). Update it to cover all scenarios:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case 1: {
            // If user cancels the request, grantResults will be empty
            if (grantResults.length == 0) {
                Toast.makeText(this, "Permission request cancelled", Toast.LENGTH_SHORT).show();
                return;
            }
            
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted—send your SMS here
                sendSMS(phoneNumberTo, smsMessage);
            } else {
                // Permission denied—inform the user
                Toast.makeText(this, "SMS permission denied, can't send messages", Toast.LENGTH_SHORT).show();
                // Optional: Guide user to app settings to enable permission
            }
            return;
        }
        // Handle other request codes if needed
    }
}
5. Add Error Tracking to Diagnose Failures

To pinpoint exactly why sending fails, add broadcast receivers to listen for SMS send/delivery statuses. This will tell you if it's a network issue, radio problem, or something else:

private void sendSMSWithStatus(String phoneNumber, String message) {
    SmsManager smsManager = SmsManager.getDefault();
    ArrayList<String> messageParts = smsManager.divideMessage(message);
    
    // Create intents to track send/delivery status
    Intent sentIntent = new Intent("SMS_SENT_ACTION");
    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent, PendingIntent.FLAG_IMMUTABLE);
    
    Intent deliveredIntent = new Intent("SMS_DELIVERED_ACTION");
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, deliveredIntent, PendingIntent.FLAG_IMMUTABLE);
    
    // Register receiver for send status
    registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(context, "SMS sent successfully!", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(context, "No network service available", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(context, "Radio is turned off", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(context, "SMS send failed: " + getResultCode(), Toast.LENGTH_SHORT).show();
            }
            unregisterReceiver(this);
        }
    }, new IntentFilter("SMS_SENT_ACTION"));
    
    // Register receiver for delivery status (optional)
    registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (getResultCode() == Activity.RESULT_OK) {
                Toast.makeText(context, "SMS delivered to recipient", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "SMS not delivered", Toast.LENGTH_SHORT).show();
            }
            unregisterReceiver(this);
        }
    }, new IntentFilter("SMS_DELIVERED_ACTION"));
    
    // Send the SMS with status tracking
    smsManager.sendMultipartTextMessage(phoneNumber, null, messageParts,
            Collections.nCopies(messageParts.size(), sentPI),
            Collections.nCopies(messageParts.size(), deliveredPI));
}
6. Check Device/System Limitations
  • Avoid emulators: Some Android emulators don't support SMS sending—test on a physical device if possible.
  • Verify network status: Ensure your device has cellular service and isn't in airplane mode.
  • Check carrier restrictions: Make sure your plan allows SMS sending, and there are no account issues (like unpaid bills).

内容的提问来源于stack exchange,提问作者omriman12

火山引擎 最新活动