查找并迭代android中的所有短信/彩信

2024-01-06

首先,也是最重要的,我发现了这个answer https://stackoverflow.com/a/6446831/2415237特别有帮助。然而,这让我想知道如何找到这些信息。

我似乎不知道如何迭代收件箱中的所有消息。我当前的解决方案使用Uri.parse("content://mms-sms/conversations")其中我使用“_id”和“ct_t”。然而,尽管有 30 条消息(其中 20 条在保存对话线程中,其他则分为另外两个对话),但我似乎只能在手机中找到这三个对话。这样的说法是有道理的content://mms-sms/conversations。然而,其他提供商似乎只处理短信或彩信。有没有办法以我替换的方式迭代整个消息列表"content://mms-sms/conversations"与其他东西?

public boolean refresh() {
    final String[] proj = new String[]{"_id","ct_t"};
    cursor = cr.query(Uri.parse("content://mms-sms/conversations"),proj,null,null,null);
    if(!(cursor.moveToFirst())) {
        empty = true;
        cursor.close();
        return false;
    }
    return true;
}

我用下一个函数迭代消息

    public boolean next() {

        if(empty) {
            cursor.close();
            return false;
        }
        msgCnt = msgCnt + 1;

        Msg msg;
        String msgData = cursor.getString(cursor.getColumnIndex("ct_t"));
        if("application/cnd.wap.multipart.related".equals(msgData)) {
            msg = ParseMMS(cursor.getString(cursor.getColumnIndex("_id")));
        } else {
            msg = ParseSMS(cursor.getString(cursor.getColumnIndex("_id")));
        }


        if(!(cursor.moveToNext())) {
            empty = true;
            cursor.close();
            return false;
        }

        return true;
    }

嗯,我所问的似乎不太可能。
对于那些刚刚开始执行此类任务的人来说,建议了解如何内容提供商 http://developer.android.com/guide/topics/providers/content-provider-basics.html工作一般。添加到查询中的每个 Uri 值都会返回对特定表的访问权限。

花一些时间看看不同的电话彩信 http://developer.android.com/reference/android/provider/Telephony.MmsSms.html可以访问的表,从我的测试看来,您可以访问的唯一表正在使用"content://mms-sms/conversations作为使用"content://mms-sms"导致空游标。

这就是生活,以这种方式迭代消息并没有真正的意义,因为根据消息是短信还是彩信,提取数据的内容和方法有很大不同。分别迭代和解析 SMS 和 MMS 消息并将有趣的数据存储到同一类对象类型中,以便人们以后可以按照需要的方式进行操作,这是有意义的。

对这样的主题有用的是电话.Sms 文档 http://developer.android.com/reference/android/provider/Telephony.Sms.html。在那里人们可以找到描述 http://developer.android.com/reference/android/provider/Telephony.TextBasedSmsColumns.html列索引字段。您可以找到相同的信息电话彩信 http://developer.android.com/reference/android/provider/Telephony.Mms.html以及子表电话彩信部分 http://developer.android.com/reference/android/provider/Telephony.Mms.Part.html#SEQ,带有指向每个基本列的链接来描述信息。

话虽这么说,这是问题的解决方案How can I iterate all the SMS/MMS messages in the phone?这是对我有用的解决方案。

public class Main extends AppCompatActivity {
    //Not shown, Overrides,  button to call IterateAll();
    //implementations to follow
    IterateAll();
    public void ScanMMS();
    public void ScanSMS();
    public void ParseMMS(Msg msg);
    public Bitmap getMmsImg(String id);
    public String getMmsAddr(String id);
}

IterateAll() 只是调用两个不同的函数

IterateAll() {
    ScanMMS();
    ScanSMS();
}

ScanMMS() 将迭代content://mms表从每个彩信中提取数据。

public void ScanMMS() {
        System.out.println("==============================ScanMMS()==============================");
        //Initialize Box
        Uri uri = Uri.parse("content://mms");
        String[] proj = {"*"};
        ContentResolver cr = getContentResolver();

        Cursor c = cr.query(uri, proj, null, null, null);

        if(c.moveToFirst()) {
            do {
                /*String[] col = c.getColumnNames();
                String str = "";
                for(int i = 0; i < col.length; i++) {
                    str = str + col[i] + ": " + c.getString(i) + ", ";
                }
                System.out.println(str);*/
                //System.out.println("--------------------MMS------------------");
                Msg msg = new Msg(c.getString(c.getColumnIndex("_id")));
                msg.setThread(c.getString(c.getColumnIndex("thread_id")));
                msg.setDate(c.getString(c.getColumnIndex("date")));
                msg.setAddr(getMmsAddr(msg.getID()));


                ParseMMS(msg);
                //System.out.println(msg);
            } while (c.moveToNext());
        }

        c.close();

    }

}

可以看到,很多重要的彩信数据都在这个表中,例如消息日期、消息 ID 和线程 ID。您需要使用该消息 ID 从彩信中提取更多信息。

MMS 消息被分成更小的数据部分。每个部分都包含不同的内容,例如图像或文本部分。您必须像我下面那样迭代每个部分。

public void ParseMMS(Msg msg) {
        Uri uri = Uri.parse("content://mms/part");
        String mmsId = "mid = " + msg.getID();
        Cursor c = getContentResolver().query(uri, null, mmsId, null, null);
        while(c.moveToNext()) {
/*          String[] col = c.getColumnNames();
            String str = "";
            for(int i = 0; i < col.length; i++) {
                str = str + col[i] + ": " + c.getString(i) + ", ";
            }
            System.out.println(str);*/

            String pid = c.getString(c.getColumnIndex("_id"));
            String type = c.getString(c.getColumnIndex("ct"));
            if ("text/plain".equals(type)) {
                msg.setBody(msg.getBody() + c.getString(c.getColumnIndex("text")));
            } else if (type.contains("image")) {
                msg.setImg(getMmsImg(pid));
            }


        }
        c.close();
        return;
    }

每个部分作为中间字段,对应于之前找到的消息的 id。我们仅在 MMS 部件库中搜索该 mms id,然后迭代找到的不同部件。ct or content_type如文档中所述,描述了该部件是什么,即文本、图像等。我扫描该类型以查看如何处理该部件。如果它是纯文本,我将该文本添加到当前消息正文中(显然可以有多个文本部分,但我没有看到它,但我相信它),如果它是图像,则将图像加载到位图中。我想象位图很容易用 java 发送到我的计算机,但谁知道呢,也许只想将它作为字节数组加载。

无论如何,以下是如何从 MMS 部分获取图像数据的方法。

public Bitmap getMmsImg(String id) {
    Uri uri = Uri.parse("content://mms/part/" + id);
    InputStream in = null;
    Bitmap bitmap = null;

    try {
        in = getContentResolver().openInputStream(uri);
        bitmap = BitmapFactory.decodeStream(in);
        if(in != null)
            in.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return bitmap;
}

你知道,我不完全确定在内容解析器上打开输入流是如何真正工作的,以及它如何只给我图像而不是像所有其他数据那样,没有线索,但它似乎有效。我在寻找解决方案时从一些不同的来源偷了这个。

彩信地址不像短信地址那样直接提取,但您可以通过以下方法获取全部地址。我唯一没能做的就是找出发件人是谁。如果有人知道的话我会很高兴。

public String getMmsAddr(String id) {
        String sel = new String("msg_id=" + id);
        String uriString = MessageFormat.format("content://mms/{0}/addr", id);
        Uri uri = Uri.parse(uriString);
        Cursor c = getContentResolver().query(uri, null, sel, null, null);
        String name = "";
        while (c.moveToNext()) {
/*          String[] col = c.getColumnNames();
            String str = "";
            for(int i = 0; i < col.length; i++) {
                str = str + col[i] + ": " + c.getString(i) + ", ";
            }
            System.out.println(str);*/
            String t = c.getString(c.getColumnIndex("address"));
            if(!(t.contains("insert")))
                name = name + t + " ";
        }
        c.close();
        return name;
}

这一切只是为了彩信。好消息是短信要简单得多。

public void ScanSMS() {
        System.out.println("==============================ScanSMS()==============================");
        //Initialize Box
        Uri uri = Uri.parse("content://sms");
        String[] proj = {"*"};
        ContentResolver cr = getContentResolver();

        Cursor c = cr.query(uri,proj,null,null,null);

        if(c.moveToFirst()) {
            do {
                String[] col = c.getColumnNames();
                String str = "";
                for(int i = 0; i < col.length; i++) {
                    str = str + col[i] + ": " + c.getString(i) + ", ";
                }
                //System.out.println(str);

                System.out.println("--------------------SMS------------------");

                Msg msg = new Msg(c.getString(c.getColumnIndex("_id")));
                msg.setDate(c.getString(c.getColumnIndex("date")));
                msg.setAddr(c.getString(c.getColumnIndex("Address")));
                msg.setBody(c.getString(c.getColumnIndex("body")));
                msg.setDirection(c.getString(c.getColumnIndex("type")));
                msg.setContact(c.getString(c.getColumnIndex("person")));
                System.out.println(msg);


            } while (c.moveToNext());
        }
        c.close();
}

这是我的简单消息结构,因此任何人都可以根据需要快速编译上述代码。

import android.graphics.Bitmap;

/**
 * Created by rbenedict on 3/16/2016.
 */

//import java.util.Date;

public class Msg {
    private String id;
    private String t_id;
    private String date;
    private String dispDate;
    private String addr;
    private String contact;
    private String direction;
    private String body;
    private Bitmap img;
    private boolean bData;
    //Date vdat;

    public Msg(String ID) {
        id = ID;
        body = "";
    }

    public void setDate(String d) {
        date = d;
        dispDate = msToDate(date);
    }
    public void setThread(String d) { t_id = d; }

    public void setAddr(String a) {
        addr = a;
    }
    public void setContact(String c) {
        if (c==null) {
            contact = "Unknown";
        } else {
            contact = c;
        }
    }
    public void setDirection(String d) {
        if ("1".equals(d))
            direction = "FROM: ";
        else
            direction = "TO: ";

    }
    public void setBody(String b) {
        body = b;
    }
    public void setImg(Bitmap bm) {
        img = bm;
        if (bm != null)
            bData = true;
        else
            bData = false;
    }

    public String getDate() {
        return date;
    }
    public String getDispDate() {
        return dispDate;
    }
    public String getThread() { return t_id; }
    public String getID() { return id; }
    public String getBody() { return body; }
    public Bitmap getImg() { return img; }
    public boolean hasData() { return bData; }

    public String toString() {

        String s = id + ". " + dispDate + " - " + direction + " " + contact + " " + addr + ": "  + body;
        if (bData)
            s = s + "\nData: " + img;
        return s;
    }

    public String msToDate(String mss) {

        long time = Long.parseLong(mss,10);

        long sec = ( time / 1000 ) % 60;
        time = time / 60000;

        long min = time % 60;
        time = time / 60;

        long hour = time % 24 - 5;
        time = time / 24;

        long day = time % 365;
        time = time / 365;

        long yr = time + 1970;

        day = day - ( time / 4 );
        long mo = getMonth(day);
        day = getDay(day);

        mss = String.valueOf(yr) + "/" + String.valueOf(mo) + "/" + String.valueOf(day) + " " + String.valueOf(hour) + ":" + String.valueOf(min) + ":" + String.valueOf(sec);

        return mss;
    }
    public long getMonth(long day) {
        long[] calendar = {31,28,31,30,31,30,31,31,30,31,30,31};
        for(int i = 0; i < 12; i++) {
            if(day < calendar[i]) {
                return i + 1;
            } else {
                day = day - calendar[i];
            }
        }
        return 1;
    }
    public long getDay(long day) {
        long[] calendar = {31,28,31,30,31,30,31,31,30,31,30,31};
        for(int i = 0; i < 12; i++) {
            if(day < calendar[i]) {
                return day;
            } else {
                day = day - calendar[i];
            }
        }
        return day;
    }



}

关于此解决方案的一些最终评论和注释。

person 字段似乎始终为 NULL,稍后我计划实现联系人查找。我也无法识别是谁发送了彩信。

我对java不是很熟悉,而且我还在学习它。我确信有一个数据容器(ArrayList)(向量?)可以容纳用户定义的对象。如果可以按对象(日期)中的特定字段进行排序,则可以迭代该列表并按时间顺序排列所有消息:彩信/短信以及发送/接收的消息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

查找并迭代android中的所有短信/彩信 的相关文章

  • 计算Android设备的PPI

    如何计算 Android 设备的 PPI 最特别的是 Android 平板电脑 请注意 我想计算设备的 PPI 而不是 DPI 就像一二三一样简单 让我们来计算一下PPI to Nexus 5 例如 float LCD Diagonal 4
  • 如何获取之前的碎片?

    为了在我的应用程序中重用某些片段 我需要知道哪个片段是返回堆栈上的第二个片段 为了做到这一点 我正在使用getFragmentManager getFragments 显示以下错误 但有效 FragmentManager getFragme
  • Android 在打开应用程序时会广播吗?

    例如 如果我想知道Youtube何时打开 是否有与之相关的广播 我当然知道我可以轮询 logcat 消息来检查活动 但我可以通过广播来做到这一点吗 因为它会少得多的耗电 此链接似乎表明这是不可能的 如何跟踪 Android 中的应用程序使用
  • Twitter 登录说明

    我想在 Android 中创建一个 Twitter 应用程序 为此 我想创建一个登录页面并登录到 Twitter 为此 我们需要消费者密钥和消费者密钥 这是什么意思 要创建此登录页面 除了 Twitter 帐户之外 我们还需要其他任何东西吗
  • Manifest Merger工具:替换失败

    我正在使用一个使用自己的 android theme 的库 因此在构建时收到以下错误 错误 55 9 任务 contacit processDebugManifest 执行失败 清单合并失败 AndroidManifest xml 中的属性
  • 自定义选择器活动:SecurityException UID n 无权 content:// uri

    我正在构建一个选择器应用程序来替换本机 Android 共享对话框 它工作正常 除非我尝试通过长按图像 gt 共享图像从 Chrome 共享图像 我发现 Google 没有捕获异常 它崩溃了 所以我可以通过 Logcat 查看它 在 Goo
  • Service 和 IntentService,运行从服务器轮询数据库值的服务哪个更好?

    我读过很多关于Service and IntentService 然而 当做出决定时 我没有足够的信心选择使用哪种类型来创建一个后台服务 该服务将在一定时间间隔内从数据库轮询数据 并在获得所需数据时停止它 因为数据代表请求的状态 例如 订购
  • 从 Android 代码设置的 SECRET_CODE

    我知道如何使用清单文件中的秘密代码 它与此源代码配合良好
  • 安卓定位不准确

    我正在尝试获取当前用户的位置 我试图重构我的代码以获得更好的结果 但我只是不断得到关于准确度的荒谬位置 它在 900 600 米之间 如何才能得到更好的结果 使其精度达到50m以内 这是我的代码 package com agam mapsl
  • Android 如何更改 OnTouchListener 上的按钮背景

    你好 我在 xml 中有一个按钮 我正在使用OnTouchListener在我的活动中获得button按下并释放 但问题是 当我按下按钮时背景颜色没有改变 当我延长可能的活动时OnClickListener背景正在改变 任何人都可以告诉我的
  • 如何在android线性布局上获得阴影? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在android中为View设置阴影 https stackoverflow com questions 4406524 how to set shadow to a view in androi
  • glTexImage2D: 之前出错:( 0x506 内部 0x1908 格式 0x1908 类型 0x1401

    当使用 Android Studio 运行模拟器时 我在模拟器屏幕上看不到任何内容 一切都是黑色的 我得到以下事件日志 模拟器 glTexImage2D 出错了 0x506 内部 0x1908 格式 0x1908 类型 0x1401 我已经
  • Android Studio:未找到 Gradle DSL 方法:“classpath()”

    首先 我已阅读所有其他解决方案帖子以及有关迁移到 1 0 的官方文档 到目前为止 还没有任何效果 Error Error 23 0 Gradle DSL method not found classpath Possible causes
  • PhoneStateListener 不调用

    这是我的完整代码 广播示例 java package com example broadcast gt import android app Activity import gt android content Context import
  • HERE 地图:更改路线已行驶部分的颜色

    导航时可以改变路线的颜色吗 具体来说 我希望路线中已行驶的部分的颜色与即将行驶的部分的颜色不同 现在都是同一个颜色 将 MapRoute 对象的 TravelColor 变量设置为透明对我来说很有效 mapRoute color Resou
  • 如何修改 Skobbler 注释而不重新添加它

    我必须修改 SKAnnotation 的图像 注释生成器代码 private SKAnnotation getAnnotationFromView int id int minZoomLvl View view SKAnnotation a
  • 按钮 - 单击时更改背景颜色

    我的活动中有 8 个按钮 我正在寻找的是 按钮具有默认背景 单击按钮时 背景颜色应更改为其他颜色 这部分非常简单 但是 当我单击任何其他按钮时 第一个按钮的背景颜色应该变回默认颜色 我知道这将使用 选择器状态 来完成 但我不太确定如何实现它
  • Android:RecyclerView 不显示片段中的列表项

    有人可以帮我尝试让我的 RecyclerView 出现吗 如果我不在片段中实现它 就会出现这种情况 然而 当我尝试将其实现到片段中时 CarFront 中的其他 XML 代码与 RecyclerView 分开显示 我的日志中收到此错误 E
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • Android 材料芯片组件崩溃应用程序。无法膨胀 xml

    Tried Chip来自两个支持库的组件 com google android support design 28 0 0 rc01和材料 com google android material material 1 0 0 rc01 堆栈

随机推荐

  • 以这种方式传递参数意味着什么?

    我正在学习 javascript 我看到了我不理解的这段代码 exports configure expressapp null userdb null path myroute gt handle routes 我对传入参数的结构以及内部
  • NavigationBar setShadowImage 并不总是有效

    我试图在表格视图中为导航栏设置自定义阴影图像 但它仅显示在某些视图中 我创建了一个超类来设置表视图的样式 void viewDidLoad super viewDidLoad Set navigation bar background se
  • 在 TensorFlowdynamic_rnn 中使用sequence_length参数时如何处理填充

    我正在尝试使用dynamic rnnTensorflow 中的函数可加快训练速度 经过一些阅读后 我的理解是加速训练的一种方法是显式地将值传递给sequence length该函数中的参数 经过更多阅读后 发现this https stac
  • 如何在 Android Kitkat 中设置默认短信应用程序?

    我制作了一个 Android 短信应用程序 在其中我可以像 Android 消息应用程序一样发送和接收短信 现在我已将目标设置为 4 4 Android KitKat 版本 但 Android KitKat 具有新的 默认消息传递 应用程序
  • 如何在python中发出post请求

    这是卷曲命令 curl H X API TOKEN
  • Boost Log 的琐碎记录器的“惰性求值”是如何工作的?

    跟进明确检查 boost log 过滤器 https stackoverflow com a 50345102 9305398 以下示例使用来自的简单记录器升压日志 https www boost org doc libs master l
  • 如何从 int 转换为 char*?

    我知道的唯一方法是 include
  • 将 JSON 文件导入 Windows 10 上的 Postgresql 11

    我有一个 JSON 文件 C sensors 201802091904 json 该数据文件与 PostgreSQL 安装位于同一本地驱动器上 以下是 JSON 的示例 Data collection of property value p
  • 在 Blackberry Playbook 模拟器中打开 .bar 文件

    您好 我有一个早期版本的 Playbook 应用程序 是我们的一位开发人员在 Flash Builder 中为我们制作的 它是一个 bar 文件 我已经安装了所有必需的 Abode 和 RIM SDK 密钥和模拟器 并且可以在 Flash
  • 如何创建从其他几个组件继承的Delphi组件?

    我发现有关如何创建 delphi 组件的教程很好 但它们只使用现有组件之一作为继承操作的对象 像这样的东西 unit CountBtn interface uses Windows Messages SysUtils Classes Gra
  • 重命名属性名称并更改多个对象的值

    在下面的对象中 我想更改属性名称 thumb to thumbnail 我还想更改的值title包括 span tags 这是我的对象 var data thumb images 01 png title My title thumb im
  • 带键的数组的 Twig for 循环

    我使用 Twig 并且有一个带有如下键的数组 array 1 alpha array 2 bravo array 3 charlie array 8 delta array 9 echo 我想拿到钥匙 1 2 3 8 9 和内容 alpha
  • 无效操作异常

    我创建了一个 WCF 服务 在 IIS 上托管时运行良好 现在 我采用了相同的服务 并在 WPF 中创建了一个主机应用程序 当尝试从该应用程序启动该服务时 出现以下异常 The HttpGetEnabled property of Serv
  • 与 KeyValuePair 键上的列表相交?

    如何根据键插入两个键值对列表 我努力了 List
  • jQuery UI Accordion - 如何完全删除样式?

    我喜欢 jQuery 手风琴 http jqueryui com demos accordion 的功能 但是我不想要这种风格 我想摆脱所有的样式 img 边框 颜色等 我没有看到这个选项 这是他们应该添加的内容 还是我误会了 您可以制作自
  • linux下c语言蓝牙编程

    我正在尝试在 linux ubuntu 中运行基本的 c 代码来搜索蓝牙设备 但我遇到了一些问题 通过使用命令sudo apt get install bluez 要安装所需的blueZ库 说明bluez已经是最新版本了 但出现错误 无法找
  • PHP 正则表达式查找自定义添加的 HTML 标签之间的文本

    我有以下场景 Got an HTML模板将用于的文件mailing 这是一个简化的示例 table tr td Heading 1 td td heading 2 td tr table
  • http.sys 实现

    我们都知道有一个名为 http sys 的二进制文件内核模式驱动程序在我们的 Windows 中 它为我们进行 HTTP 处理 这基本上就是我们所知道的一切 但今天我想 嘿 我们所有的网络东西 比如 TCP IP 之类的东西都在这里 在用户
  • 有充分的理由不使用 ORM 吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 查找并迭代android中的所有短信/彩信

    首先 也是最重要的 我发现了这个answer https stackoverflow com a 6446831 2415237特别有帮助 然而 这让我想知道如何找到这些信息 我似乎不知道如何迭代收件箱中的所有消息 我当前的解决方案使用Ur