package com.bytedance.ttcollector.utils; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.Settings; import android.util.Log; import android.util.Pair; import androidx.core.content.FileProvider; import com.mysql.jdbc.Statement; import com.sound.apksource.ApkSource; import com.sound.duoapks.ApkSourceBuilder; import com.sound.filedescriptor.FlexSaiPackageInstaller; import com.sound.filedescriptor.PreferencesHelper; import com.sound.filedescriptor.SaiPiSessionParams; import com.sound.shell.RootedSaiPackageInstaller; import com.yanzhenjie.andserver.util.StringUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import de.robv.android.xposed.XposedBridge; import okhttp3.FormBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class TTTask { public static Boolean _installRet; public static Boolean _paused; private static String TAG = "AFTask"; private final Context _context; private final String _appid; private final String _downloadUrl; private Connection _dbConn; private Statement _dbStat; private static boolean go = false; static { _installRet = null; _paused = false; } public TTTask(Context context, String appid, String downloadUrl) throws Throwable { _context = context; _appid = appid; _downloadUrl = downloadUrl; } /** * 获取apk文件名 * @param appid * @return * @throws Throwable */ private String apkFileName(String appid) throws Throwable{ String result = ""; String sql="SELECT ApkPath FROM apkinfo1 WHERE PackageName = '" + appid + "';"; ResultSet rs=_dbStat.executeQuery(sql); if(rs.next()){ result = rs.getString("ApkPath"); } rs.close(); return result; } /** * 下载APk * @param downloadUrl * @param fileName * @return * @throws Throwable */ private String downloadAPK(String downloadUrl, String fileName) throws Throwable { Log.d("AFTask", "downloadAPK: " + Environment.getExternalStorageState()); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ String sdPath = Environment.getExternalStorageDirectory() + "/"; String savePath = sdPath + "aftask"; File dir = new File(savePath); if (!dir.exists()){ Process process = Runtime.getRuntime().exec("su"); PrintWriter PrintWriter = new PrintWriter(process.getOutputStream()); PrintWriter.println("mkdir " + sdPath + "aftask"); PrintWriter.println("chmod 777 " + sdPath + "aftask"); PrintWriter.flush(); PrintWriter.close(); process.waitFor(); } // 下载文件 HttpURLConnection conn = (HttpURLConnection) new URL(downloadUrl + fileName).openConnection(); conn.connect(); InputStream is = conn.getInputStream(); File apkFile = new File(savePath, fileName); FileOutputStream fos = new FileOutputStream(apkFile); byte[] buffer = new byte[10240]; while (true) { int numread = is.read(buffer); if (numread < 0){ break; } fos.write(buffer, 0, numread); } fos.close(); is.close(); return apkFile.getPath(); } return ""; } private static boolean returnResult(int value){ // 代表成功 if (value == 0) { return true; } else if (value == 1) { // 失败 return false; } else { // 未知情况 return false; } } private boolean clientInstallApk(File apkFile){ PrintWriter PrintWriter = null; Process process = null; try { process = Runtime.getRuntime().exec("su"); PrintWriter = new PrintWriter(process.getOutputStream()); PrintWriter.println("chmod 777 " + apkFile); PrintWriter.println("pm install -r " + apkFile); PrintWriter.flush(); PrintWriter.close(); int value = process.waitFor(); return returnResult(value); } catch (Exception e) { e.printStackTrace(); }finally{ if(process!=null){ process.destroy(); } } return false; } private boolean clientInstallApks(File apkFile){ Uri uri = Uri.fromFile(apkFile); FlexSaiPackageInstaller mInstaller = FlexSaiPackageInstaller.getInstance(_context); PreferencesHelper mPrefsHelper = PreferencesHelper.getInstance(_context); RootedSaiPackageInstaller rootedSaiPackageInstaller = RootedSaiPackageInstaller.getInstance(_context); ApkSource apkSource = new ApkSourceBuilder(_context) .fromZipContentUri(uri) .setZipExtractionEnabled(mPrefsHelper.shouldExtractArchives()) .setReadZipViaZipFileEnabled(mPrefsHelper.shouldUseZipFileApi()) .setSigningEnabled(mPrefsHelper.shouldSignApks()) .build(); // mInstaller.enqueueSession(mInstaller.createSessionOnInstaller(mPrefsHelper.getInstaller(), new SaiPiSessionParams(apkSource))); rootedSaiPackageInstaller.enqueueSession(mInstaller.createSessionOnInstaller(mPrefsHelper.getInstaller(), new SaiPiSessionParams(apkSource))); while(_installRet == null){ try{ Thread.sleep(1000); }catch (Exception e){} } boolean result = _installRet; _installRet = null; return result; } /** * 删除APK * @param apk_file_path * @return */ private boolean deleteAPK(final String apk_file_path) { try { File f = new File(apk_file_path); return f.delete(); }catch (Throwable err){ return false; } } /** * 卸载APK * @param packageName * @return * @throws Throwable */ private boolean clientUninstall(String packageName) { PrintWriter PrintWriter = null; Process process = null; try { process = Runtime.getRuntime().exec("su"); PrintWriter = new PrintWriter(process.getOutputStream()); PrintWriter.println("pm uninstall " + packageName); PrintWriter.flush(); PrintWriter.close(); int value = process.waitFor(); return returnResult(value); } catch (Exception e) { e.printStackTrace(); }finally{ if(process!=null){ process.destroy(); } } return false; } /** * 打开APP * @param packageName * @throws Throwable */ private boolean openApp(String packageName) { try{ Global.setTargetAppName(packageName); Intent intent = _context.getPackageManager().getLaunchIntentForPackage(packageName); // if(intent != null){ // _context.startActivity(intent); // return true; // }else{ // CmdUtils.amStart(getApkMainActivity(packageName)); // return false; // } _context.startActivity(intent); }catch (Throwable e){ e.printStackTrace(); return false; } return true; } public String getApkMainActivity(String packageName) { String mainActivity = null; final PackageManager packageManager = _context.getPackageManager(); PackageInfo pi = null; try { pi = _context.getPackageManager().getPackageInfo(packageName, 0); } catch (PackageManager.NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(pi == null || pi.packageName == null){ //Toast.makeText(this, "还没安装!", 2000).show(); Log.d(TAG, "getMainActivity: " + "apk还没安装"); return null; } Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null); resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER); resolveIntent.setPackage(pi.packageName); List apps = packageManager.queryIntentActivities(resolveIntent, 0); ResolveInfo ri = apps.iterator().next(); if (ri != null) { String pkgName = ri.activityInfo.packageName; String className = ri.activityInfo.name; Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); ComponentName cn = new ComponentName(pkgName, className); Log.d(TAG, "openApp: " + cn.toString()); Log.d(TAG, "openApp: " + cn.toShortString()); Log.d(TAG, "openApp: " + cn.flattenToString()); Log.d(TAG, "openApp: " + cn.flattenToShortString()); mainActivity = cn.flattenToShortString(); // intent.setComponent(cn); // MyApplication.getContext().startActivity(intent); } return mainActivity; } /** * 拷贝日志文件 * @param packageName * @param maxSecondOfWait * @return * @throws Throwable */ private boolean copyLogFile(String packageName, long maxSecondOfWait, long minSecondOfWait) throws Throwable { long begin = System.currentTimeMillis(); Process process = Runtime.getRuntime().exec("su"); PrintWriter printWriter = new PrintWriter(process.getOutputStream()); printWriter.println("chmod 777 /data/data/" + packageName); printWriter.println("mkdir /data/data/com.bytedance.ttcollector/" + packageName); printWriter.println("chmod 777 /data/data/com.bytedance.ttcollector/" + packageName); printWriter.flush(); boolean afCopied = false, adCopied = false; while ((!afCopied || !adCopied) && (System.currentTimeMillis() - begin <= (maxSecondOfWait * 1000))){ boolean notAF = new File("/data/data/" + packageName + "/AFNOEXISTS.lock").exists(); boolean notAD = new File("/data/data/" + packageName + "/ADNOEXISTS.lock").exists(); if (notAF) { afCopied = true; } else { boolean existsAFVer = new File("/data/data/" + packageName + "/AFVERSION.lock").exists(); boolean existsAFApp = new File("/data/data/" + packageName + "/AFAPP.lock").exists(); boolean existsAFPostT = new File("/data/data/" + packageName + "/AFT.lock").exists(); boolean existsAFPostC = new File("/data/data/" + packageName + "/AFCONVERSIONS.lock").exists(); afCopied = existsAFVer && existsAFApp && (existsAFPostT || existsAFPostC); } if (notAD) { adCopied = true; } else { boolean existsADVer = new File("/data/data/" + packageName + "/ADVERSION.lock").exists(); boolean existsADApp = new File("/data/data/" + packageName + "/ADAPP.lock").exists(); adCopied = existsADVer && existsADApp; } Thread.sleep(2000); } while (System.currentTimeMillis() - begin <= minSecondOfWait * 1000){ Thread.sleep(2000); } printWriter.println("cp -a /data/data/" + packageName + "/AFVERSION.txt /data/data/com.bytedance.ttcollector/" + packageName + "/AFVERSION.txt"); printWriter.println("cp -a /data/data/" + packageName + "/AFAPP.txt /data/data/com.bytedance.ttcollector/" + packageName + "/AFAPP.txt"); printWriter.println("cp -a /data/data/" + packageName + "/AFT.txt /data/data/com.bytedance.ttcollector/" + packageName + "/AFT.txt"); printWriter.println("cp -a /data/data/" + packageName + "/AFCONVERSIONS.txt /data/data/com.bytedance.ttcollector/" + packageName + "/AFCONVERSIONS.txt"); printWriter.println("cp -a /data/data/" + packageName + "/AFREQUEST.txt /data/data/com.bytedance.ttcollector/" + packageName + "/AFREQUEST.txt"); printWriter.println("cp -a /data/data/" + packageName + "/ADVERSION.txt /data/data/com.bytedance.ttcollector/" + packageName + "/ADVERSION.txt"); printWriter.println("cp -a /data/data/" + packageName + "/ADAPP.txt /data/data/com.bytedance.ttcollector/" + packageName + "/ADAPP.txt"); printWriter.println("chmod 777 /data/data/com.bytedance.ttcollector/" + packageName + "/*.*"); printWriter.flush(); printWriter.close(); return returnResult(process.waitFor()); } private Pair readSdkVer(String packageName, String verFileName, String appFileName, String nameIfExists){ Pair result = new Pair("unknown", "unknown"); try { File fVer = new File("/data/data/com.bytedance.ttcollector/" + packageName, verFileName); if (fVer.exists()){ File fApp = new File("/data/data/com.bytedance.ttcollector/" + packageName, appFileName); BufferedReader readerVer = new BufferedReader(new InputStreamReader(new FileInputStream(fVer))); String thirdDetect = fApp.exists() ? nameIfExists : (nameIfExists + "2"); String thirdVer = readerVer.readLine(); readerVer.close(); result = new Pair<>(thirdDetect, thirdVer); } }catch (Throwable e){ } return result; } private Pair saveInfoOfApkVer(String packageName, String fileName, Pair afver, Pair adver){ String thirdDetect = "unknown", thirdVer = "unknown"; try { if (!afver.first.equals("unknown") && !adver.first.equals("unknown")) { thirdDetect = afver.first + "+" + adver.first; thirdVer = afver.second + "+" + adver.second; }else if(!afver.first.equals("unknown") || !adver.first.equals("unknown")) { if(afver.first.equals("unknown")) { thirdDetect = adver.first; thirdVer = adver.second; } else { thirdDetect = afver.first; thirdVer = afver.second; } } String sql = "UPDATE apkinfo1 SET ThirdDetect = '" + thirdDetect + "', ThirdVer = '" + thirdVer + "' WHERE PackageName = '" + packageName + "' AND ApkPath = '" + fileName + "'"; _dbStat.execute(sql); } catch(Throwable e){ e.printStackTrace(); } return new Pair<>(thirdDetect, thirdVer); } private String addAFOption(String packageName, String latestVerOption, String json, String postFile){ String result = ""; try { JSONObject target = new JSONObject(json); FileReader fileReader = new FileReader(postFile); BufferedReader reader = new BufferedReader(fileReader); JSONObject option = new JSONObject(); JSONObject post = new JSONObject(reader.readLine()); if (post.has("android_id")){ String android_id = "", current_value = post.getString("android_id"); try { android_id = Settings.Secure.getString(_context.getContentResolver(), Settings.Secure.ANDROID_ID); }catch (Throwable ex){} if (android_id != null && !android_id.isEmpty()) { current_value = current_value.replace(android_id, "{android_id}"); } if (post.has("advertiserId")){ String advertiserId = post.getString("advertiserId"); current_value = current_value.replace(advertiserId, "{gaid}"); } if (post.has("uid")){ String uid = post.getString("uid"); current_value = current_value.replace(uid, "{uid}"); } if(!current_value.contains("{")){ option.put("manualhandle", true); } option.put("android_id", current_value); } if (post.has("appUserId")){ String android_id = "", current_value = post.getString("appUserId"); try { android_id = Settings.Secure.getString(_context.getContentResolver(), Settings.Secure.ANDROID_ID); }catch (Throwable ex){} if (android_id != null && !android_id.isEmpty()) { current_value = current_value.replace(android_id, "{android_id}"); } if (post.has("advertiserId")){ String advertiserId = post.getString("advertiserId"); current_value = current_value.replace(advertiserId, "{gaid}"); } if (post.has("uid")){ String uid = post.getString("uid"); current_value = current_value.replace(uid, "{uid}"); } if(!current_value.contains("{")){ option.put("manualhandle", true); } option.put("appUserId", current_value); } if (post.has("customData")){ String android_id = "", current_value = post.getString("customData"); try { android_id = Settings.Secure.getString(_context.getContentResolver(), Settings.Secure.ANDROID_ID); }catch (Throwable ex){} if (android_id != null && !android_id.isEmpty()) { current_value = current_value.replace(android_id, "{android_id}"); } if (post.has("advertiserId")){ String advertiserId = post.getString("advertiserId"); current_value = current_value.replace(advertiserId, "{gaid}"); } if(!current_value.contains("{")){ option.put("manualhandle", true); } option.put("customData", current_value); } if (post.has("currency")){ option.put("currency", post.getString("currency")); } if (post.has("onelink_id")){ option.put("onelink_id", post.getString("onelink_id")); } if (post.has("af_currentstore")){ option.put("api_store_value", post.getString("af_currentstore")); } // if (post.has("channel")){ // option.put("channel", post.getString("channel")); // } // if (post.has("imei")){ // option.put("imei", post.getString("imei")); // } // if (post.has("lvl")){ // option.put("lvl", true); // } //比对 if (latestVerOption != null && latestVerOption.length() != 0) { JSONObject latestVerOptionJson = new JSONObject(latestVerOption); Iterator it = latestVerOptionJson.keys(); while (it.hasNext()) { String key = it.next(); // Log.d(TAG, "propCorrection: key " + key); // Log.d(TAG, "propCorrection: value " + prop4ServerJson.getString(key)); //信任服务器旧版数据模式 // if ((!option.has(key)) || option.getString(key).equals("")) { // //propJson.put(key, prop4ServerJson.getString(key)); // option.put(key, latestVerOptionJson.get(key)); // } //信任自己取到的数据模式 if ((option.has(key))) { option.remove(key); option.put(key, latestVerOptionJson.get(key)); } } } if (option.length() > 0) { //替换uuid android_id gaid String optionStr = option.toString(); optionStr = optionStr.replaceAll("[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}", "{uuid36}"); optionStr = optionStr.replaceAll("[0-9A-F]{8}(-[0-9A-F]{4}){3}-[0-9A-F]{12}", "{uuid36U}"); optionStr = optionStr.replaceAll("[0-9a-f]{32}", "{uuid32}"); optionStr = optionStr.replaceAll("[0-9A-F]{32}", "{uuid32U}"); optionStr = optionStr.replaceAll("[0-9a-fA-F]{16}", "{android_id}"); //额外需要修改参数的apk判断 optionStr = specOption(packageName, optionStr); option = new JSONObject(optionStr); //prop.put("option", option); target.put("option", option); } result = target.toString(); reader.close(); fileReader.close(); }catch (Throwable e){ e.printStackTrace(); } return result; } //特殊APP的option处理 public static String specOption(String packageName, String optionStr) { String specPackageNames = "com.eterno.shortvideos|com.fiverr.fiverr"; if (specPackageNames.contains(packageName)) { JSONObject prop = null; try { prop = new JSONObject(optionStr); if (prop == null) return optionStr; switch (packageName) { case "com.eterno.shortvideos": if (prop.has("appUserId")) { prop.put("appUserId", "j.{2}{0}{2}{1}{2}{1}{1}{1}{2}{1}{1}{1}{2}{2}{2}{1}{1}{1}{2}{1}{2}{1}{2}{2}{2}{0}{2}{2}{2}{1}09A"); } break; case "com.fiverr.fiverr": if (prop.has("appUserId")) { prop.put("appUserId", "{timestamp13}{0}{0}{0}{0}{0}{0}{0}{0}{0}{0}"); } break; case "com.neptune.domino": if (prop.has("appUserId")) { prop.put("appUserId", "{4}{4}:{4}{4}:{4}{4}:{4}{4}:{4}{4}:{4}{4}"); } break; } } catch (JSONException e) { e.printStackTrace(); } optionStr = prop.toString(); } return optionStr; } private JSONArray getRequestEvents(String packageName){ JSONArray subEvents = new JSONArray(); try{ File fRequest = new File("/data/data/com.bytedance.ttcollector/" + packageName, "AFREQUEST.txt"); if (fRequest.exists()){ BufferedReader readerApp = new BufferedReader(new InputStreamReader(new FileInputStream(fRequest))); List timestamps = new ArrayList<>(); HashMap map = new HashMap<>(); String line = readerApp.readLine(); while (line != null){ try{ if (!line.isEmpty()){ JSONObject request = new JSONObject(line); long timestamp = request.getLong("timestamp"); String url = request.getString("url"); if (!url.contains("t.appsflyer.com") && !url.contains("conversions.appsflyer.com")){ map.put(timestamp, request); timestamps.add(timestamp); } } line = readerApp.readLine(); }catch (Exception ex){ line = ""; } } Collections.sort(timestamps); for (int i = 0; i < timestamps.size(); i++) { String type = "", name = "", value = ""; long timeDelayMin = 100, timeDelayMax = 100; try{ JSONObject target = map.get(timestamps.get(i)); JSONObject targetContent = new JSONObject(target.getString("content")); URL url = new URL(target.getString("url")); String host = url.getHost(); if (host.equals("attr.appsflyer.com")){ type = "attr"; } else if (host.equals("register.appsflyer.com")){ type = "register"; } else if (host.equals("launches.appsflyer.com")){ type = "launche"; } else if (host.equals("inapps.appsflyer.com")){ type = "inapp"; name = targetContent.getString("eventName"); value = targetContent.getString("eventValue"); } if (i < (timestamps.size() - 1)){ timeDelayMin = timestamps.get(i + 1) - timestamps.get(i) - 2; timeDelayMax = timestamps.get(i + 1) - timestamps.get(i) + 2; } JSONObject subEventsItem = new JSONObject(); subEventsItem.put("type", type); subEventsItem.put("name", name); subEventsItem.put("value", value); subEventsItem.put("timeDelayMin", timeDelayMin); subEventsItem.put("timeDelayMax", timeDelayMax); subEvents.put(subEventsItem); }catch (Exception ex){ } } } }catch (Throwable err){ err.printStackTrace(); } return subEvents; } private void saveInfoOfApkAFInfo(String packageName, String fileVer, String afVer){ try { File fApp = new File("/data/data/com.bytedance.ttcollector/" + packageName, "AFAPP.txt"); File fPostT = new File("/data/data/com.bytedance.ttcollector/" + packageName, "AFT.txt"); File fPostC = new File("/data/data/com.bytedance.ttcollector/" + packageName, "AFCONVERSIONS.txt"); if (fApp.exists()){ BufferedReader readerApp = new BufferedReader(new InputStreamReader(new FileInputStream(fApp))); String dataContent = readerApp.readLine(); readerApp.close(); if (fPostT.exists() || fPostC.exists()){ //从服务器读取参数 String latestVerOption = queryLatestProp(packageName); dataContent = addAFOption(packageName, latestVerOption, dataContent, fPostC.exists() ? fPostC.getPath() : fPostT.getPath()); } String sql = "INSERT INTO apkprotocprop (PackageName, Prop, appVer, thirdParty, thirdVer) VALUES(?, ?, ?, ?, ?);"; // PreparedStatement ps = _dbConn.prepareStatement(sql); // ps.setString(1, packageName); // ps.setString(2, dataContent); // ps.setString(3, fileVer); // ps.setString(4, "AF"); // ps.setString(5, afVer); // ps.executeUpdate(); // Log.e("AFTask", "apkprotocprop update ok"); // String url = String.format("http://123.56.44.45/tt/manage/apkInfo!addApkProtocPropOp.do?apkProtocProp.packageName=%s&apkProtocProp.appVer=%s&apkProtocProp.thirdParty=%s&apkProtocProp.thirdVer=%s&apkProtocProp.prop=%s", packageName, fileVer, "AF", afVer, dataContent); // System.out.println(url); OkHttpClient client = new OkHttpClient(); FormBody formBody = null; JSONObject jsonObject = new JSONObject(dataContent); formBody = new FormBody.Builder() .add("apkProtocProp.packageName", packageName) .add("apkProtocProp.appVer", fileVer) .add("apkProtocProp.thirdParty", "AF") .add("apkProtocProp.thirdVer", afVer) .add("apkProtocProp.prop", jsonObject.toString()) .build(); Request request = new Request.Builder() .url("http://123.56.44.45/tt/manage/apkInfo!addApkProtocPropOp.do?") .addHeader("Content-Type", "application/x-www-form-urlencoded") .method("POST", formBody) .build(); Response response = client.newCall(request).execute(); if(response.code() == 200) { System.out.println("UpdateOK"); } else { System.out.println("UpdateError"); } } }catch (IOException | JSONException e){ e.printStackTrace(); } } private String queryLatestProp(String packageName) { String propString = null; int latestVersionCode = 0; String optionString = null; String sql = "SELECT * FROM apkprotocprop WHERE PackageName = ?;"; try { PreparedStatement ps = _dbConn.prepareStatement(sql); ps.setString(1, packageName); ResultSet rs = ps.executeQuery(); while (rs.next()){ propString = rs.getString("Prop"); JSONObject jsonObject = new JSONObject(propString); if (jsonObject.has("versionCode")){ if (jsonObject.getInt("versionCode") > latestVersionCode){ latestVersionCode = jsonObject.getInt("versionCode"); if (jsonObject.has("option")){ optionString = jsonObject.getString("option"); } } } } Log.d("AFTask", "queryLatestProp: " + propString); } catch (SQLException | JSONException e) { e.printStackTrace(); } Log.e("AFTask", "latestVersionCode: " + latestVersionCode + " option: " + optionString); return optionString; } private void saveInfoOfApkADInfo(String packageName, String fileVer, String adVer){ try { File fApp = new File("/data/data/com.bytedance.ttcollector/" + packageName, "ADAPP.txt"); if (fApp.exists()){ BufferedReader readerApp = new BufferedReader(new InputStreamReader(new FileInputStream(fApp))); String dataContent = readerApp.readLine(); readerApp.close(); String sql = "INSERT INTO apkprotocprop (PackageName, Prop, appVer, thirdParty, thirdVer) VALUES(?, ?, ?, ?, ?);"; // PreparedStatement ps = _dbConn.prepareStatement(sql); // ps.setString(1, packageName); // ps.setString(2, dataContent); // ps.setString(3, fileVer); // ps.setString(4, "ADJUST"); // ps.setString(5, adVer); // ps.executeUpdate(); // Log.e("AFTask", "apkprotocprop update ok"); // String url = String.format("http://123.56.44.45/tt/manage/apkInfo!addApkProtocPropOp.do?apkProtocProp.packageName=%s&apkProtocProp.appVer=%s&apkProtocProp.thirdParty=%s&apkProtocProp.thirdVer=%s&apkProtocProp.prop=%s", packageName, fileVer, "ADJUST", adVer, dataContent); // System.out.println(url); OkHttpClient client = new OkHttpClient(); FormBody formBody = null; JSONObject jsonObject = new JSONObject(dataContent); formBody = new FormBody.Builder() .add("apkProtocProp.packageName", packageName) .add("apkProtocProp.appVer", fileVer) .add("apkProtocProp.thirdParty", "ADJUST") .add("apkProtocProp.thirdVer", adVer) .add("apkProtocProp.prop", jsonObject.toString()) .build(); Request request = new Request.Builder() .url("http://123.56.44.45/tt/manage/apkInfo!addApkProtocPropOp.do?") .addHeader("Content-Type", "application/x-www-form-urlencoded") .method("POST", formBody) .build(); Response response = client.newCall(request).execute(); if(response.code() == 200) { System.out.println("UpdateOK"); } else { System.out.println("UpdateError"); } } }catch (IOException | JSONException e){ e.printStackTrace(); } } private void updateEventOfApk(String packageName, String fileName){ JSONObject eventJson = new JSONObject(); try{ eventJson.put("afterInstallSync", true); eventJson.put("afterInstallDelayMin", 3); eventJson.put("afterInstallDelayMax", 10); eventJson.put("sysVars", new JSONObject()); JSONArray events = new JSONArray(); JSONObject eventsItem = new JSONObject(); eventsItem.put("sort", 1); eventsItem.put("subEvents", getRequestEvents(packageName)); events.put(eventsItem); eventJson.put("events", events); String sql = "UPDATE apkinfo1 SET eventJson = ? WHERE PackageName = ? AND ApkPath = ?"; PreparedStatement ps = _dbConn.prepareStatement(sql); ps.setString(1, eventJson.toString()); ps.setString(2, packageName); ps.setString(3, fileName); ps.executeUpdate(); }catch (Exception err){ err.printStackTrace(); } } /** * 保存参数到数据库 * @param packageName * @param fileName * @return * @throws Throwable */ private void saveInfoOfApk(String packageName, String fileName) { String fileVer = fileName.substring(fileName.lastIndexOf("_") + 1, fileName.lastIndexOf(".")); Pair afver = readSdkVer(packageName, "AFVERSION.txt", "AFAPP.txt", "appsflyer"); Pair adver = readSdkVer(packageName, "ADVERSION.txt", "ADAPP.txt", "adjust"); saveInfoOfApkVer(packageName, fileName, afver, adver); saveInfoOfApkAFInfo(packageName, fileVer, afver.second); saveInfoOfApkADInfo(packageName, fileVer, adver.second); updateEventOfApk(packageName, fileName); } private void saveApp(String appid, String fileName, long waitMaxSecond, long waitMinSecond){ try{ if (copyLogFile(appid, waitMaxSecond, waitMinSecond)){ saveInfoOfApk(appid, fileName); } } catch (Throwable e) { e.printStackTrace(); } } private void doBusiness(String apkPath, long waitMaxSecond, long waitMinSecond) throws Throwable{ String fileName = ""; if(apkPath != ""){ fileName = apkPath; }else { fileName = apkFileName(_appid); } String path = downloadAPK(_downloadUrl, fileName); Log.e("AFTask", "Download apk end"); //移动到tmp文件夹 CmdUtils.moveFile2Tmp(path); String apkSdcard = path; path = "/data/local/tmp/" + fileName; if(path.endsWith(".apk")) { clientInstallApk(new File(path)); } else { clientInstallApks(new File(path)); } Log.e("AFTask", "install apk end"); // deleteAPK(path); deleteAPK(apkSdcard); CmdUtils.deleteFile(path); if (openApp(_appid)){ Log.e("AFTask", "open apk end"); saveApp(_appid, fileName, waitMaxSecond, waitMinSecond); } clientUninstall(_appid); } // /** // * 初始化 // * @throws Throwablel // */ public void init(String dbhost, String dbname, String dbuser, String dbpass) throws Throwable { Class.forName("com.mysql.jdbc.Driver"); _dbConn= DriverManager.getConnection("jdbc:mysql://" + dbhost + "/" + dbname, dbuser, dbpass); _dbStat = (Statement)_dbConn.createStatement(); } public void start(long waitMaxSecond, long waitMinSecond){ new Thread(new Runnable(){ @Override public void run() { try{ doBusiness("", waitMaxSecond, waitMinSecond); }catch (Throwable err){ XposedBridge.log("AFTASK ERROR : " + err.getMessage()); } } }).start(); } public static void startTask(Context context){ new Thread(new Runnable(){ @Override public void run() { while(!_paused){ String packageName = "", apkPath = ""; int code = -1; try { HttpURLConnection conn = (HttpURLConnection) new URL("http://123.56.44.45/tt/ddj/autoApk.do").openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); if (200 == conn.getResponseCode()){ String line; StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line = br.readLine()) != null) { sb.append(line); } Log.e("AFTask", sb.toString()); JSONObject json = new JSONObject(sb.toString()); if (go) { json = new JSONObject("{\"code\":1,\"apkPath\":\"com.jar.app_4.9.6.apk\",\"packageName\":\"com.jar.app\"}"); go = false; } //JSONObject json = new JSONObject("{\"code\":1,\"apkPath\":\"ru.ligastavok.android_3.8.0.apk\",\"packageName\":\"ru.ligastavok.android\"}"); code = json.has("code") ? json.getInt("code"): -1; packageName = json.has("packageName") ? json.getString("packageName") : ""; apkPath = json.has("apkPath") ? json.getString("apkPath") : ""; } if (code != 1) { Thread.sleep(5000); continue; } //if (code != 1) { continue; } if (packageName == null || apkPath == null) { continue; } if (packageName.isEmpty() || apkPath.isEmpty()) { continue; } //TTTask task = new TTTask(context, packageName, "http://123.56.44.45/tt/upload/ddj/"); TTTask task = new TTTask(context, packageName, "http://39.103.73.250/tt/upload/ddj/"); task.init("pc-2ze3t9ojzloi45k3to.mysql.polardb.rds.aliyuncs.com", "advert_lcddj", "advertuser1116", "IvM@ck#z9$Eqy3KGBK4g"); task.doBusiness(apkPath, 60, 0); Log.e("AFTask", "Loop end for pack: " + packageName); } catch(Throwable e){ Log.d("AFTask", "run: " + e.toString()); e.printStackTrace(); } } } }).start(); } }