当前位置: 首页 > 知识库问答 >
问题:

Android KitKat(API 19)-如何在短信内容提供商中编写消息,而不发送它们,从非默认应用程序?

苏星宇
2023-03-14

现在,我有以下代码:

清单文件

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

Java类

private final String SENT_SMS_CONTENT_PROVIDER_URI_OLDER_API_19 = "content://sms/sent";

ContentValues values = new ContentValues();
values.put("address", mNumber);
values.put("body", mMessage);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
  mContext.getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);
else mContext.getContentResolver().insert(Uri.parse(SENT_SMS_CONTENT_PROVIDER_URI_OLDER_API_19), values);
    null
    null

不幸的是,下一个代码在Android 4.4.2中停止工作:

Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.Settings");
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.putExtra(":android:show_fragment", "com.android.settings.applications.AppOpsSummary");
startActivity(intent);

我没有解决这个问题的办法。

共有1个答案

钦宏义
2023-03-14

SMSWriteOputils类使用反射来访问AppopsManager服务的方法,以便启用/禁用非默认SMS应用程序对API Level 19(KitKat)中的SMS提供程序的写访问。一旦设置,一个应用程序的访问模式将被保留,直到它被重置,或者该应用程序被卸载。

启用应用程序的写访问允许该应用程序使用与SMS提供程序交互的所有标准方法,包括insert()delete()

请注意,该类不进行API级别检查,并且仍然需要write_sm权限。

import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public final class SmsWriteOpUtils {
    private static final int WRITE_OP_CODE = 15;

    public static boolean isWriteEnabled(Context context) {
        int result = checkOp(context);
        return result == AppOpsManager.MODE_ALLOWED;
    }

    public static boolean setWriteEnabled(Context context, boolean enabled) {
        int mode = enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
        return setMode(context, mode);
    }

    private static int checkOp(Context context) {
        try {
            Method checkOpMethod = AppOpsManager.class.getMethod("checkOp",
                                                                 Integer.TYPE,
                                                                 Integer.TYPE,
                                                                 String.class);

            AppOpsManager appOpsManager =
                (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
            int uid = context.getApplicationInfo().uid;
            String packageName = context.getPackageName();

            return checkOpMethod.invoke(appOpsManager, WRITE_OP_CODE, uid, packageName);
        }
        catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return -1;
    }

    private static boolean setMode(Context context, int mode) {
        try {
            Method setModeMethod = AppOpsManager.class.getMethod("setMode",
                                                                 Integer.TYPE,
                                                                 Integer.TYPE,
                                                                 String.class,
                                                                 Integer.TYPE);

            AppOpsManager appOpsManager =
                (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
            int uid = context.getApplicationInfo().uid;
            String packageName = context.getPackageName();

            setModeMethod.invoke(appOpsManager, WRITE_OP_CODE, uid, packageName, mode);

            return true;
        }
        catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }
}
boolean canWriteSms;

if(!SmsWriteOpUtils.isWriteEnabled(getApplicationContext())) {
    canWriteSms = SmsWriteOpUtils.setWriteEnabled(getApplicationContext(), true);
}
...
 类似资料:
  • 我的Android应用程序使用短信无声地发出通知。在Kitkat之前,这些通知不会记录到SMS提供商中,因此不会出现在用户的会话列表中。这是应用程序想要的行为。 随着Kitkat SMS的更改(请参阅下面引用的SmsManger文档),这些消息仍然被发送,但现在会自动写入SMS提供商,从而出现在用户的会话列表中。这对我的应用程序来说是不可取的。 从Android4.4(API Level19)开始

  • 我想知道我是否可以用非默认短信应用程序发送短信。

  • 我有一个运行在上。 我使用来提供静态文件,即生成的包,但这是不相关的。 我想要实现的是: 关于我想提供。我能做到。 在我想为。 在我想提供。 最后两个,我做不到。当我进入或我收到了默认的nginx页面。 为了使事情更加混乱被完全注释掉。 此外,如果在的块中,我将替换为,我将获得该特定项目的服务,但是我将无法为另一个服务。 下面,我将向您展示我的nginx配置 谢谢你的帮助! 编辑 我找到的解决方案

  • 我试图在Kafka上发送消息,当在特定表记录中插入时。我认为这部分应用程序将被视为供应商。 我有以下代码。 我实际上想发送数据。所以,我正在寻找更像以下内容的东西: 这可能吗?我如何配置它?例如,如果 我声明为“供应商”,那么如何向其传递数据 如果我声明一个“函数”,那么输入似乎将从主题接收并转发。我没有收到来自主题的数据。我正在从RESTAPI数据库接收数据 我不确定以下几点是否能有所帮助:但只

  • 首先,我使用模拟器来测试这一点。我想用短信文本(作为参数发送)打开默认的SMS应用程序,并允许用户从那里获得控制权(以及内置的应用程序)。我使用以下代码: 当我按下按钮时,什么也没发生。我希望SMS默认应用程序打开,包含用户必须填写的文本和其他字段,然后发送消息。这是因为模拟器还是我的代码?我还在清单中指定了权限: