編輯:關於Android編程
原理基於上篇的多渠道打包工具,我們使用apktool解壓需要驗證的apk文件後,去讀AndroidManifest.xml,當讀到渠道號哪一行的時候輸出即可。
源碼如下:
Main.java
[java]
package com.Market5577.channelVerifyTool;
public class Main {
public static void main(String[] args) {
System.out
.println("=====**====Code by H3c=====**======");
System.out.println("==**==渠道驗證工具==**==");
if (args.length != 1) {
System.out
.println("==ERROR==usage:java -jar channelV.jar apkDirectory======");
System.out
.println("==INFO==Example: java -jar channelV.jar /apps======");
return;
}
String apk = args[0];
SplitApk sp = new SplitApk(apk);
sp.mySplit();
}
}
package com.Market5577.channelVerifyTool;
public class Main {
public static void main(String[] args) {
System.out
.println("=====**====Code by H3c=====**======");
System.out.println("==**==渠道驗證工具==**==");
if (args.length != 1) {
System.out
.println("==ERROR==usage:java -jar channelV.jar apkDirectory======");
System.out
.println("==INFO==Example: java -jar channelV.jar /apps======");
return;
}
String apk = args[0];
SplitApk sp = new SplitApk(apk);
sp.mySplit();
}
}
SplitApk.java
[java]
package com.Market5577.channelVerifyTool;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class SplitApk {
HashMap<String, String> qudao = new HashMap<String, String>();// 渠道號,渠道名
String curPath;// 當前文件夾路徑
String apkDirectory;
public SplitApk(String directory) {
this.curPath = new File("").getAbsolutePath();
this.apkDirectory = directory;
}
public void mySplit() {
File dire = new File(apkDirectory);
if (!dire.exists()) {
System.out.println("沒有該文件");
return;
}
if (dire.isDirectory()) {
File[] sonFile = dire.listFiles();
for (File file : sonFile) {
modifyXudao(file.getAbsolutePath());
}
} else {
modifyXudao(apkDirectory);
}
System.out.println("====Over====");
}
/**
* apktool解壓apk,替換渠道值
*
* @throws Exception
*/
private void modifyXudao(String apkName) {
// 解壓 /C 執行字符串指定的命令然後終斷
String cmdUnpack = "cmd.exe /C java -jar apktool.jar d -f -s "
+ apkName;
runCmd(cmdUnpack);
String[] apkFilePath = apkName.split("\\\\");
String shortApkName = apkFilePath[apkFilePath.length - 1];
String dir = shortApkName.split(".apk")[0];
File packDir = new File(dir);// 獲得解壓的apk目錄
String f_mani = packDir.getAbsolutePath() + "\\AndroidManifest.xml";
File manifest = new File(f_mani);
for (int i = 0; i < 10; i++) {
if (manifest.exists()) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (!manifest.exists()) {
System.out.println("====驗證失敗======");
}
/*
* 遍歷map,復制manifese進來,修改後打包,簽名,存儲在對應文件夾中
*/
BufferedReader br = null;
FileReader fr = null;
String keyLine = null;
try {
fr = new FileReader(manifest);
br = new BufferedReader(fr);
String line = null;
while ((line = br.readLine()) != null) {
if (line.contains("\"BaiduMobAd_CHANNEL\"")) { // 關鍵代碼===我這裡是用的百度統計工具
keyLine = line;
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("====驗證失敗======");
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (keyLine != null) {
String tmps[] = keyLine.split("\\\"");
System.out.println("讀到的渠道是:" + tmps[3]);
} else {
System.out.println("====驗證失敗,請關閉======");
}
// 刪除中途文件
String cmdKey = String.format("cmd.exe /C rd /s/q %s", dir);
runCmd(cmdKey);
}
/**
* 執行指令
*
* @param cmd
*/
public void runCmd(String cmd) {
Runtime rt = Runtime.getRuntime();
BufferedReader br = null;
InputStreamReader isr = null;
try {
Process p = rt.exec(cmd);
// p.waitFor();
isr = new InputStreamReader(p.getInputStream());
br = new BufferedReader(isr);
String msg = null;
while ((msg = br.readLine()) != null) {
System.out.println(msg);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (isr != null) {
isr.close();
}
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.Market5577.channelVerifyTool;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class SplitApk {
HashMap<String, String> qudao = new HashMap<String, String>();// 渠道號,渠道名
String curPath;// 當前文件夾路徑
String apkDirectory;
public SplitApk(String directory) {
this.curPath = new File("").getAbsolutePath();
this.apkDirectory = directory;
}
public void mySplit() {
File dire = new File(apkDirectory);
if (!dire.exists()) {
System.out.println("沒有該文件");
return;
}
if (dire.isDirectory()) {
File[] sonFile = dire.listFiles();
for (File file : sonFile) {
modifyXudao(file.getAbsolutePath());
}
} else {
modifyXudao(apkDirectory);
}
System.out.println("====Over====");
}
/**
* apktool解壓apk,替換渠道值
*
* @throws Exception
*/
private void modifyXudao(String apkName) {
// 解壓 /C 執行字符串指定的命令然後終斷
String cmdUnpack = "cmd.exe /C java -jar apktool.jar d -f -s "
+ apkName;
runCmd(cmdUnpack);
String[] apkFilePath = apkName.split("\\\\");
String shortApkName = apkFilePath[apkFilePath.length - 1];
String dir = shortApkName.split(".apk")[0];
File packDir = new File(dir);// 獲得解壓的apk目錄
String f_mani = packDir.getAbsolutePath() + "\\AndroidManifest.xml";
File manifest = new File(f_mani);
for (int i = 0; i < 10; i++) {
if (manifest.exists()) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (!manifest.exists()) {
System.out.println("====驗證失敗======");
}
/*
* 遍歷map,復制manifese進來,修改後打包,簽名,存儲在對應文件夾中
*/
BufferedReader br = null;
FileReader fr = null;
String keyLine = null;
try {
fr = new FileReader(manifest);
br = new BufferedReader(fr);
String line = null;
while ((line = br.readLine()) != null) {
if (line.contains("\"BaiduMobAd_CHANNEL\"")) { // 關鍵代碼===我這裡是用的百度統計工具
keyLine = line;
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("====驗證失敗======");
} finally {
try {
if (fr != null) {
fr.close();
}
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
if (keyLine != null) {
String tmps[] = keyLine.split("\\\"");
System.out.println("讀到的渠道是:" + tmps[3]);
} else {
System.out.println("====驗證失敗,請關閉======");
}
// 刪除中途文件
String cmdKey = String.format("cmd.exe /C rd /s/q %s", dir);
runCmd(cmdKey);
}
/**
* 執行指令
*
* @param cmd
*/
public void runCmd(String cmd) {
Runtime rt = Runtime.getRuntime();
BufferedReader br = null;
InputStreamReader isr = null;
try {
Process p = rt.exec(cmd);
// p.waitFor();
isr = new InputStreamReader(p.getInputStream());
br = new BufferedReader(isr);
String msg = null;
while ((msg = br.readLine()) != null) {
System.out.println(msg);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (isr != null) {
isr.close();
}
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
生成jar後寫一個批處理即可:
[html]
@echo off
::set /p var=請拖入apk:
::java -jar cVerify.jar %var%
java -jar cVerify.jar C:\Users\Harris\Desktop\rePackTool\apk
echo.&echo 請按任意鍵退出...&pause>nul
exit
@echo off
::set /p var=請拖入apk:
::java -jar cVerify.jar %var%
java -jar cVerify.jar C:\Users\Harris\Desktop\rePackTool\apk
echo.&echo 請按任意鍵退出...&pause>nul
exit
該工具支持文件和文件夾的拖入~
觀察者模式有時被稱作發布/訂閱模式,觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它
第4節 遠程調用之前提到過:如果站在Service與觸發Service運行的那個組件的角度,根據它們的關系進行分類,有兩種:本地Service,遠程Service。本地S
實際上字母索引表的效果,可以說在現在的眾多APP中使用的非常流行,比如支付寶,微信中的聯系人,還有購物,買票的APP中選擇全國城市,切換城市的時候,這時候的城市也就是按照
Android 實現自定義dialog圓角功能 剛接觸公司的Android項目,客戶畫好了界面,需求如下: 彈出的窗口是要四個圓角,並且標題欄顏色和下