Android获取通讯录并上传(包含通讯录加密)

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

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

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
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();//上报通讯录信息即可
上面解密后的数据日志为(声明:通讯录数据都是假数据,如有雷同,纯属巧合,可联系我删除):

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


1
2
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

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

1
Manifest.permission.READ_CONTACTS

  

 

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

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

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

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

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

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

 

 

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

 

posted @   Andye  阅读(3556)  评论(1编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示