java - Oreo 8.0 - 'sendTextMessage()' 未将消息保存到已发送文件夹
问题描述
我正在尝试使用“sendTextMessage”或“sendMultipartTextMessage”从我自己的应用程序发送短信。对于高于 API 19 (KitKat) 的手机,此消息将保存到发送的文件夹中。但是,在我的 Android 8.0 Oreo 手机上,它不会保存到已发送的项目中。
为了在此处发布,我创建了一个非常基本的测试应用程序。当 MainActivity 的 Resume 函数触发时,此 App 将简单地检查权限并发送文本。这是代码。
显现:
<?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>
建造等级
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.focus4software.www.myapplicationtest2"
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
主要活动:
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 Provider(默认 SMS 应用始终负责写入)其向 SMS Provider 发送的消息)。有关如何充当默认 SMS 应用程序的信息,请参阅电话。
作为一种解决方法,我尝试手动保存消息。在 SendSMS 函数的底部,这被注释掉了。但是,运行此代码不会导致异常,但也不会将 SMS 保存到发送文件夹。这也适用于旧手机。我不确定这是否是一个相关问题。
我在这里错过了什么吗?任何人都可以帮忙吗?:)
解决方案
只是想将这个线程更新为我发现的内容。
似乎 Mike M 是正确的,因为这是特定于某些型号的。我使用的是荣耀 9,另一个堆栈溢出用户在 p20 lite 上遇到了类似的问题。都是华为。我对许多不是华为的模型进行了许多测试,并且从未设法复制该问题。
正如我的问题中提到的,如果短信不存在,使用代码手动保存短信也无法保存短信……也许这适用于这种情况下的其他用户。
我发现唯一可行的解决方法是显示短信活动并让用户自己发送短信。缺点是它需要用户输入,您只需填充 SMS 活动让他们发送消息。这是一个关于如何做到这一点的有用链接: launch sms application with an intent
对于有类似问题的人,可以只使用一些时髦的代码弹出 SMS Activity 某些模型.. 或者通过尝试保存虚拟短信并查看它是否有效来检测是否存在此问题(如果确实有效,请记住将其删除工作).. 如果它失败显示 SMS 活动......
IMO 每种解决方法都令人不安,我愿意接受任何人的任何建议。:)
推荐阅读
- python - 为什么先前定义的 python 变量仍然会导致“赋值前引用”错误?
- android - Asynctask 在后台打开网页 Android Kotlin
- r - 根据另一列的日期添加具有是/否值的列
- android - 将 retrofit2 从 2.6.0 更新到 2.9.0 版本时出错似乎与 Firebase 冲突
- android-studio - NullPointerException 不在我的代码中,但在 LibGDX AndroidInput 的 onResume() 中
- javascript - Zapier Code (JavaStep) 操作:如何将服务器 XML 响应正文转换为 JSON 或 JS 对象?
- python - 循环两个不同的 Win 10 Toast 通知
- python - 比较 Pandas 列中上一个和下一个不同的值
- c++ - 关于邻接矩阵实现的问题
- android - 当我在 Firebase Android 中记录第一次时间时,无法获取 profileUser 的 imageUrl