查找并迭代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中的所有短信/彩信 的相关文章

  • PhoneGap/Cordova 应用程序通知

    我是 PhoneGap Cordova 的新手 我希望向我的应用程序添加一些通知 推送通知 因此当应用程序上发布新文章时 它会提醒用户 本地通知 在设定的时间间隔 日期和时间 我可以提示用户我的应用程序上的最新文章 我进行了大量搜索 但找不
  • socket.io xhr 在连接缓慢时出现错误(3G 移动网络)

    当我在 3G 移动网络 互联网连接速度慢 上测试我的真实聊天应用程序时 Socket io反复断开然后重新连接 我已经记录了原因 它说 xhr post error 这提高了 transport error 然后断开连接 我可以知道什么意思
  • 当满足条件时,如何以编程方式更改 ImageButton src 目标?

    我有一个学校项目 我正在尝试开发一个手电筒应用程序 对于开 关 ImageButton 我想要 4 个自定义图像 如果手电筒关闭 turn on png 默认 turn on pressing png 按下状态 true 如果手电筒打开 t
  • 改造中的多个队列导致内存不足错误?

    我正在使用retrofit2 做我的项目 当我的呼叫失败时 我再次重复相同的呼叫 重复此 呼叫使我的应用程序强制关闭 当我查看日志时 我得到了错误日志 如下所示 我觉得这是由于同一呼叫的多次排队造成的 所以我在排队之前就这样做了 我打电话给
  • 覆盖 Android 中的电源按钮

    我正在开发一个应用程序 其中我需要在按下电源按钮时执行一个操作 但不幸的是我无法处理按下电源按钮时的操作 我尝试使用 onKeyDown 和dispatchKeyEvent 方法 但似乎没有任何效果 任何人都可以建议我解决这个问题的任何其他
  • 退出设备上的 system.img

    我正在为我们部署给客户的设备 LG p509 Optimus 1 开发自动应用程序更新解决方案 我们可以控制这些设备 并且目前在它们上安装自定义内核 但不是完整的自定义 ROM 由于我们试图在设备上自动更新我们的应用程序 因此我们需要由我们
  • ExpandableListview OnGroupClickListener 未触发

    我正在关注这个 以编程方式折叠 ExpandableListView 中的组 https stackoverflow com questions 4314777 programmatically collapse a group in ex
  • 将 java 中的 byte[] 转换为 C++ 中的 unsigned char* 的正确方法,反之亦然?

    我是 C 和 JNI 的新手 我尝试找到一种正确的方法 通过使用 JNI 将 java 中的 byte 转换为 C 中的 unsigned char 反之亦然 我正在安卓上工作 在谷歌和SO中寻找解决方案后 我还没有找到将java中的byt
  • MIUI 权限被拒绝活动 KeyguardLocked

    当应用程序处于后台且屏幕被锁定时 我无法启动活动 没有异常或警告 只是不调用 onCreate 我一直在与这个问题作斗争 我想我终于找到了它的根源 日志中有一行 D com android server am ExtraActivityMa
  • 是否可以通过 Android 应用程序来录音?

    我是一名开发人员 希望创建一个 Android 应用程序来记录电话 这是出于我个人的需要 为了我自己的目的和记录而记录电话 是否有可能做到这一点 是否可以访问麦克风以及通过扬声器发出的声音 我对 Android 开发有点陌生 所以请耐心等待
  • 当 minifyEnabled 为 true 时 Android 应用程序崩溃

    我正在使用多模块应用程序 并且该应用程序崩溃时minifyEnabled true in the installed模块的build gradle 以下是从游戏控制台检索到的反混淆堆栈跟踪 FATAL EXCEPTION Controlle
  • 如何通过 Android 按钮单击运行单独的应用程序

    我尝试在 Android 应用程序中添加两个按钮 以从单独的两个应用程序订单系统和库存系统中选择一个应用程序 如图所示 我已将这两个应用程序实现为两个单独的 Android 项目 当我尝试运行此应用程序时 它会出现直到正确选择窗口 但是当按
  • 无法使用 findViewById() 找到视图

    我找不到TextView通过致电findViewById 即使 ID 确实存在 OtherActivity public class OtherActivity extends Activity Override protected voi
  • Android SearchView 在启动时隐藏键盘

    我有一个小问题正在尝试解决 当我打开应用程序时 键盘会显示输入搜索视图的查询 不过 我只想在单击搜索视图时显示键盘 我该如何解决 Thanks 这对我有用 用于隐藏焦点的代码 searchView SearchView view findV
  • Android:GestureDetector 无法与选项卡(TabActivity、Tabwidget)一起工作(gestureDetector.onTouchEvent(event) 始终为 false)

    我已经用不同的子活动实现了 TabActivity intent new Intent setClass this MyChildTabActiviy class Initialize a TabSpec for each tab and
  • 如何在android中通过蓝牙向配对设备发送短信?

    在我的应用程序中 我想通过蓝牙发送和接收短信 我可以在列表视图中看到配对设备名称和地址的列表 但是当我尝试向配对设备发送文本时 什么也没有发生 在其他设备中没有收到文本 这是我向配对设备发送消息的代码 private void sendDa
  • fs-extra:源和目标不能相同。 (科尔多瓦)

    我在使用 cordova 构建时遇到错误 Error Source and destination must not be the same 构建系统 Ionic ionic cli 4 10 1 ionic framework ionic
  • Android-dispatchTouchEvent 给了我一个 StackOverflowError

    这里我有一个带有 setOnTouchListener 的 ViewFlipper 它工作得很好 然后我膨胀 ReLayNewsItem 然后将其添加到 ViewFlipper 现在我希望 WebView web 监听触摸事件并将它们传递给
  • 丢失应用程序的密钥库文件(但已启用 Google Play 应用程序签名)

    我已经失去了原来的keystore用于签署我的应用程序的文件 我的应用启用了 Google Play 应用签名 如果我联系 Google 支持人员 是否可以重置密钥 以便我可以继续上传到此包 我希望我可以做到这一点 因为应用程序签名已启用
  • 将对象从手机共享到 Android Wear

    我创建了一个应用程序 在此应用程序中 您拥有包含 2 个字符串 姓名和年龄 和一个位图 头像 的对象 所有内容都保存到 sqlite 数据库中 现在我希望可以在我的智能手表上访问这些对象 所以我想实现的是你可以去启动 启动应用程序并向左和向

随机推荐

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

    我正在学习 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