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

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

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

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 {

@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 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获取用户通讯录上传,Android获取通讯录并上传(包含通讯录加密)(示例代码)...相关推荐

  1. vue/js如何精准获取用户当前地理位置,精准获取经纬度、精准地图选点,Android定位偏移问题解决

    前言: 当时h5页面使用腾讯地图.百度地图.高德地图等获取用户当前地理位置坐标,均有偏移,偏移好几公里,无法获取精准经纬度.最后调用了微信jssdk的方法,才获取了精准的经纬度. 二.具体步骤 1.调 ...

  2. android 按键用户点击事件,Android按键事件处理过程详解

    Android按键事件处理过程详解 (2013-09-26 14:05:19) 标签: it 在Android系统中,存在多种界面事件,如点击事件.触摸事件.焦点事件和菜单事件等,在这些界面事件发生时 ...

  3. 从微信服务器获取用户信息,微信小程序Ⅴ [获取登陆用户信息,重点openID(详解)]...

    ♩ 背景 其实这篇文章几个月前就写完了,可是这段时间,微信小程序官方文档有了更新,同事在我本身的实际操做过程当中,发现以前写的过于繁杂,因此如今进行简化梳理,欢迎指摘. 语言框架:ThinkPHP3. ...

  4. php微信小程序获取用户信息,微信小程序获取openid及用户信息的方法

    本文主要介绍微信小程序如何获取openid及用户信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家. 1. 获取openid 1.1 获取code 调用接口获取登录凭证(code ...

  5. tp5微信公众号获取用户openid_tp5+微信公众号获取用户基本信息

    获取用户基本信息(UnionID机制) 获取用户基本信息(UnionID机制) 在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯 ...

  6. html怎样获取用户手机号码,小程序如何获取用户手机号?

    在小程序获客过程中,我们有非常多的应用场景希望获取当前访客的手机号,通过小程序提供的这一便利功能,可以大大增强我们的营销效果. 在小程序中,获取手机号有下面两种方式: 一.用户进入首页(或某一页面), ...

  7. 小程序获取用户头像大图 小程序获取用户头像模糊的问题 小程序自定义转发头像模糊 小程序自定义转发分享大图...

    在开发小程序的时候,大家肯定有做过自定义转发分享图片的.我们现在做了一个名片小程序,需要做的一个功能就是,用户在转发分享自己的名片,在微信里显示的小程序缩略图,我们使用的是用户的微信头像,但是发现一个 ...

  8. android 圆形相机预览拍照_Android多种方式实现相机圆形预览的示例代码

    效果图如下: 一.为预览控件设置圆角 public RoundTextureView(Context context, AttributeSet attrs) { super(context, att ...

  9. android html5 加密,android studio MD5加密 示例代码

    md5加密法核心源码 package com.study.luoki; import android.app.*; import android.os.*; import android.widget ...

  10. android获取通知栏消息源代码,Android高仿UC浏览器和360手机卫士消息常驻栏(通知栏)(示例代码)...

    之前网上看了下自己定义消息栏,通知栏,了解到了Notification这个控件.发现UC浏览器等都是这样的类型,今天写个demo实现下.如图: 当中每一个button都有不同的功能.代码例如以下: p ...

最新文章

  1. 简述vi编辑器的启动\退出\保存文件
  2. shell中数组基础语法
  3. Chrome原生工具实现长截图
  4. php+条件限定符,const 限定符
  5. java 分治法排序_分治法实现1-N的数字按字典序全排列组合 Java语言
  6. android wine教程_技术|如何在 Android 上借助 Wine 来运行 Windows Apps
  7. Java代码发送post请求工具类
  8. 五一快乐假期每天都在上课qaq
  9. 欧拉环游和中国邮递员问题
  10. 数据库使用SHADOW系统实现高可用性
  11. oracle数据文件recover,又遇BUG-ORA-01148:数据文件忽然变为recover状态
  12. 把时间当作朋友 读书笔记
  13. bundle包是什么意思_bundle与package区别与联系
  14. Oasis montaj无法计算均衡重力异常
  15. 70句计算机英语,爱英优选:70句成人英语日常口语大全
  16. Anaconda4.5.1+tensorflow2.1.0+keras2.3.1+theano+Mingw+python3.6安装总结
  17. 按字节编址,一字节等于多少比特?
  18. 2020华数杯数学建模C题脱贫帮扶绩效评价求解全过程文档及程序
  19. mock.js+vue的简单使用
  20. 炎炎夏日打造一个属于自己的“便携小空调”吧

热门文章

  1. SQL数据库的导入和导出
  2. cmd用管理员权限连接远程桌面命令
  3. Linux是实时系统还是分时操作系统?
  4. SAS9.4安装简易教程(保姆级)附带报错处理
  5. VC6.0下载和安装教程
  6. 华为交换机配置时区_把华为交换机设置成时钟源服务器(NTP)
  7. 最新python大数据毕业设计选题推荐(三)
  8. BPA仿真软件需要购买吗,BPA电力仿真软件教程
  9. html 好看的英文字体,23款网页设计师必备:经典私藏英文字体
  10. 何钦铭c语言程序设计第三版课本,C语言程序设计(第3版)