Android 读取、接收、发送 手机短信

:https://www.cnblogs.com/ycclmy/tag/android/

1、Android 读取手机短信

From:https://www.cnblogs.com/ycclmy/p/3193075.html

获取 android 手机短信需要在 AndroidManifest.xml 加权限:

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

获取短信只需要得到 ContentResolver 就行了,它的 URI 主要有:

content://sms/          所有短信
content://sms/inbox     收件箱
content://sms/sent      已发送
content://sms/draft     草稿
content://sms/outbox    发件箱
content://sms/failed    发送失败
content://sms/queued    待发送列表

SMS 数据库中的字段如下:

_id        一个自增字段,从1开始
thread_id  序号,同一发信人的id相同
address    发件人手机号码
person     联系人列表里的序号,陌生人为null
date       发件日期
protocol   协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO
read       是否阅读 0未读, 1已读
status     状态 -1接收,0 complete, 64 pending, 128 failed
type       ALL = 0;INBOX = 1;SENT = 2;DRAFT = 3;OUTBOX = 4;FAILED = 5; QUEUED = 6;
body       短信内容
service_center 短信服务中心号码编号。如+8613800755500
subject        短信的主题
reply_path_present TP-Reply-Path
locked

示例代码:

package com.lmy.sms;import java.sql.Date;
import java.text.SimpleDateFormat;import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.ScrollView;
import android.widget.TextView;public class SmsReadActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView tv = new TextView(this);tv.setText(getSmsInPhone());ScrollView sv = new ScrollView(this);sv.addView(tv);setContentView(sv);}public String getSmsInPhone() {final String SMS_URI_ALL = "content://sms/"; // 所有短信final String SMS_URI_INBOX = "content://sms/inbox"; // 收件箱final String SMS_URI_SEND = "content://sms/sent"; // 已发送final String SMS_URI_DRAFT = "content://sms/draft"; // 草稿final String SMS_URI_OUTBOX = "content://sms/outbox"; // 发件箱final String SMS_URI_FAILED = "content://sms/failed"; // 发送失败final String SMS_URI_QUEUED = "content://sms/queued"; // 待发送列表StringBuilder smsBuilder = new StringBuilder();try {Uri uri = Uri.parse(SMS_URI_ALL);String[] projection = new String[] { "_id", "address", "person","body", "date", "type", };Cursor cur = getContentResolver().query(uri, projection, null,null, "date desc"); // 获取手机内部短信// 获取短信中最新的未读短信// Cursor cur = getContentResolver().query(uri, projection,// "read = ?", new String[]{"0"}, "date desc");if (cur.moveToFirst()) {int index_Address = cur.getColumnIndex("address");int index_Person = cur.getColumnIndex("person");int index_Body = cur.getColumnIndex("body");int index_Date = cur.getColumnIndex("date");int index_Type = cur.getColumnIndex("type");do {String strAddress = cur.getString(index_Address);int intPerson = cur.getInt(index_Person);String strbody = cur.getString(index_Body);long longDate = cur.getLong(index_Date);int intType = cur.getInt(index_Type);SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");Date d = new Date(longDate);String strDate = dateFormat.format(d);String strType = "";if (intType == 1) {strType = "接收";} else if (intType == 2) {strType = "发送";} else if (intType == 3) {strType = "草稿";} else if (intType == 4) {strType = "发件箱";} else if (intType == 5) {strType = "发送失败";} else if (intType == 6) {strType = "待发送列表";} else if (intType == 0) {strType = "所以短信";} else {strType = "null";}smsBuilder.append("[ ");smsBuilder.append(strAddress + ", ");smsBuilder.append(intPerson + ", ");smsBuilder.append(strbody + ", ");smsBuilder.append(strDate + ", ");smsBuilder.append(strType);smsBuilder.append(" ]\n\n");} while (cur.moveToNext());if (!cur.isClosed()) {cur.close();cur = null;}} else {smsBuilder.append("no result!");}smsBuilder.append("getSmsInPhone has executed!");} catch (SQLiteException ex) {Log.d("SQLiteException in getSmsInPhone", ex.getMessage());}return smsBuilder.toString();}
}

2、Android 接收短信

启动程序时启动一个 service,在 service 里注册接收短信的广播,当手机收到短信里,打印出短信内容跟电话号码。

package com.lmy.SmsListener;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;public class SmsListenerActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
//        setContentView(R.layout.main);TextView tv = new TextView(this);tv.setText("Hello. I started!");setContentView(tv);Intent service = new Intent(this, MyService.class);this.startService(service);}
}

当 service 被 kill 后,我们可以在开机时自动启动 service。

开机自动启动一个 service,在 service 里注册接收短信的广播,当手机收到短信里,打印出短信内容跟电话号码。

开机启动后系统会发出一个 Standard Broadcast Action,名字叫android.intent.action.BOOT_COMPLETED,这个 Action 只会发出一次。

创建一个类继承 BroadcastReceiver,在 onReceive(Context context, Intent intent) 里面启动service。

package com.lmy.SmsListener;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;public class MyBrocast extends BroadcastReceiver {static final String ACTION = "android.intent.action.BOOT_COMPLETED";@Overridepublic void onReceive(Context context, Intent intent) {Log.v("dimos", "MyBrocast");if (intent.getAction().equals(ACTION)) {Intent service = new Intent(context, MyService.class);context.startService(service);}}}

在 service 中注册一个接收短信的广播:

package com.lmy.SmsListener;import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");localIntentFilter.setPriority(2147483647);SmsRecevier localMessageReceiver = new SmsRecevier();Log.v("dimos", "MyService");registerReceiver(localMessageReceiver, localIntentFilter);}}

广播接收到短信:

package com.lmy.SmsListener;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;public class SmsRecevier extends BroadcastReceiver {public SmsRecevier() {super();Log.v("dimos", "SmsRecevier create");}@Overridepublic void onReceive(Context context, Intent intent) {String dString = SmsHelper.getSmsBody(intent);String address = SmsHelper.getSmsAddress(intent);Log.i("dimos", dString+","+address);//阻止广播继续传递,如果该receiver比系统的级别高,//那么系统就不会收到短信通知了abortBroadcast(); }
}

获得短信内容跟短信地址:

package com.lmy.SmsListener;import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;public class SmsHelper {/*** 获得短信内容* */public static String getSmsBody(Intent intent) {String tempString = "";Bundle bundle = intent.getExtras();Object messages[] = (Object[]) bundle.get("pdus");SmsMessage[] smsMessage = new SmsMessage[messages.length];for (int n = 0; n < messages.length; n++) {smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);// 短信有可能因为使用了回车而导致分为多条,所以要加起来接受tempString += smsMessage[n].getDisplayMessageBody();}return tempString;}/*** 获得短信地址* */public static String getSmsAddress(Intent intent) {Bundle bundle = intent.getExtras();Object messages[] = (Object[]) bundle.get("pdus");return SmsMessage.createFromPdu((byte[]) messages[0]).getDisplayOriginatingAddress();}
}

在 AndroidManifest.xml 里声明并加权限:

<?xml version="1.0" encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.lmy.SmsListener"android:versionCode="1"android:versionName="1.0"><uses-sdkandroid:minSdkVersion="7" /><applicationandroid:icon="@drawable/icon"android:label="@string/app_name"><activityandroid:name=".SmsListenerActivity"android:label="@string/app_name"><intent-filter><actionandroid:name="android.intent.action.MAIN" /><categoryandroid:name="android.intent.category.LAUNCHER" /></intent-filter></activity><receiverandroid:name="MyBrocast"android:enabled="true"><intent-filter><actionandroid:name="android.intent.action.BOOT_COMPLETED" /></intent-filter></receiver><service android:name="MyService"></service></application><uses-permissionandroid:name="android.permission.RECEIVE_SMS" /><!-- 接收短信权限 --><!-- 添加接收系统启动消息(用于开机启动)权限 --><uses-permissionandroid:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</manifest>

这样就可以获得接收到的短信了。

3、Android SmsManager 发送短信

SmsManager 可以在后台发送短信,无需用户操作,开发者就用这个 SmsManager 功能在后台偷偷给SP发短信,导致用户话费被扣。必须添加 android.permission.SEND_SMS 权限。

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

如果短信内容过长,可以使用 SmsManager.divideMessage(String text)方法自动拆分成一个ArrayList 数组,再根据数组长度循环发送。

用 sendMultipartTextMessage(String destinationAddress, string scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) 方法发送。参数分别为:号码,短信服务中心号码(null 即可),短信内容,短信发送结果广播PendingIntent,短信到达广播。

下面写一个 demo 查移动话费余额,贴上代码:

package com.dimos.sendmessage;import java.util.ArrayList;import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.telephony.SmsManager;public class SendMessageActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);SendReceiver receiver=new SendReceiver();IntentFilter filter=new IntentFilter();filter.addAction(SendReceiver.ACTION);registerReceiver(receiver,filter);//必须先注册广播接收器,否则接收不到发送结果SmsManager smsManager = SmsManager.getDefault();Intent intent = new Intent();intent.setAction(SendReceiver.ACTION);ArrayList<String> divideMessage = smsManager.divideMessage("ye");PendingIntent sentIntent = PendingIntent.getBroadcast(this, 1, intent,PendingIntent.FLAG_UPDATE_CURRENT);ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();sentIntents.add(sentIntent);try {smsManager.sendMultipartTextMessage("10086", null,divideMessage, sentIntents, null);} catch (Exception e) {e.printStackTrace();}}
}

接收器:

package com.dimos.sendmessage;import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;public class SendReceiver extends BroadcastReceiver {public static final String ACTION = "action.send.sms";@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (ACTION.equals(action)) {int resultCode = getResultCode();if (resultCode == Activity.RESULT_OK) {// 发送成功System.out.println("发送成功!");} else {// 发送失败System.out.println("发送失败!");}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/495135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flex和js进行参数传递

来着&#xff1a;http://www.cnblogs.com/Cnol/archive/2009/09/20/1570365.html 方法一&#xff1a;flex接收网页传值&#xff01;~ 1<?xml version"1.0" encoding"utf-8"?> 2<mx:Application xmlns:mx"http://www.adobe.com/2006/mxml&q…

师法自然,仿生技术是如何改变世界的?

来源&#xff1a;36Kr摘要&#xff1a;“向自然学习”&#xff0c;这并非是句空话。本文介绍了科学家如何借鉴大自然&#xff0c;在材料科学&#xff0c;信息技术等领域实现创新。希望能为您带来启发。当今世界最伟大的创新者&#xff0c;非大自然莫属。大自然经过45亿年的演变…

Auto.JS 开发

From&#xff1a;https://blog.csdn.net/a6892255/article/details/107302369 autojs 代码大全(实战演练)&#xff1a;https://blog.csdn.net/qq_30931547/article/details/106459765 &#xff1a;https://github.com/snailuncle/autojsCommonFunctions/blob/master/autojsCo…

【研究】大脑如何在“知道”与“无知”之间做出决定

来源&#xff1a;中国生物技术网摘要&#xff1a;我们时而会对“求知欲”如饥似渴&#xff0c;时而又会觉得“无知是福”而享受放空&#xff0c;那么问题来了&#xff0c;在特定的时间里&#xff0c;我们是如何在这两种心态之间进行选择的呢&#xff1f;英国伦敦大学学院(UCL)的…

js 逆向分析的神器 --- v_jstools

From&#xff1a;https://mp.weixin.qq.com/s/LisYhDKK_6ddF-19m1gvzg 1、下载和安装插件 这是一款浏览器插件&#xff0c;功能非常的nice 工具地址&#xff1a;https://github.com/cilame/v_jstools 浏览器打开上面的网站后&#xff0c;点击 code 按钮&#xff0c;选择 Down…

网站运营

一个站点要有对用户有用&#xff0c;比如亚马逊&#xff0c;卖书的网站多得是&#xff0c;但是亚马逊除了卖书&#xff0c;还提供了很多其他的对客户有用的东西。首先一点&#xff0c;要考虑对自己有用&#xff0c;如果对自己有用&#xff0c;那么必然会对很多其他人有用。 The…

《中国人工智能开源软件发展白皮书(2018)》(附下载及解读PPT)

来源&#xff1a;走向智能论坛摘要&#xff1a;近日&#xff0c;中国人工智能开源软件发展联盟召集中国电子技术标准化研究院等企事业单位&#xff0c;编撰并正式发布《中国人工智能开源软件发展白皮书&#xff08;2018&#xff09;》&#xff0c;白皮书研究梳理人工智能开源软…

把 charles,Fiddler 证书安装到安卓根目录,解决安卓微信 7.0 版本以后安装证书也无法抓包问题,需要 root

From&#xff1a;https://testerhome.com/topics/21956 OpenSSL &#xff1a;https://slproweb.com/products/Win32OpenSSL.html 谷歌在安卓7.0修改了安全策略&#xff0c;安卓系统 大于 7.0 时&#xff0c; 应用不在信任用户安装的证书文件。用户添加的 CA 证书不能再用于安全…

nfs配置小结

nfs服务器端配置文件&#xff1a;vim /etc/exports共享目录 允许访问主机(访问权限)/mnt/share 192.168.17.152(rw)/mnt/share *(rw)载入nfs配置信息&#xff1a;/etc/init.d/nfs reloadexportfs -a查看本地nfs共享信息&#xff1a;exportfs -v查看远程n…

科学家发现跨越生命的重要门槛或许没那么难

来源&#xff1a;中国科学报将团藻&#xff08;拥有数百个细胞的藻类&#xff09;与其相对简单的亲缘物种——单细胞衣藻&#xff08;左上&#xff09;和拥有4~16个细胞的盘藻&#xff08;右上&#xff09;作对比&#xff0c;揭示了向多细胞生命发展的步骤。数十亿年前&#xf…

windows 的 wsl 命令

​wsl 文档&#xff1a;https://docs.microsoft.com/zh-cn/windows/wsl/ From &#xff1a;https://blog.csdn.net/weixin_34101784/article/details/88729575 From &#xff1a;https://www.cnblogs.com/Flat-White/p/13501639.html 玩转 WLS&#xff1a;Windows 10 Ubuntu子系…

C++ Primer 第10章 习题10.24

//10.24.cpp //建立一个单词排除集 //用于识别以s借位、但这个结尾的s,又不能删除的单词 //使用这个排除集删除输入单词尾部的s&#xff0c;生成该单词的非复数版本 //如果输入的是排除集中的单词&#xff0c;则保持该单词不变 #include<iostream> #include<set> #…

人机工程学/人因工程学的定义

来源&#xff1a;人机与认知实验室摘要&#xff1a;人机工程学&#xff08;Human Machine Environment&#xff09;和人因工程学&#xff08;Human Factor Environment&#xff09;国际百科全书的标题表明&#xff0c;人机工程学和人因工程学可能是两个独立的学科领域。人机工程…

Google Pixel 解锁BL、刷入Twrp、magisk Root、安装 Xposed

Google Pixel 解锁 BL、刷入Twrp及Root &#xff1a;http://www.itfanr.cc/2018/10/16/google-pixel-unlock-bl-and-root/ Pixel 安装 Xposed 框架&#xff1a;https://blog.csdn.net/someby/article/details/110388712 自己动手刷 pixel 镜像&#xff08; 原生镜像、自己编译…

用户控件

1.用户控件转载于:https://www.cnblogs.com/williamwindy/archive/2012/02/29/2374797.html

全球人脸识别精度一年提高75.6%,拉动全球安防市场超高增长

来源&#xff1a;AI 科技评论摘要&#xff1a;有「工业界黄金标准」之称的美国国家标准与技术研究院&#xff08;National Institute of Standards and Technology&#xff0c;NIST&#xff09;最近公布了全球人脸识别算法测试&#xff08;FRVT&#xff09;结果 FRVT 2018&…

Android 手机的高级终端 Termux 安装、使用

From&#xff1a;https://www.sqlsec.com/2018/05/termux.html Termux 高级终端安装使用配置教程 &#xff1a;https://www.cnblogs.com/cutesnow/p/11430833.html 神器Termux 的使用记录&#xff1a;https://cloud.tencent.com/developer/article/1609398 adb shell 下使用 te…

#ifdef,#ifndef,#define,#endif解析(原)

我们在看一些开源的源代码的时候&#xff0c;经常会看到如下情景&#xff1a; # if defined(_PTHREADS) && !defined(_NOTHREADS) # define __STL_PTHREADS # endif # if defined(_UITHREADS) && !defined(_PTHREADS) && !defined(_NOTHREADS) # …

这10项创新技术正在引领零售业数字化转型

来源&#xff1a;资本实验室摘要&#xff1a;随着近几年电子商务的快速发展&#xff0c;全球实体零售业纷纷出现业绩下滑的现象&#xff0c;裁员、闭店、抛售成为一些传统零售巨头短期自救的方式&#xff0c;但这些方式却只能治标不治本&#xff0c;无法解决长期以来传统商业模…

内网穿透 --- frp、termite

​中文文档&#xff1a;https://github.com/fatedier/frp/blob/dev/README_zh.md 手机frp内网穿透搭建随身携带的服务器&#xff1a;https://blog.csdn.net/sinat_27938829/article/details/73604722 软路由 通过 Openwrt 自带的 Frp 插件&#xff1a;https://zhuanlan.zhihu.c…