Java 奥利奥8.0-';sendTextMessage()';未将邮件保存到“已发送”文件夹

Java 奥利奥8.0-';sendTextMessage()';未将邮件保存到“已发送”文件夹,java,android,Java,Android,我正在尝试使用“sendTextMessage”或“sendMultipartTextMessage”从我自己的应用程序发送短信。对于高于API 19(KitKat)的手机,此消息将保存到sent文件夹。然而,在我的Android 8.0 Oreo手机上,它并没有保存到发送的邮件中 为了在这里发布,我创建了一个非常基本的测试应用程序。当为MainActivity启动Resume函数时,此应用程序将只检查权限并发送文本。这是代码 舱单: <?xml version="1.0" encodin

我正在尝试使用“sendTextMessage”或“sendMultipartTextMessage”从我自己的应用程序发送短信。对于高于API 19(KitKat)的手机,此消息将保存到sent文件夹。然而,在我的Android 8.0 Oreo手机上,它并没有保存到发送的邮件中

为了在这里发布,我创建了一个非常基本的测试应用程序。当为MainActivity启动Resume函数时,此应用程序将只检查权限并发送文本。这是代码

舱单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.focus4software.www.myapplicationtest">

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
主要活动:

package com.focus4software.www.myapplicationtest;

import android.Manifest;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Telephony;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_RESULTCODE = 1;

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

    @Override
    public void onResume(){
        super.onResume();


        //Check Permissions first
        if (android.os.Build.VERSION.SDK_INT >= 23) {
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
                //Permissions not found..  request them
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.SEND_SMS}, REQUEST_RESULTCODE);
            }
            else {
                this.SendSMS();
            }
        }
        else {
            this.SendSMS();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_RESULTCODE: {
                if (grantResults.length == 1) {
                    //Make sure none of the permissions were denied
                    boolean somethingDenied = false;
                    for (int result : grantResults){
                        if (result != PackageManager.PERMISSION_GRANTED){
                            somethingDenied = true;
                        }
                    }

                    if (somethingDenied){
                        //a permission was denied
                        Toast.makeText(getApplicationContext(), "Failed to Send The TEST SMS, Permission was denied", Toast.LENGTH_SHORT).show();
                    }
                    else {
                        //turn the app on.. permissions accepted
                        this.SendSMS();
                    }
                }
                else {
                    Toast.makeText(getApplicationContext(), "Failed to Send The TEST SMS, incorrect amount of permissions returned.", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }

    private void SendSMS (){
        String phone = "[INSERT PHONE NUMBER]";
        String message = "InCodeTestExtra";

        //send sms
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phone, null, message, null, null);

        //Show we got here
        Toast.makeText(getApplicationContext(), "Code Executed...  SMS Passed on.", Toast.LENGTH_SHORT).show();

        //Save SMS
        //this.SaveSMS(getApplicationContext(), phone, message);
    }

    private void SaveSMS(Context inContext, String inAddress, String inBody) {
        try {
            ContentValues values = new ContentValues();
            values.put("address", inAddress);
            values.put("body", inBody);
            values.put("read", 1);
            values.put("date", System.currentTimeMillis());
            //values.put("status", delivered);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Uri uri = Telephony.Sms.Sent.CONTENT_URI;
                inContext.getApplicationContext().getContentResolver().insert(uri, values);
            }
            else {
                inContext.getApplicationContext().getContentResolver().insert(Uri.parse("content://sms/sent"), values);
            }

            //notify of the save
            Toast.makeText(getApplicationContext(), "SMS SAVED (Maybe)", Toast.LENGTH_SHORT).show();
        } catch (Exception ex) {
            //notify of the Failure
            Toast.makeText(getApplicationContext(), "SMS Failed to save (" + ex.getMessage() + ")", Toast.LENGTH_SHORT).show();
        }
    }
}
如前所述,这不是将信息保存到我的Android Oreo手机的发送文件夹

根据Android文档,这是注定要发生的

注意:从Android 4.4(API级别19)开始,当且仅当应用程序 如果未选择作为默认短信应用程序,系统将自动 将使用此方法发送的消息写入SMS提供程序( 默认SMS应用程序始终负责将其发送的消息写入 短信服务提供商)。有关如何作为默认设置的信息,请参见 SMS应用程序,请参阅电话

作为一种解决方法,我尝试手动保存消息。在SendSMS函数的底部,这是注释掉的。但是,运行此代码不会导致异常,但也不会将SMS保存到send文件夹。这也适用于老式手机。我不确定这是否是一个相关问题


我是不是遗漏了什么??有人能帮忙吗?:)

我只是想把这个帖子更新到我发现的内容

Mike M似乎是正确的,因为这是特定于某些型号的。我使用的是荣誉9,另一个堆栈溢出用户在p20 lite上也有类似的问题。。都是华威。我在很多模型上做了很多测试,这些模型不是华威的,也从来没有复制过这个问题

正如我在问题中提到的,如果短信不存在,则使用代码手动保存短信也无法保存短信……在这种情况下,这可能适用于其他用户

我发现唯一有效的解决办法是显示短信活动,让用户自己发送短信。缺点是它需要用户输入,您只需填充SMS活动,让他们发送消息。 这里有一个关于如何做到这一点的有用链接:

对于有类似问题的人,可能只会弹出带有一些时髦代码的特定型号的SMS活动。。或者通过尝试保存一条虚拟短信并查看其是否有效来检测是否存在此问题(如果有效,请记住将其删除)。。如果失败,则显示SMS活动


在我看来,每个解决方案都是令人不安的混乱,我愿意听取任何人的建议。:)

消息是否成功发送?也就是说,收信人真的收到了吗?您正在测试的手机的品牌/型号是什么?是,信息发送正常。它只是不在发送后的文件夹中。我使用华为荣誉9作为测试。好吧,我不得不说这个特殊的问题是特定于该型号的,因为我没有听说过其他任何型号的确切行为。在8.0中有一个bug,如果一个应用程序没有持有
READ\u PHONE\u STATE
权限,它会抛出一个
SecurityException
,但我不认为这是一种表现,因为该异常会破坏整个发送,并且不会保持沉默。据报道,我所听到的唯一一个模糊不清的类似问题是通过在该方法中传递send and delivery
PendingEvent
s解决的,但这是一个自定义ROM。很长的一段时间,但你可以给他们一次尝试。我将尝试在另一个型号上尝试。我必须找到一个,等我找到后我会在这里更新。关于READ_PHONE_状态和使用挂起的意图,这个问题来自一个更大的应用程序,该应用程序使用“sendMultipartTextMessage”,同时拥有该权限并传递意图,问题仍然存在。我将继续尝试安装了安卓8.0的其他设备,看看会发生什么。我还将在一些模拟器上进行试验,看看是否会发生这种情况。我会在这里更新,谢谢你的提示:)我和华为荣誉有同样的问题。。。
package com.focus4software.www.myapplicationtest;

import android.Manifest;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Telephony;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_RESULTCODE = 1;

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

    @Override
    public void onResume(){
        super.onResume();


        //Check Permissions first
        if (android.os.Build.VERSION.SDK_INT >= 23) {
            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
                //Permissions not found..  request them
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.SEND_SMS}, REQUEST_RESULTCODE);
            }
            else {
                this.SendSMS();
            }
        }
        else {
            this.SendSMS();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_RESULTCODE: {
                if (grantResults.length == 1) {
                    //Make sure none of the permissions were denied
                    boolean somethingDenied = false;
                    for (int result : grantResults){
                        if (result != PackageManager.PERMISSION_GRANTED){
                            somethingDenied = true;
                        }
                    }

                    if (somethingDenied){
                        //a permission was denied
                        Toast.makeText(getApplicationContext(), "Failed to Send The TEST SMS, Permission was denied", Toast.LENGTH_SHORT).show();
                    }
                    else {
                        //turn the app on.. permissions accepted
                        this.SendSMS();
                    }
                }
                else {
                    Toast.makeText(getApplicationContext(), "Failed to Send The TEST SMS, incorrect amount of permissions returned.", Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }

    private void SendSMS (){
        String phone = "[INSERT PHONE NUMBER]";
        String message = "InCodeTestExtra";

        //send sms
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phone, null, message, null, null);

        //Show we got here
        Toast.makeText(getApplicationContext(), "Code Executed...  SMS Passed on.", Toast.LENGTH_SHORT).show();

        //Save SMS
        //this.SaveSMS(getApplicationContext(), phone, message);
    }

    private void SaveSMS(Context inContext, String inAddress, String inBody) {
        try {
            ContentValues values = new ContentValues();
            values.put("address", inAddress);
            values.put("body", inBody);
            values.put("read", 1);
            values.put("date", System.currentTimeMillis());
            //values.put("status", delivered);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                Uri uri = Telephony.Sms.Sent.CONTENT_URI;
                inContext.getApplicationContext().getContentResolver().insert(uri, values);
            }
            else {
                inContext.getApplicationContext().getContentResolver().insert(Uri.parse("content://sms/sent"), values);
            }

            //notify of the save
            Toast.makeText(getApplicationContext(), "SMS SAVED (Maybe)", Toast.LENGTH_SHORT).show();
        } catch (Exception ex) {
            //notify of the Failure
            Toast.makeText(getApplicationContext(), "SMS Failed to save (" + ex.getMessage() + ")", Toast.LENGTH_SHORT).show();
        }
    }
}