Android SmsManager 发送失败

Android SmsManager Fails to Send

我的应用程序中已经有一个 activity 可以发送 SMS 消息,所以我认为将一些代码复制到另一个 activity 会很容易,但是没有!我试图在 MainActivity 上放置两个按钮来发送预先编写的 SMS 消息。完整的 MainActivity.java 是:

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;

import android.telephony.SmsManager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private int MY_PERMISSIONS_REQUEST_SMS_RECEIVE = 10;
    private int MY_PERMISSIONS_REQUEST_SMS_SEND = 20;
    Button button_8;
    Button button_9;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkPermission();
        }

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        button_8 = findViewById(R.id.availability_8);
        button_8.setOnClickListener(view -> sendSMS8());
        button_9 = findViewById(R.id.availability_9);
        button_9.setOnClickListener(view -> sendSMS9());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_most_recent_tasking:
                Intent intent1 = new Intent(this, ShoutActivity.class);
                startActivity(intent1);
                break;

            case R.id.action_settings:
                Intent intent2 = new Intent(this, SettingsActivity.class);
                startActivity(intent2);
                break;

            case R.id.action_about:
                Intent intent3 = new Intent(this, AboutActivity.class);
                startActivity(intent3);
                break;

            default:
                return super.onOptionsItemSelected(item);

        }
        return true;
    }

    protected void sendSMS8() {
        try {
            SmsManager smsManager = SmsManager.getDefault();
            smsManager.sendTextMessage(getString(R.string.at_number), null, "8", null, null);
            Toast.makeText(getApplicationContext(), R.string.a_sent,
                    Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), R.string.a_failed,
                    Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }

    protected void sendSMS9() {
        try {
            SmsManager smsManager = SmsManager.getDefault();
            smsManager.sendTextMessage(getString(R.string.at_number), null, "9", null, null);
            Toast.makeText(getApplicationContext(), R.string.a_sent,
                    Toast.LENGTH_LONG).show();
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), R.string.a_failed,
                    Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void checkPermission() {
        if ((ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED)) {
            requestPermissions(new String[]{Manifest.permission.RECEIVE_SMS}, MY_PERMISSIONS_REQUEST_SMS_RECEIVE);
        }
        if ((ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED)) {
            requestPermissions(new String[]{Manifest.permission.SEND_SMS}, MY_PERMISSIONS_REQUEST_SMS_SEND);
        }
    }
}

AndroidManifest 文件包括

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

        <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:theme="@style/Theme.CgPager.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

我只是不明白为什么这不起作用。 (每次我 运行 它,吐司报告“可用性发送失败”即 string.a_failed。

为了比较,此代码正在另一个 activity:

    protected void sendSMS1() {
    try {
        SmsManager smsManager = SmsManager.getDefault();
        smsManager.sendTextMessage(getString(R.string.at_number), null, "1", null, null);
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        boolean partner_text =  sharedPreferences.getBoolean("partner", false);
        if(partner_text){
            String text_message =  sharedPreferences.getString("partner_textmessage", "");
            String partner_telno =  sharedPreferences.getString("partner_phone", "");
            smsManager.sendTextMessage(partner_telno, null, text_message, null, null);
        }
        Intent intent = getIntent();
        String shoutContent = intent.getStringExtra(ReceiveAlertActivity.EXTRA_MESSAGE);
        Intent secondintent = new Intent(this, ShoutActivity.class);
        secondintent.putExtra(MESSAGE, shoutContent);
        startActivity(secondintent);
        Toast.makeText(getApplicationContext(), R.string.r_sent,
                Toast.LENGTH_LONG).show();
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), R.string.r_failed,
                Toast.LENGTH_LONG).show();
        e.printStackTrace();
    }
}

更新

  1. 你写的代码显示,第一次打开文件时获得的是android.Manifest.permission.RECEIVE_SMS权限,而不是发送短信的权限。 The android.Manifest.permission.SEND_SMS permission只有在第二次打开文件时才会得到

    解决办法是增加请求权限结果的回调方法(onRequestPermissionsResult)。需要多次执行回调方法才能申请下一个权限

  2. 下面通过实现onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)方法提供了一个简单的解决这个问题的方法。

    一个。在Activity.

    中获取权限

    b。

  3. 下面是复杂的批量获取权限的方法。下面是一个例子。

    一个。在AndroidManifest.xml文件中添加要动态获取的权限。

    b。在Activity中批量获取权限:

    c。在onRequestPermissionsResult方法中获取权限后进行处理。


  1. 建议您查看短信发送失败的日志,定位原因。 您可以在 Android Studio 控制台上查看日志。过滤字段为SMS.

    比如您没有发送短信的权限,调用发送短信的代码时会产生如下日志:

  2. 也可以把Toast消息中的Msg改一下,这样可以查看短信原因Toast消息发送失败

    Toast Msg 可以改为""+e.getMessage()

    错误信息:

  3. 以华为phone为例。 App获取短信发送权限后,第一次发送短信时会弹出警告对话框,如下图。

  4. 所以建议您查看日志,找出发送短信失败的原因。