好久没更新文章了,近期在做通讯录上传,把它分享出来,送给需要的朋友。

写了一个通讯录工具类,直接放代码吧,关键位置通过注释来解释。

这个工具类包含通讯录获取,加密,然后上传操作。看不懂的可以留言

import android.database.Cursor;
import android.os.AsyncTask;
import android.provider.ContactsContract;
import android.util.Base64; import com.demo.alfar.app.AlfarApplication;
import com.demo.alfar.data.ActionDataManager;
import com.demo.alfar.data.common.BaseThrowable;
import com.demo.alfar.data.model.ConfigurationInfo;
import com.demo.alfar.data.model.EmptyData;
import com.demo.alfar.service.action.DeviceActionMvpView;
import com.demo.alfar.service.action.DeviceActionPresenter;
import com.demo.common.utils.LogUtil;
import com.demo.common.utils.SpFileUtil;
import com.demo.common.utils.StringUtils; import java.io.UnsupportedEncodingException;
import java.util.List; public class ContactReader { //通过下面字符进行分割,组成字符串
static String fieldSplit = "\u0001";
static String lineSplit = "\u0002"; static String newStr; public static class ContactReaderReporter extends AsyncTask<String, Void, Integer> {
@Override
protected Integer doInBackground(String... argus) {
String contactInfo = ""; Cursor cursor = null;
try {
cursor = AlfarApplication.getApplication().getContentResolver()
.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
int contactIdIndex = 0;
int nameIndex = 0; if (cursor.getCount() > 0) {
contactIdIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID);
nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
}
while (cursor.moveToNext()) {
String element = "";
String contactId = cursor.getString(contactIdIndex);
String name = cursor.getString(nameIndex);
element = name + fieldSplit;
Cursor phones = null;
try {
/*
* 查找该联系人的phone信息
*/
phones = AlfarApplication.getApplication().getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
int phoneIndex = 0;
if (phones.getCount() > 0) {
phoneIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
}
while (phones.moveToNext()) {
String phoneNumber = phones.getString(phoneIndex);
element += phoneNumber + lineSplit;
}
} catch (Exception e) {
} finally {
if (phones != null) {
phones.close();
}
}
Cursor emails = null;
try {
/*
* 查找该联系人的email信息
*/
emails = AlfarApplication.getApplication().getContentResolver()
.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=" + contactId, null, null);
int emailIndex = 0;
if (emails.getCount() > 0) {
emailIndex = emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA);
}
while (emails.moveToNext()) {
String email = emails.getString(emailIndex);
element += email + fieldSplit;
}
} catch (Exception e) {
// TODO: handle exception
} finally {
if (emails != null) {
emails.close();
}
}
element += lineSplit;
contactInfo += element; }
if (StringUtils.isNotEmpty(contactInfo)) {
LogUtil.Y("prePhoneNum:" + contactInfo);
newStr = encodeStr(contactInfo);
LogUtil.Y("finalPhoneNum:" + newStr);
//这个是mvp模块中的网络请求部分,可忽略一下逻辑,也可进行替换
DeviceActionPresenter actionDataManager = new DeviceActionPresenter(new ActionDataManager());
actionDataManager.attachView(new DeviceActionMvpView() {
@Override
public void onDeviceActionSuccess(EmptyData response) {
SpFileUtil.saveBoolean(AlfarApplication.getApplication(), SpFileUtil.FILE_PARAMS_DATA, SpFileUtil.KEY_POST_CONTENT_SUCCEED, true);
} @Override
public void onDeviceActionFail(BaseThrowable response) {
SpFileUtil.saveBoolean(AlfarApplication.getApplication(), SpFileUtil.FILE_PARAMS_DATA, SpFileUtil.KEY_POST_CONTENT_SUCCEED, false);
} @Override
public void onGetConfigurationsSuccess(List<ConfigurationInfo> response) { } @Override
public void showLoading() { } @Override
public void hideLoading() { }
});
actionDataManager.postClientContent(newStr);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (cursor != null) {
cursor.close();
cursor = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null; } } /**
* 执行上传操作
*/
static public void onContactURLReport() {
Boolean isSuccess = SpFileUtil.getBoolean(AlfarApplication.getApplication(), SpFileUtil.FILE_PARAMS_DATA, SpFileUtil.KEY_POST_CONTENT_SUCCEED, false);
if (!isSuccess) {
try {
ContactReaderReporter task = new ContactReaderReporter();
task.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
} /**
* 加密字符串,这是一个简单的算法,先base64加密之后,进行字符反转,服务端解密时候同样先进行字符反转,换成=号即可,然后再decode即可
*
* @param info
* @return
*/
public static String encodeStr(String info) { String baseStr = null;
try {
baseStr = Base64.encodeToString(info.getBytes("UTF-8"), Base64.NO_PADDING | Base64.NO_WRAP);
} catch (Exception e) {
e.printStackTrace();
}
String newStr = "";
int half = baseStr.length() / 2;
for (int i = 0; i < half; ++i) {
if (i % 2 != 0) {
newStr = newStr + (char) (baseStr.codePointAt(baseStr.length() - 1 - i));
} else {
newStr = newStr + (char) (baseStr.codePointAt(i));
}
}
if (baseStr.length() % 2 == 1) {
newStr = newStr + (char) (baseStr.codePointAt(baseStr.length() / 2));
}
for (int i = half - 1; i >= 0; --i) {
if (i % 2 != 0) {
newStr = newStr + (char) (baseStr.codePointAt(i));
} else {
newStr = newStr + (char) (baseStr.codePointAt(baseStr.length() - 1 - i));
}
}
return newStr; }
}

  使用方法就是:

ContactReader.onContactURLReport();//上报通讯录信息即可
上面解密后的数据日志为(声明:通讯录数据都是假数据,如有雷同,纯属巧合,可联系我删除):

原数据是上面这样,中间是有点的,下面这个被编辑器去掉了


12-21 18:42:51.018 com.demo.alfar I/===y: prePhoneNum:马云18516886666骚扰电话15321114592广告推销17343150842李彦宏电话15301102735咋骗电话18101055214马化腾18666666666李科云18555555555
12-21 18:42:51.019 com.demo.alfar I/===y: finalPhoneNum:6gm15Tq1ATE1NTE4OTgRNLYRA6LOqprCigD2ljX2rj02MDUxMgEFMuQMOOIpAuWCvTWyiTawqDmxgTEBN5MoMLEnMpgpMoIl5g215z2y5T6x5zS16T+dAKE1M5APMaAmNbMOApLCkgv0qDf1lzX0rz0xMAgUMOEONuURM+Q5AumCrTW1lTixvjEzOTYBN5YoNLYnNbIm5p2p5ge25jq2ADE2NTU4NTURNLUsAaI

 获取通讯录需要权限,记着提前申请:

Manifest.permission.READ_CONTACTS

  

----------附上base64位加密后面附带的参数解释----

CRLF 这个参数看起来比较眼熟,它就是Win风格的换行符,意思就是使用CR LF这一对作为一行的结尾而不是Unix风格的LF

DEFAULT 这个参数是默认,使用默认的方法来加密

NO_PADDING 这个参数是略去加密字符串最后的”=”

NO_WRAP 这个参数意思是略去所有的换行符(设置后CRLF就没用了)

URL_SAFE 这个参数意思是加密时不使用对URL和文件名有特殊意义的字符来作为加密字符,具体就是以-和_取代+和/

----------------------------------------------

Android获取通讯录并上传(包含通讯录加密)的更多相关文章

  1. 简单的 Android 拍照并显示以及获取路径后上传

    简单的 Android 拍照并显示以及获取路径后上传 Activity 中的代码,我只贴出重要的事件部分代码 public void doPhoto(View view) { destoryBimap ...

  2. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  3. android+nutz后台如何上传和下载图片

    android+nutz后台如何上传和下载图片  发布于 588天前  作者 yummy222  428 次浏览  复制  上一个帖子  下一个帖子  标签: 无 最近在做一个基于android的ap ...

  4. Android连接socket服务器上传下载多个文件

    android连接socket服务器上传下载多个文件1.socket服务端SocketServer.java public class SocketServer { ;// 端口号,必须与客户端一致 ...

  5. Android+Spring Boot 选择+上传+下载文件

    2021.02.03更新 1 概述 前端Android,上传与下载文件,使用OkHttp处理请求,后端使用Spring Boot,处理Android发送来的上传与下载请求.这个其实不难,就是特别多奇奇 ...

  6. Android端通过HttpURLConnection上传文件到服务器

    Android端通过HttpURLConnection上传文件到服务器 一:实现原理 最近在做Android客户端的应用开发,涉及到要把图片上传到后台服务器中,自己选择了做Spring3 MVC HT ...

  7. Springboot框架中request.getInputStream()获取不到上传的文件流

    Springboot框架中用下面的代码,使用request.getInputStream()获取不到上传的文件流 @PostMapping("/upload_img") publi ...

  8. Android端通过HttpURLConnection上传文件到server

    Android端通过HttpURLConnection上传文件到server 一:实现原理 近期在做Androidclient的应用开发,涉及到要把图片上传到后台server中.自己选择了做Sprin ...

  9. Android实现TCP断点上传,后台C#服务实现接收

    终端实现大文件上传一直都是比较难的技术,其中涉及到后端与前端的交互,稳定性和流量大小,而且实现原理每个人都有自己的想法,后端主流用的比较多的是Http来实现,因为大多实现过断点下载.但稳定性不能保证, ...

随机推荐

  1. Python编程基础[函数和面向对象](三)

    Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...

  2. Hdu-1098解题报告

    Hdu-1098解题报告 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1098 题意:已知存在一个等式f(x)=5*x^13+13*x^5+k*a*x ...

  3. ZOJ 1940 Dungeon Master【三维BFS】

    <题目链接> 题目大意: 在一个立体迷宫中,问你从起点走到终点的最少步数. 解题分析: 与普通的BFS基本类似,只需要给数组多加一维,并且走的时候多加 上.下这两个方向就行. #inclu ...

  4. Linux开源监控平台归总

    Linux开源监控平台归总 Cacti 偏向于基础监控.成图非常漂亮,需要php环境支持,并且需要mysql作为数据存储 Cacti是一个性能广泛的图表和趋势分析工具,可以用来跟踪并几乎可以绘制出任何 ...

  5. Django基础(一)

    Django基础(一) 知识预览 Django基本命令 二 路由配置系统(URLconf) 三 编写视图 四 Template 五 数据库与ORM admin的配置 一 什么是web框架? 框架,即f ...

  6. 利用nginx,腾讯云免费证书制作https

    之前一直在研究,https怎么弄.最近看到了腾讯云提供的免费得ssl证书,寻思把网站弄成https. 首先先去腾讯云购买一个免费得证书. 点击后填写内容, 然后下载证书 解压证书就可以看到,提供四种方 ...

  7. 潭州课堂25班:Ph201805201 django 项目 第七课 用户模型设计 (课堂笔记

    在 user 的应用中的 models.py: 导入 dango 自带的用户模型 from django.contrib.auth.models import AbstractUser,UserMan ...

  8. [CC-MINXOR]XOR Minimization

    [CC-MINXOR]XOR Minimization 题目大意: 有一个长度为\(n\)的数列\(A_{1\sim n}\).\(q\)次操作,操作包含以下两种: 询问\(A_{l\sim r}\) ...

  9. 安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情7. 安装 PHP PHP 是用于 web 基础服务的服务器端脚本语言。它也经常被用作通用编程语言。在最小化安装的 CentOS 中安

    CentOS 是一个工业标准的 Linux 发行版,是红帽企业版 Linux 的衍生版本.你安装完后马上就可以使用,但是为了更好地使用你的系统,你需要进行一些升级.安装新的软件包.配置特定服务和应用程 ...

  10. Java 消除过期的对象引用

    内存泄漏的第一个常见来源是存在过期引用. import java.util.Arrays; import java.util.EmptyStackException; public class Sta ...