Android KitKat(API 19) – 如何在SMS内容提供程序中写入消息,而不将其发送到非默认应用程序?

前端之家收集整理的这篇文章主要介绍了Android KitKat(API 19) – 如何在SMS内容提供程序中写入消息,而不将其发送到非默认应用程序?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试创建一个在系统的“发送方框”中写入消息的 Android应用程序.这些消息不应该通过GSM网络发送给接收者,这个想法只是将它们写入发送内容提供者.

现在,我有这个代码

清单文件

<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);

对于API版本低于19的设备,此实现工作正常.对于这些较旧的sdk版本,只需要访问由uri内容定义的内容提供者:// sms / sent.

对于较新的sdk版本,这不工作.显然,Android改变了在KitKat版本中管理SMS模块的方式.根据下一篇文章,只有默认的SMS应用程序可以编写和更新新的SMS内容提供程序(android.provider.Telephony.Sms.Sent – 以前的内容:// sms / sent也不可用):

> http://android-developers.blogspot.pt/2013/10/getting-your-sms-apps-ready-for-kitkat.html

考虑到这个应用程序的行为,把默认的短信应用程序变成没有意义.此应用程序不需要从内容提供商读取SMS消息,不应通过SmsManager.getDefault().sendTextMessage发送任何消息.它应该做的唯一的事情是在发送提供程序中写入一些消息.

您可以理解,请求用户将默认应用更改为我的,然后返回到上一个SMS应用程序,每次有必要在Sent中写入消息(这是建议在Android Developers Blogspot中的“​​备份和恢复应用程序的建议”部分).

下一篇文章揭示了一些取消隐藏选项OP_WRITE_SMS的方法

> http://www.androidpolice.com/2013/12/06/non-default-sms-apps-in-kitkat-can-still-write-to-the-sms-database-using-a-switch-in-app-ops-no-root-required/

新新200新200新200新新旗新新新新新新新新新新新旗新旗新200新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新旗新新

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);

X- 20045 X- 200 X- 200 200 X- 200 200:

解决方法

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

启用应用程序的写访问权限允许应用程序与SMS提供程序进行交互的所有标准方法,包括insert()和delete().

请注意,此类不执行API级别检查,并且仍需要WRITE_SMS权限.

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,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",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,packageName,mode);

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

使用示例

boolean canWriteSms;

if(!SmsWriteOpUtils.isWriteEnabled(getApplicationContext())) {
    canWriteSms = SmsWriteOpUtils.setWriteEnabled(getApplicationContext(),true);
}
...

注意:对于常规用户应用程序,这仅适用于API Level 19(KitKat).孔在以后的版本中修补.

原文链接:https://www.f2er.com/android/310462.html

猜你在找的Android相关文章